[build] influx: InfluxDB instance setup

175 views
Skip to first unread message

Michael Pratt (Gerrit)

unread,
Mar 23, 2022, 5:58:51 PM3/23/22
to Michael Pratt, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gopher Robot, Heschi Kreinick, Dmitri Shuralyov, Michael Knyszek, golang-co...@googlegroups.com

Michael Pratt submitted this change.

View Change



2 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: influx/main.go
Insertions: 61, Deletions: 62.

@@ -21,7 +21,6 @@

"github.com/influxdata/influxdb-client-go/v2"
"github.com/influxdata/influxdb-client-go/v2/domain"
-
"cloud.google.com/go/compute/metadata"
secretmanager "cloud.google.com/go/secretmanager/apiv1"
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
@@ -29,6 +28,57 @@

const influxURL = "https://localhost:443"

+func main() {
+ if err := run(); err != nil {
+ log.Printf("Error completing setup: %v", err)
+ os.Exit(1)
+ }
+}
+
+func run() error {
+ ctx := context.Background()
+
+ // Connecting via localhost with self-signed certs, so no cert checks.
+ options := influxdb2.DefaultOptions()
+ options.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
+ client := influxdb2.NewClientWithOptions(influxURL, "", options)
+ defer client.Close()
+
+ log.Printf("Waiting for influx to start...")
+ for {
+ _, err := client.Ready(ctx)
+ if err != nil {
+ log.Printf("Influx not ready: %v", err)
+ time.Sleep(1 * time.Second)
+ continue
+ }
+ break
+ }
+
+ log.Printf("Influx ready!")
+
+ allowed, err := setupAllowed(ctx)
+ if err != nil {
+ return fmt.Errorf("error checking setup: %w", err)
+ }
+ if !allowed {
+ log.Printf("Influx already set up!")
+ return nil
+ }
+
+ secrets, err := setupUsers(ctx, client)
+ if err != nil {
+ return fmt.Errorf("error setting up users: %w", err)
+ }
+
+ if err := secrets.recordOrLog(ctx); err != nil {
+ return fmt.Errorf("error recording secrets: %w", err)
+ }
+
+ log.Printf("Influx setup complete!")
+ return nil
+}
+
// Setup is the response to Influx GET /api/v2/setup.
type Setup struct {
Allowed bool `json:"allowed"`
@@ -66,23 +116,6 @@
return s.Allowed, nil
}

-func generatePassword() (string, error) {
- const passwordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
- const length = 64
-
- b := make([]byte, 0, length)
- max := big.NewInt(int64(len(passwordCharacters) - 1))
- for i := 0; i < length; i++ {
- j, err := rand.Int(rand.Reader, max)
- if err != nil {
- return "", fmt.Errorf("error generating random number: %w", err)
- }
- b = append(b, passwordCharacters[j.Int64()])
- }
-
- return string(b), nil
-}
-
type influxSecrets struct {
adminPass string
adminToken string
@@ -218,53 +251,19 @@
}, nil
}

-func run() error {
- ctx := context.Background()
+func generatePassword() (string, error) {
+ const passwordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
+ const length = 64

- // Connecting via localhost with self-signed certs, so no cert checks.
- options := influxdb2.DefaultOptions()
- options.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
- client := influxdb2.NewClientWithOptions(influxURL, "", options)
- defer client.Close()
-
- log.Printf("Waiting for influx to start...")
- for {
- _, err := client.Ready(ctx)
+ b := make([]byte, 0, length)
+ max := big.NewInt(int64(len(passwordCharacters) - 1))
+ for i := 0; i < length; i++ {
+ j, err := rand.Int(rand.Reader, max)
if err != nil {
- log.Printf("Influx not ready: %v", err)
- time.Sleep(1 * time.Second)
- continue
+ return "", fmt.Errorf("error generating random number: %w", err)
}
- break
+ b = append(b, passwordCharacters[j.Int64()])
}

- log.Printf("Influx ready!")
-
- allowed, err := setupAllowed(ctx)
- if err != nil {
- return fmt.Errorf("error checking setup: %w", err)
- }
- if !allowed {
- log.Printf("Influx already set up!")
- return nil
- }
-
- secrets, err := setupUsers(ctx, client)
- if err != nil {
- return fmt.Errorf("error setting up users: %w", err)
- }
-
- if err := secrets.recordOrLog(ctx); err != nil {
- return fmt.Errorf("error recording secrets: %w", err)
- }
-
- log.Printf("Influx setup complete!")
- return nil
-}
-
-func main() {
- if err := run(); err != nil {
- log.Printf("Error completing setup: %v", err)
- os.Exit(1)
- }
+ return string(b), nil
}
```
```
The name of the file: go.mod
Insertions: 1, Deletions: 1.

@@ -27,6 +27,7 @@
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
+ github.com/influxdata/influxdb-client-go/v2 v2.8.0
github.com/jackc/pgconn v1.11.0
github.com/jackc/pgx/v4 v4.13.0
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1
@@ -62,7 +63,6 @@
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
- github.com/influxdata/influxdb-client-go/v2 v2.8.0 // indirect
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451 // indirect
```

Approvals: Heschi Kreinick: Looks good to me, approved Michael Pratt: Trusted; Run TryBots Gopher Robot: TryBots succeeded
influx: InfluxDB instance setup

This CL creates a Docker image for running an InfluxDB instance for the
Go performance monitoring dashboard.

The image is based on the Google-maintained GCP InfluxDB 2 image, with
an additional small program to perform initial database setup and push
access credentials to Google Secret Manager.

See README.md for instructions on running the image locally or on GCP.

This CL is based on CL 392635 after we decided it belongs better in
x/build. It drop the custom module, using the standard x/build/go.mod
instead. Plus it adds a Makefile and and expectation of `docker build`
running from the repository.

For golang/go#48803

Change-Id: Ib79242311acee9529073cd68c9754e6459a49319
Reviewed-on: https://go-review.googlesource.com/c/build/+/394354
Reviewed-by: Heschi Kreinick <hes...@google.com>
Trust: Michael Pratt <mpr...@google.com>
Run-TryBot: Michael Pratt <mpr...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
M go.mod
M go.sum
A influx/Dockerfile
A influx/Makefile
A influx/README.md
A influx/main.go
6 files changed, 402 insertions(+), 0 deletions(-)

diff --git a/go.mod b/go.mod
index 969d5bf..bbe5911 100644
--- a/go.mod
+++ b/go.mod
@@ -27,6 +27,7 @@
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4
+ github.com/influxdata/influxdb-client-go/v2 v2.8.0
github.com/jackc/pgconn v1.11.0
github.com/jackc/pgx/v4 v4.13.0
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1
@@ -56,11 +57,13 @@
github.com/beorn7/perks v1.0.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
+ github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
+ github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451 // indirect
github.com/jackc/pgio v1.0.0 // indirect
@@ -72,6 +75,7 @@
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jstemmer/go-junit-report v0.9.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.9.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.15.0 // indirect
diff --git a/go.sum b/go.sum
index 685ed07..fbbedf8 100644
--- a/go.sum
+++ b/go.sum
@@ -174,10 +174,13 @@
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
+github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dghubble/oauth1 v0.7.0 h1:AlpZdbRiJM4XGHIlQ8BuJ/wlpGwFEJNnB4Mc+78tA/w=
github.com/dghubble/oauth1 v0.7.0/go.mod h1:8pFdfPkv/jr8mkChVbNVuJ0suiHe278BtWI4Tk1ujxk=
@@ -217,9 +220,11 @@
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw=
+github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.3.3 h1:mBQ8NiOgDkINJrZtoizkC3nDNYgSaWtxyem6S2XHBtA=
github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
+github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -230,6 +235,8 @@
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -310,6 +317,7 @@
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/gonum/blas v0.0.0-20181208220705-f22b278b28ac/go.mod h1:P32wAyui1PQ58Oce/KYkOqQv8cVw1zAapXOl+dRFGbc=
github.com/gonum/floats v0.0.0-20181209220543-c233463c7e82/go.mod h1:PxC8OnwL11+aosOB5+iEPoV3picfs8tUpkVd0pDo+Kg=
github.com/gonum/internal v0.0.0-20181124074243-f884aa714029/go.mod h1:Pu4dmpkhSyOzRwuXkOgAvijx4o+4YMUJJo9OvPYMkks=
@@ -377,6 +385,7 @@
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
@@ -416,7 +425,11 @@
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb-client-go/v2 v2.8.0 h1:iaS3NrKUk6D0nkZZWjDm+fFWjrNKkix5YF2YrdVRJ8I=
+github.com/influxdata/influxdb-client-go/v2 v2.8.0/go.mod h1:x7Jo5UHHl+w8wu8UnGiNobDDHygojXwJX4mx7rXGKMk=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
+github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
@@ -533,6 +546,8 @@
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
+github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
+github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
@@ -544,13 +559,18 @@
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
@@ -725,6 +745,9 @@
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
+github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
@@ -781,8 +804,10 @@
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -962,6 +987,7 @@
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1005,6 +1031,8 @@
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/influx/Dockerfile b/influx/Dockerfile
new file mode 100644
index 0000000..3f44eea
--- /dev/null
+++ b/influx/Dockerfile
@@ -0,0 +1,32 @@
+# Copyright 2022 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+FROM golang:1.18 AS build
+
+COPY go.mod /app/go.mod
+COPY go.sum /app/go.sum
+
+WORKDIR /app
+
+RUN go mod download
+
+COPY . /app
+
+RUN go build -o run-influx golang.org/x/build/influx
+
+FROM marketplace.gcr.io/google/influxdb2:latest
+
+COPY --from=build /app/run-influx /run-influx
+
+# For now, generate a self-signed cert to use. Not for production use!
+RUN openssl req -x509 -nodes -newkey rsa:2048 \
+ -keyout /etc/ssl/influxdb-selfsigned.key \
+ -out /etc/ssl/influxdb-selfsigned.crt \
+ -days 30 \
+ -subj '/CN=localhost'
+
+# Run our setup application in the background and the parent Influx entrypoint
+# in the foreground.
+ENTRYPOINT ["/bin/sh"]
+CMD ["-c", "/run-influx & /docker-entrypoint.sh influxd --tls-cert=/etc/ssl/influxdb-selfsigned.crt --tls-key=/etc/ssl/influxdb-selfsigned.key --http-bind-address=:443"]
diff --git a/influx/Makefile b/influx/Makefile
new file mode 100644
index 0000000..730b841
--- /dev/null
+++ b/influx/Makefile
@@ -0,0 +1,23 @@
+# Copyright 2022 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+MUTABLE_VERSION ?= latest
+VERSION ?= $(shell git rev-parse --short HEAD)
+
+IMAGE_STAGING := gcr.io/go-dashboard-dev/influx
+IMAGE_PROD := gcr.io/symbolic-datum-552/influx
+
+docker-prod:
+ docker build --force-rm -f Dockerfile --tag=$(IMAGE_PROD):$(VERSION) ..
+ docker tag $(IMAGE_PROD):$(VERSION) $(IMAGE_PROD):$(MUTABLE_VERSION)
+docker-staging:
+ docker build --force-rm -f Dockerfile --tag=$(IMAGE_STAGING):$(VERSION) ..
+ docker tag $(IMAGE_STAGING):$(VERSION) $(IMAGE_STAGING):$(MUTABLE_VERSION)
+
+push-prod: docker-prod
+ docker push $(IMAGE_PROD):$(MUTABLE_VERSION)
+ docker push $(IMAGE_PROD):$(VERSION)
+push-staging: docker-staging
+ docker push $(IMAGE_STAGING):$(MUTABLE_VERSION)
+ docker push $(IMAGE_STAGING):$(VERSION)
diff --git a/influx/README.md b/influx/README.md
new file mode 100644
index 0000000..785991b
--- /dev/null
+++ b/influx/README.md
@@ -0,0 +1,16 @@
+# InfluxDB container image
+
+This directory contains the source for the InfluxDB container image used in the
+Go Performance Monitoring system. The image is based on the Google-maintained
+GCP InfluxDB 2 image, with an additional small program to perform initial
+database setup and push access credentials to Google Secret Manager.
+
+## Local
+
+To run an instance locally:
+
+ $ sudo docker build -t golang_influx . && sudo docker run --rm -p 443:8086 golang_influx
+
+Browse / API connect to https://localhost:8086 (note that the instance uses a
+self-signed certificate), and authenticate with user 'admin' or 'reader' with
+the password or API token logged by the container.
diff --git a/influx/main.go b/influx/main.go
new file mode 100644
index 0000000..caf83a1
--- /dev/null
+++ b/influx/main.go
@@ -0,0 +1,269 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This program runs in the InfluxDB container, performs initial setup of the
+// database, and publishes access secrets to secret manager. If the database is
+// already set up, it just sets up certificates and starts InfluxDB.
+package main
+
+import (
+ "context"
+ "crypto/rand"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "log"
+ "math/big"
+ "net/http"
+ "os"
+ "time"
+
+ "github.com/influxdata/influxdb-client-go/v2"
+ "github.com/influxdata/influxdb-client-go/v2/domain"
+ "cloud.google.com/go/compute/metadata"
+ secretmanager "cloud.google.com/go/secretmanager/apiv1"
+ secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
+)
+
+const influxURL = "https://localhost:443"
+
+func main() {
+ if err := run(); err != nil {
+ log.Printf("Error completing setup: %v", err)
+ os.Exit(1)
+ }
+}
+
+func run() error {
+ ctx := context.Background()
+
+ // Connecting via localhost with self-signed certs, so no cert checks.
+ options := influxdb2.DefaultOptions()
+ options.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
+ client := influxdb2.NewClientWithOptions(influxURL, "", options)
+ defer client.Close()
+
+ log.Printf("Waiting for influx to start...")
+ for {
+ _, err := client.Ready(ctx)
+ if err != nil {
+ log.Printf("Influx not ready: %v", err)
+ time.Sleep(1 * time.Second)
+ continue
+ }
+ break
+ }
+
+ log.Printf("Influx ready!")
+
+ allowed, err := setupAllowed(ctx)
+ if err != nil {
+ return fmt.Errorf("error checking setup: %w", err)
+ }
+ if !allowed {
+ log.Printf("Influx already set up!")
+ return nil
+ }
+
+ secrets, err := setupUsers(ctx, client)
+ if err != nil {
+ return fmt.Errorf("error setting up users: %w", err)
+ }
+
+ if err := secrets.recordOrLog(ctx); err != nil {
+ return fmt.Errorf("error recording secrets: %w", err)
+ }
+
+ log.Printf("Influx setup complete!")
+ return nil
+}
+
+// Setup is the response to Influx GET /api/v2/setup.
+type Setup struct {
+ Allowed bool `json:"allowed"`
+}
+
+// setupAllowed returns true if Influx setup is allowed. i.e., the server has
+// not already been set up.
+//
+// The Influx Go client unfortunately doesn't expose a method to query this, so
+// we must access the API directly.
+func setupAllowed(ctx context.Context) (bool, error) {
+ req, err := http.NewRequestWithContext(ctx, "GET", influxURL+"/api/v2/setup", nil)
+ if err != nil {
+ return false, fmt.Errorf("error creating request: %w", err)
+ }
+
+ // Connecting via localhost with self-signed certs, so no cert checks.
+ client := &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ },
+ }
+ resp, err := client.Do(req)
+ if err != nil {
+ return false, fmt.Errorf("error send request: %w", err)
+ }
+ defer resp.Body.Close()
+
+ var s Setup
+ d := json.NewDecoder(resp.Body)
+ if err := d.Decode(&s); err != nil {
+ return false, fmt.Errorf("error decoding response: %w", err)
+ }
+
+ return s.Allowed, nil
+}
+
+type influxSecrets struct {
+ adminPass string
+ adminToken string
+ readerPass string
+ readerToken string
+}
+
+const (
+ adminPassSecretName = "influx-admin-pass"
+ adminTokenSecretName = "influx-admin-token"
+ readerPassSecretName = "influx-reader-pass"
+ readerTokenSecretName = "influx-reader-token"
+)
+
+// recordOrLog saves the secrets to Secret Manager, if available, or simply
+// logs them when not running on GCP.
+func (i *influxSecrets) recordOrLog(ctx context.Context) error {
+ projectID, err := metadata.ProjectID()
+ if err != nil {
+ log.Printf("Error fetching GCP project ID: %v", err)
+ log.Printf("Assuming I am running locally.")
+ log.Printf("Admin password: %s", i.adminPass)
+ log.Printf("Admin token: %s", i.adminToken)
+ log.Printf("Reader password: %s", i.readerPass)
+ log.Printf("Reader token: %s", i.readerToken)
+ return nil
+ }
+
+ client, err := secretmanager.NewClient(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating secret manager client: %w", err)
+ }
+ defer client.Close()
+
+ addSecretVersion := func(name, data string) error {
+ parent := fmt.Sprintf("projects/%s/secrets/%s", projectID, name)
+ req := &secretmanagerpb.AddSecretVersionRequest{
+ Parent: parent,
+ Payload: &secretmanagerpb.SecretPayload{
+ Data: []byte(data),
+ },
+ }
+
+ if _, err := client.AddSecretVersion(ctx, req); err != nil {
+ return fmt.Errorf("add secret version error: %w", err)
+ }
+
+ log.Printf("Secret added to %s", parent)
+
+ return nil
+ }
+
+ if err := addSecretVersion(adminPassSecretName, i.adminPass); err != nil {
+ return fmt.Errorf("error adding admin password secret: %w", err)
+ }
+ if err := addSecretVersion(adminTokenSecretName, i.adminToken); err != nil {
+ return fmt.Errorf("error adding admin token secret: %w", err)
+ }
+ if err := addSecretVersion(readerPassSecretName, i.readerPass); err != nil {
+ return fmt.Errorf("error adding reader password secret: %w", err)
+ }
+ if err := addSecretVersion(readerTokenSecretName, i.readerToken); err != nil {
+ return fmt.Errorf("error adding reader token secret: %w", err)
+ }
+
+ log.Printf("Secrets added to secret manager")
+
+ return nil
+}
+
+// setupUsers sets up an 'admin' and 'reader' user on a new InfluxDB instance.
+func setupUsers(ctx context.Context, client influxdb2.Client) (influxSecrets, error) {
+ adminPass, err := generatePassword()
+ if err != nil {
+ return influxSecrets{}, fmt.Errorf("error generating 'admin' password: %w", err)
+ }
+
+ // Initial instance setup; creates admin user.
+ onboard, err := client.Setup(ctx, "admin", adminPass, "golang", "perf", 0)
+ if err != nil {
+ return influxSecrets{}, fmt.Errorf("influx setup error: %w", err)
+ }
+
+ // Create a read-only user.
+ reader, err := client.UsersAPI().CreateUserWithName(ctx, "reader")
+ if err != nil {
+ return influxSecrets{}, fmt.Errorf("error creating user 'reader': %w", err)
+ }
+
+ readerPass, err := generatePassword()
+ if err != nil {
+ return influxSecrets{}, fmt.Errorf("error generating 'reader' password: %w", err)
+ }
+
+ if err := client.UsersAPI().UpdateUserPassword(ctx, reader, readerPass); err != nil {
+ return influxSecrets{}, fmt.Errorf("error setting 'reader' password: %w", err)
+ }
+
+ // Add 'reader' to 'golang' org.
+ if _, err := client.OrganizationsAPI().AddMember(ctx, onboard.Org, reader); err != nil {
+ return influxSecrets{}, fmt.Errorf("error adding 'reader' to org 'golang': %w", err)
+ }
+
+ // Grant read access to buckets and dashboards.
+ newAuth := &domain.Authorization{
+ OrgID: onboard.Org.Id,
+ UserID: reader.Id,
+ Permissions: &[]domain.Permission{
+ {
+ Action: domain.PermissionActionRead,
+ Resource: domain.Resource{
+ Type: domain.ResourceTypeBuckets,
+ },
+ },
+ {
+ Action: domain.PermissionActionRead,
+ Resource: domain.Resource{
+ Type: domain.ResourceTypeDashboards,
+ },
+ },
+ },
+ }
+ auth, err := client.AuthorizationsAPI().CreateAuthorization(ctx, newAuth)
+ if err != nil {
+ return influxSecrets{}, fmt.Errorf("error granting access to 'reader': %w", err)
+ }
+
+ return influxSecrets{
+ adminPass: adminPass,
+ adminToken: *onboard.Auth.Token,
+ readerPass: readerPass,
+ readerToken: *auth.Token,
+ }, nil
+}
+
+func generatePassword() (string, error) {
+ const passwordCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_+`-={}|[]\\:\"<>?,./"
+ const length = 64
+
+ b := make([]byte, 0, length)
+ max := big.NewInt(int64(len(passwordCharacters) - 1))
+ for i := 0; i < length; i++ {
+ j, err := rand.Int(rand.Reader, max)
+ if err != nil {
+ return "", fmt.Errorf("error generating random number: %w", err)
+ }
+ b = append(b, passwordCharacters[j.Int64()])
+ }
+
+ return string(b), nil
+}

To view, visit change 394354. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: build
Gerrit-Branch: master
Gerrit-Change-Id: Ib79242311acee9529073cd68c9754e6459a49319
Gerrit-Change-Number: 394354
Gerrit-PatchSet: 5
Gerrit-Owner: Michael Pratt <mpr...@google.com>
Gerrit-Reviewer: Dmitri Shuralyov <dmit...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
Gerrit-Reviewer: Michael Pratt <mpr...@google.com>
Gerrit-CC: Michael Knyszek <mkny...@google.com>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages