diff --git a/.gitignore b/.gitignore index f0583180fa..0064305ae9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ ui/reports/ build/ backup/ +vendor/ .vscode/ # Binaries diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index a0654c8e76..0000000000 --- a/Gopkg.lock +++ /dev/null @@ -1,623 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/BurntSushi/toml" - packages = ["."] - revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005" - version = "v0.3.1" - -[[projects]] - name = "github.com/Masterminds/semver" - packages = ["."] - revision = "c7af12943936e8c39859482e61f0574c2fd7fc75" - version = "v1.4.2" - -[[projects]] - name = "github.com/NYTimes/gziphandler" - packages = ["."] - revision = "6710af535839f57c687b62c4c23d649f9545d885" - -[[projects]] - name = "github.com/Sirupsen/logrus" - packages = ["."] - revision = "3ec0642a7fb6488f65b06f9040adc67e3990296a" - -[[projects]] - name = "github.com/alecthomas/kingpin" - packages = ["."] - revision = "947dcec5ba9c011838740e680966fd7087a71d0d" - version = "v2.2.6" - -[[projects]] - branch = "master" - name = "github.com/alecthomas/template" - packages = [ - ".", - "parse" - ] - revision = "a0175ee3bccc567396460bf5acd36800cb10c49c" - -[[projects]] - branch = "master" - name = "github.com/alecthomas/units" - packages = ["."] - revision = "2efee857e7cfd4f3d0138cc3cbb1b4966962b93a" - -[[projects]] - branch = "master" - name = "github.com/apache/arrow" - packages = [ - "go/arrow", - "go/arrow/array", - "go/arrow/internal/bitutil", - "go/arrow/internal/cpu", - "go/arrow/internal/debug", - "go/arrow/math", - "go/arrow/memory" - ] - revision = "cf047fc67698fe3655471da64ced8d9335668dc4" - -[[projects]] - name = "github.com/apex/log" - packages = [ - ".", - "handlers/cli" - ] - revision = "941dea75d3ebfbdd905a5d8b7b232965c5e5c684" - version = "v1.1.0" - -[[projects]] - name = "github.com/aws/aws-sdk-go" - packages = [ - "aws", - "aws/awserr", - "aws/awsutil", - "aws/client", - "aws/client/metadata", - "aws/corehandlers", - "aws/credentials", - "aws/credentials/ec2rolecreds", - "aws/credentials/endpointcreds", - "aws/credentials/processcreds", - "aws/credentials/stscreds", - "aws/csm", - "aws/defaults", - "aws/ec2metadata", - "aws/endpoints", - "aws/request", - "aws/session", - "aws/signer/v4", - "internal/ini", - "internal/s3err", - "internal/sdkio", - "internal/sdkrand", - "internal/sdkuri", - "internal/shareddefaults", - "private/protocol", - "private/protocol/eventstream", - "private/protocol/eventstream/eventstreamapi", - "private/protocol/query", - "private/protocol/query/queryutil", - "private/protocol/rest", - "private/protocol/restxml", - "private/protocol/xml/xmlutil", - "service/s3", - "service/sts" - ] - revision = "aabf189db35ba7eb5a35afe6d681fc0f70954fca" - version = "v1.16.18" - -[[projects]] - branch = "master" - name = "github.com/blakesmith/ar" - packages = ["."] - revision = "8bd4349a67f2533b078dbc524689d15dba0f4659" - -[[projects]] - name = "github.com/boltdb/bolt" - packages = ["."] - revision = "5cc10bbbc5c141029940133bb33c9e969512a698" - -[[projects]] - name = "github.com/bouk/httprouter" - packages = ["."] - revision = "ee8b3818a7f51fbc94cc709b5744b52c2c725e91" - -[[projects]] - name = "github.com/caarlos0/ctrlc" - packages = ["."] - revision = "70dc48d5d792f20f684a8f1d29bbac298f4b2ef4" - version = "v1.0.0" - -[[projects]] - branch = "master" - name = "github.com/campoy/unique" - packages = ["."] - revision = "88950e537e7e644cd746a3102037b5d2b723e9f5" - -[[projects]] - name = "github.com/cespare/xxhash" - packages = ["."] - revision = "569f7c8abf1f58d9043ab804d364483cb1c853b6" - version = "v1.1.0" - -[[projects]] - name = "github.com/dgrijalva/jwt-go" - packages = ["."] - revision = "24c63f56522a87ec5339cc3567883f1039378fdb" - -[[projects]] - branch = "master" - name = "github.com/dustin/go-humanize" - packages = ["."] - revision = "bb3d318650d48840a39aa21a027c6630e198e626" - -[[projects]] - name = "github.com/elazarl/go-bindata-assetfs" - packages = ["."] - revision = "9a6736ed45b44bf3835afeebb3034b57ed329f3e" - -[[projects]] - name = "github.com/fatih/color" - packages = ["."] - revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4" - version = "v1.7.0" - -[[projects]] - name = "github.com/go-sql-driver/mysql" - packages = ["."] - revision = "d523deb1b23d913de5bdada721a6071e71283618" - version = "v1.4.0" - -[[projects]] - name = "github.com/gogo/protobuf" - packages = [ - "gogoproto", - "jsonpb", - "plugin/compare", - "plugin/defaultcheck", - "plugin/description", - "plugin/embedcheck", - "plugin/enumstringer", - "plugin/equal", - "plugin/face", - "plugin/gostring", - "plugin/marshalto", - "plugin/oneofcheck", - "plugin/populate", - "plugin/size", - "plugin/stringer", - "plugin/testgen", - "plugin/union", - "plugin/unmarshal", - "proto", - "protoc-gen-gogo", - "protoc-gen-gogo/descriptor", - "protoc-gen-gogo/generator", - "protoc-gen-gogo/grpc", - "protoc-gen-gogo/plugin", - "sortkeys", - "types", - "vanity", - "vanity/command" - ] - revision = "49944b4a4b085da44c43d4b233ea40787396371f" - -[[projects]] - name = "github.com/golang/protobuf" - packages = ["proto"] - revision = "925541529c1fa6821df4e44ce2723319eb2be768" - version = "v1.0.0" - -[[projects]] - name = "github.com/google/go-cmp" - packages = [ - "cmp", - "cmp/cmpopts", - "cmp/internal/diff", - "cmp/internal/function", - "cmp/internal/value" - ] - revision = "8099a9787ce5dc5984ed879a3bda47dc730a8e97" - version = "v0.1.0" - -[[projects]] - name = "github.com/google/go-github" - packages = ["github"] - revision = "1bc362c7737e51014af7299e016444b654095ad9" - -[[projects]] - branch = "master" - name = "github.com/google/go-querystring" - packages = ["query"] - revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a" - -[[projects]] - name = "github.com/goreleaser/goreleaser" - packages = [ - ".", - "internal/artifact", - "internal/builders/golang", - "internal/client", - "internal/deprecate", - "internal/git", - "internal/http", - "internal/linux", - "internal/pipe", - "internal/pipe/archive", - "internal/pipe/artifactory", - "internal/pipe/before", - "internal/pipe/brew", - "internal/pipe/build", - "internal/pipe/changelog", - "internal/pipe/checksums", - "internal/pipe/defaults", - "internal/pipe/dist", - "internal/pipe/docker", - "internal/pipe/effectiveconfig", - "internal/pipe/env", - "internal/pipe/git", - "internal/pipe/nfpm", - "internal/pipe/project", - "internal/pipe/publish", - "internal/pipe/put", - "internal/pipe/release", - "internal/pipe/s3", - "internal/pipe/scoop", - "internal/pipe/sign", - "internal/pipe/snapcraft", - "internal/pipe/snapshot", - "internal/pipeline", - "internal/semerrgroup", - "internal/tmpl", - "pkg/archive", - "pkg/archive/tar", - "pkg/archive/zip", - "pkg/build", - "pkg/config", - "pkg/context", - "pkg/defaults" - ] - revision = "cdfaae9b28aa507ad27ce18497bbb38b65428d5b" - version = "v0.97.0" - -[[projects]] - name = "github.com/goreleaser/nfpm" - packages = [ - ".", - "deb", - "glob", - "rpm" - ] - revision = "11452f4e2a77580f157cc3df3f4e33b30a088062" - version = "v0.9.7" - -[[projects]] - name = "github.com/imdario/mergo" - packages = ["."] - revision = "9f23e2d6bd2a77f959b2bf6acdbefd708a83a4a4" - version = "v0.3.6" - -[[projects]] - name = "github.com/influxdata/flux" - packages = [ - ".", - "arrow", - "ast", - "builtin", - "compiler", - "complete", - "csv", - "execute", - "functions", - "functions/inputs", - "functions/outputs", - "functions/tests", - "functions/transformations", - "influxql", - "internal/parser", - "internal/pkg/syncutil", - "internal/scanner", - "internal/token", - "interpreter", - "iocounter", - "memory", - "options", - "parser", - "plan", - "semantic", - "values" - ] - revision = "8c9d0ad49204d3bbb171e96d872cf663ee7f1b4d" - version = "v0.12.0" - -[[projects]] - name = "github.com/influxdata/influxdb" - packages = [ - "influxql", - "influxql/internal", - "influxql/neldermead", - "models", - "pkg/escape" - ] - revision = "cd9363b52cac452113b95554d98a6be51beda24e" - version = "v1.1.5" - -[[projects]] - name = "github.com/influxdata/kapacitor" - packages = [ - "client/v1", - "pipeline", - "pipeline/tick", - "services/k8s/client", - "tick", - "tick/ast", - "tick/stateful", - "udf/agent" - ] - revision = "4f10efc41b4dcac070495cf95ba2c41cfcc2aa3a" - -[[projects]] - branch = "master" - name = "github.com/influxdata/line-protocol" - packages = ["."] - revision = "32c6aa80de5eb09d190ad284a8214a531c6bce57" - -[[projects]] - branch = "master" - name = "github.com/influxdata/tdigest" - packages = ["."] - revision = "a7d76c6f093a59b94a01c6c2b8429122d444a8cc" - -[[projects]] - name = "github.com/influxdata/usage-client" - packages = ["v1"] - revision = "6d3895376368aa52a3a81d2a16e90f0f52371967" - -[[projects]] - name = "github.com/jessevdk/go-flags" - packages = ["."] - revision = "4cc2832a6e6d1d3b815e2b9d544b2a4dfb3ce8fa" - -[[projects]] - name = "github.com/jmespath/go-jmespath" - packages = ["."] - revision = "c2b33e84" - -[[projects]] - name = "github.com/kamilsk/retry" - packages = [ - ".", - "backoff", - "jitter", - "strategy" - ] - revision = "495c1d672c9304451ea270d18f444ba504ce0e96" - version = "3.3.0" - -[[projects]] - name = "github.com/kevinburke/go-bindata" - packages = ["."] - revision = "46eb4c183bfc1ebb527d9d19bcded39476302eb8" - -[[projects]] - name = "github.com/lib/pq" - packages = [ - ".", - "oid" - ] - revision = "4ded0e9383f75c197b3a2aaa6d590ac52df6fd79" - version = "v1.0.0" - -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" - version = "v0.0.4" - -[[projects]] - name = "github.com/mattn/go-zglob" - packages = [ - ".", - "fastwalk" - ] - revision = "2ea3427bfa539cca900ca2768d8663ecc8a708c1" - version = "v0.0.1" - -[[projects]] - name = "github.com/microcosm-cc/bluemonday" - packages = ["."] - revision = "82c7118e8ccf7403d4860175d97bb635e8e28239" - version = "v1.0.1" - -[[projects]] - name = "github.com/mitchellh/go-homedir" - packages = ["."] - revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4" - version = "v1.0.0" - -[[projects]] - name = "github.com/opentracing/opentracing-go" - packages = [ - ".", - "log" - ] - revision = "1949ddbfd147afd4d964a9f00b24eb291e0e7c38" - version = "v1.0.2" - -[[projects]] - name = "github.com/pkg/errors" - packages = ["."] - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" - -[[projects]] - name = "github.com/satori/go.uuid" - packages = ["."] - revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a" - -[[projects]] - name = "github.com/segmentio/kafka-go" - packages = ["."] - revision = "c6db9435477f3cb658e2dd0fa93e02118c870251" - version = "v0.2.0" - -[[projects]] - name = "github.com/sergi/go-diff" - packages = ["diffmatchpatch"] - revision = "1d28411638c1e67fe1930830df207bef72496ae9" - -[[projects]] - name = "github.com/tylerb/graceful" - packages = ["."] - revision = "4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb" - version = "v1.2.15" - -[[projects]] - name = "go.uber.org/atomic" - packages = ["."] - revision = "1ea20fb1cbb1cc08cbd0d913a96dead89aa18289" - version = "v1.3.2" - -[[projects]] - name = "go.uber.org/multierr" - packages = ["."] - revision = "3c4937480c32f4c13a875a1829af76c98ca3d40a" - version = "v1.1.0" - -[[projects]] - name = "go.uber.org/zap" - packages = [ - ".", - "buffer", - "internal/bufferpool", - "internal/color", - "internal/exit", - "zapcore" - ] - revision = "ff33455a0e382e8a81d14dd7c922020b6b5e7982" - version = "v1.9.1" - -[[projects]] - name = "golang.org/x/net" - packages = [ - "context", - "context/ctxhttp", - "html", - "html/atom" - ] - revision = "749a502dd1eaf3e5bfd4f8956748c502357c0bbe" - -[[projects]] - name = "golang.org/x/oauth2" - packages = [ - ".", - "github", - "heroku", - "internal" - ] - revision = "2f32c3ac0fa4fb807a0fcefb0b6f2468a0d99bd0" - -[[projects]] - branch = "master" - name = "golang.org/x/sync" - packages = ["errgroup"] - revision = "37e7f081c4d4c64e13b10787722085407fe5d15f" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "37707fdb30a5b38865cfb95e5aab41707daec7fd" - -[[projects]] - branch = "master" - name = "golang.org/x/tools" - packages = [ - "go/ast/astutil", - "go/buildutil", - "go/gcexportdata", - "go/internal/cgo", - "go/internal/gcimporter", - "go/internal/packagesdriver", - "go/loader", - "go/packages", - "go/types/typeutil", - "internal/fastwalk", - "internal/gopathwalk", - "internal/semver" - ] - revision = "36f37f8f5c8169a4482a16bcccc34b26413e704c" - -[[projects]] - name = "google.golang.org/api" - packages = [ - "gensupport", - "googleapi", - "googleapi/internal/uritemplates", - "oauth2/v2" - ] - revision = "bc20c61134e1d25265dd60049f5735381e79b631" - -[[projects]] - name = "google.golang.org/appengine" - packages = [ - "cloudsql", - "internal", - "internal/base", - "internal/datastore", - "internal/log", - "internal/remote_api", - "internal/urlfetch", - "urlfetch" - ] - revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a" - version = "v1.0.0" - -[[projects]] - name = "gopkg.in/yaml.v2" - packages = ["."] - revision = "51d6538a90f86fe93ac480b35f37b2be17fef232" - version = "v2.2.2" - -[[projects]] - name = "honnef.co/go/tools" - packages = [ - "arg", - "callgraph", - "callgraph/static", - "cmd/staticcheck", - "config", - "deprecated", - "functions", - "internal/sharedcheck", - "lint", - "lint/lintdsl", - "lint/lintutil", - "lint/lintutil/format", - "simple", - "ssa", - "ssa/ssautil", - "ssautil", - "staticcheck", - "staticcheck/vrp", - "stylecheck", - "unused", - "version" - ] - revision = "c2f93a96b099cbbec1de36336ab049ffa620e6d7" - version = "2019.1" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "746e9e9ab66fdf249af354fe2387678b95ac6d96f48014d577eab26bdfd9ab35" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index 73d3977690..0000000000 --- a/Gopkg.toml +++ /dev/null @@ -1,85 +0,0 @@ -required = ["github.com/kevinburke/go-bindata","github.com/gogo/protobuf/proto","github.com/gogo/protobuf/jsonpb","github.com/gogo/protobuf/protoc-gen-gogo","github.com/gogo/protobuf/gogoproto"] - -[[constraint]] - name = "github.com/NYTimes/gziphandler" - revision = "6710af535839f57c687b62c4c23d649f9545d885" - -[[constraint]] - name = "github.com/Sirupsen/logrus" - revision = "3ec0642a7fb6488f65b06f9040adc67e3990296a" - -[[constraint]] - name = "github.com/boltdb/bolt" - revision = "5cc10bbbc5c141029940133bb33c9e969512a698" - -[[constraint]] - name = "github.com/bouk/httprouter" - revision = "ee8b3818a7f51fbc94cc709b5744b52c2c725e91" - -[[constraint]] - name = "github.com/dgrijalva/jwt-go" - revision = "24c63f56522a87ec5339cc3567883f1039378fdb" - -[[constraint]] - name = "github.com/elazarl/go-bindata-assetfs" - revision = "9a6736ed45b44bf3835afeebb3034b57ed329f3e" - -[[constraint]] - name = "github.com/gogo/protobuf" - revision = "49944b4a4b085da44c43d4b233ea40787396371f" - -[[constraint]] - name = "github.com/google/go-github" - revision = "1bc362c7737e51014af7299e016444b654095ad9" - -[[constraint]] - name = "github.com/influxdata/usage-client" - revision = "6d3895376368aa52a3a81d2a16e90f0f52371967" - -[[constraint]] - name = "github.com/jessevdk/go-flags" - revision = "4cc2832a6e6d1d3b815e2b9d544b2a4dfb3ce8fa" - -[[constraint]] - name = "github.com/kevinburke/go-bindata" - revision = "46eb4c183bfc1ebb527d9d19bcded39476302eb8" - -[[constraint]] - name = "github.com/satori/go.uuid" - revision = "b061729afc07e77a8aa4fad0a2fd840958f1942a" - -[[constraint]] - name = "github.com/sergi/go-diff" - revision = "1d28411638c1e67fe1930830df207bef72496ae9" - -[[constraint]] - name = "github.com/tylerb/graceful" - version = "^1.2.13" - -[[constraint]] - name = "golang.org/x/net" - revision = "749a502dd1eaf3e5bfd4f8956748c502357c0bbe" - -[[constraint]] - name = "golang.org/x/oauth2" - revision = "2f32c3ac0fa4fb807a0fcefb0b6f2468a0d99bd0" - -[[constraint]] - name = "google.golang.org/api" - revision = "bc20c61134e1d25265dd60049f5735381e79b631" - -[[constraint]] - name = "github.com/influxdata/influxdb" - version = "~1.1.0" - -[[constraint]] - name = "github.com/influxdata/kapacitor" - revision = "4f10efc41b4dcac070495cf95ba2c41cfcc2aa3a" - -[[constraint]] - name = "github.com/microcosm-cc/bluemonday" - version = "1.0.1" - -[[constraint]] - name = "github.com/influxdata/flux" - version = "0.12.0" diff --git a/LICENSE_OF_DEPENDENCIES.md b/LICENSE_OF_DEPENDENCIES.md index 3476dcda8f..3e55bea6bc 100644 --- a/LICENSE_OF_DEPENDENCIES.md +++ b/LICENSE_OF_DEPENDENCIES.md @@ -1,6 +1,6 @@ ### Go * github.com/NYTimes/gziphandler [APACHE-2.0](https://github.com/NYTimes/gziphandler/blob/master/LICENSE.md) -* github.com/Sirupsen/logrus [MIT](https://github.com/Sirupsen/logrus/blob/master/LICENSE) +* github.com/sirupsen/logrus [MIT](https://github.com/sirupsen/logrus/blob/master/LICENSE) * github.com/boltdb/bolt [MIT](https://github.com/boltdb/bolt/blob/master/LICENSE) * github.com/bouk/httprouter [BSD](https://github.com/bouk/httprouter/blob/master/LICENSE) * github.com/dgrijalva/jwt-go [MIT](https://github.com/dgrijalva/jwt-go/blob/master/LICENSE) diff --git a/cmd/chronoctl/util.go b/cmd/chronoctl/util.go index f40635dbd9..bd70b15336 100644 --- a/cmd/chronoctl/util.go +++ b/cmd/chronoctl/util.go @@ -9,7 +9,7 @@ import ( "text/tabwriter" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" + "github.com/influxdata/chronograf/kv/bolt" "github.com/influxdata/chronograf/mocks" ) diff --git a/cmd/chronograf/main.go b/cmd/chronograf/main.go index 729ca78567..396c5b6094 100644 --- a/cmd/chronograf/main.go +++ b/cmd/chronograf/main.go @@ -2,7 +2,7 @@ package main import ( "context" - "log" + "fmt" "os" "github.com/influxdata/chronograf" @@ -39,12 +39,9 @@ func main() { } if srv.ShowVersion { - log.Printf("Chronograf %s (git: %s)\n", version, commit) + fmt.Printf("Chronograf %s (git: %s)\n", version, commit) os.Exit(0) } - ctx := context.Background() - if err := srv.Serve(ctx); err != nil { - log.Fatalln(err) - } + srv.Serve(context.Background()) } diff --git a/enterprise/meta_test.go b/enterprise/meta_test.go index 7cdd6fa818..9f0dd8ff54 100644 --- a/enterprise/meta_test.go +++ b/enterprise/meta_test.go @@ -168,7 +168,7 @@ func TestMetaClient_Users(t *testing.T) { { Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -199,7 +199,7 @@ func TestMetaClient_Users(t *testing.T) { { Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -303,7 +303,7 @@ func TestMetaClient_User(t *testing.T) { want: &User{ Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -739,7 +739,7 @@ func TestMetaClient_Roles(t *testing.T) { { Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -771,7 +771,7 @@ func TestMetaClient_Roles(t *testing.T) { { Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -836,7 +836,7 @@ func TestMetaClient_Role(t *testing.T) { want: &Role{ Name: "admin", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -917,12 +917,12 @@ func TestMetaClient_UserRoles(t *testing.T) { name: nil, }, want: map[string]Roles{ - "marty": Roles{ + "marty": { Roles: []Role{ { Name: "timetravelers", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -931,7 +931,7 @@ func TestMetaClient_UserRoles(t *testing.T) { { Name: "mcfly", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -939,12 +939,12 @@ func TestMetaClient_UserRoles(t *testing.T) { }, }, }, - "docbrown": Roles{ + "docbrown": { Roles: []Role{ { Name: "timetravelers", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, @@ -952,12 +952,12 @@ func TestMetaClient_UserRoles(t *testing.T) { }, }, }, - "george": Roles{ + "george": { Roles: []Role{ { Name: "mcfly", Permissions: map[string][]string{ - "": []string{ + "": { "ViewAdmin", "ViewChronograf", }, }, diff --git a/enterprise/mocks_test.go b/enterprise/mocks_test.go index 0f3a3b42fa..c35fceee4f 100644 --- a/enterprise/mocks_test.go +++ b/enterprise/mocks_test.go @@ -23,7 +23,7 @@ func NewMockControlClient(addr string) *ControlClient { return &ControlClient{ Cluster: &enterprise.Cluster{ DataNodes: []enterprise.DataNode{ - enterprise.DataNode{ + { HTTPAddr: addr, }, }, diff --git a/enterprise/users_test.go b/enterprise/users_test.go index afd13fedb6..c715287ef0 100644 --- a/enterprise/users_test.go +++ b/enterprise/users_test.go @@ -97,7 +97,7 @@ func TestClient_Add(t *testing.T) { }, userRoles: func(ctx context.Context) (map[string]enterprise.Roles, error) { return map[string]enterprise.Roles{ - "marty": enterprise.Roles{ + "marty": { Roles: []enterprise.Role{ { Name: "admin", @@ -309,7 +309,7 @@ func TestClient_Get(t *testing.T) { }, userRoles: func(ctx context.Context) (map[string]enterprise.Roles, error) { return map[string]enterprise.Roles{ - "marty": enterprise.Roles{ + "marty": { Roles: []enterprise.Role{ { Name: "timetravels", diff --git a/go.mod b/go.mod index 360a1d42d1..5aa34f9779 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,42 @@ module github.com/influxdata/chronograf require ( - github.com/NYTimes/gziphandler v0.0.0-20170104155701-6710af535839 - github.com/Sirupsen/logrus v0.0.0-20160829202321-3ec0642a7fb6 - github.com/aws/aws-sdk-go v1.16.18 // indirect - github.com/boltdb/bolt v0.0.0-20160719165138-5cc10bbbc5c1 + github.com/NYTimes/gziphandler v1.1.1 + github.com/aws/aws-sdk-go v1.27.1 // indirect + github.com/boltdb/bolt v1.3.1 github.com/bouk/httprouter v0.0.0-20160817010721-ee8b3818a7f5 - github.com/dgrijalva/jwt-go v0.0.0-20160831183534-24c63f56522a - github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 // indirect - github.com/elazarl/go-bindata-assetfs v0.0.0-20160822204401-9a6736ed45b4 - github.com/gogo/protobuf v1.1.1 + github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/elazarl/go-bindata-assetfs v1.0.0 + github.com/gogo/protobuf v1.3.1 github.com/google/go-cmp v0.3.0 github.com/google/go-github v17.0.0+incompatible github.com/goreleaser/goreleaser v0.97.0 // indirect github.com/influxdata/flux v0.50.2 github.com/influxdata/influxdb v1.1.5 - github.com/influxdata/kapacitor v1.5.0 + github.com/influxdata/kapacitor v1.5.3 github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368 github.com/jessevdk/go-flags v1.4.0 github.com/lestrrat-go/jwx v0.9.0 + github.com/mattn/go-isatty v0.0.11 // indirect github.com/mattn/go-zglob v0.0.1 // indirect - github.com/microcosm-cc/bluemonday v1.0.1 + github.com/microcosm-cc/bluemonday v1.0.2 github.com/satori/go.uuid v1.2.0 - github.com/segmentio/kafka-go v0.2.0 // indirect - github.com/sergi/go-diff v1.0.0 - github.com/tylerb/graceful v1.2.15 - golang.org/x/net v0.0.0-20190620200207-3b0461eec859 + github.com/segmentio/kafka-go v0.3.4 // indirect + github.com/sergi/go-diff v1.1.0 + github.com/sirupsen/logrus v1.2.0 + github.com/stretchr/testify v1.4.0 + go.uber.org/atomic v1.5.1 // indirect + go.uber.org/multierr v1.4.0 // indirect + go.uber.org/zap v1.13.0 // indirect + golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 // indirect + golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect + golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - google.golang.org/api v0.7.0 + golang.org/x/sys v0.0.0-20200107162124-548cf772de50 // indirect + golang.org/x/tools v0.0.0-20200107050322-53017a39ae36 // indirect + google.golang.org/api v0.15.0 + gopkg.in/yaml.v2 v2.2.7 // indirect ) go 1.13 diff --git a/go.sum b/go.sum index 49a34181e7..e669a6bdf7 100644 --- a/go.sum +++ b/go.sum @@ -8,14 +8,14 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DataDog/zstd v1.4.0 h1:vhoV+DUHnRZdKW1i5UMjAk2G4JY8wN4ayRfYDNdEhwo= +github.com/DataDog/zstd v1.4.0/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/NYTimes/gziphandler v0.0.0-20170104155701-6710af535839 h1:8pTAlrxf5XHylXJ0n3iSEeUwMr/JVfI3QuPYeqCtAxI= -github.com/NYTimes/gziphandler v0.0.0-20170104155701-6710af535839/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/Sirupsen/logrus v0.0.0-20160829202321-3ec0642a7fb6 h1:Tp6VdyWz8sPuNnRbgf5jqIOV/zoG4mA5nBHtJyFb4Hc= -github.com/Sirupsen/logrus v0.0.0-20160829202321-3ec0642a7fb6/go.mod h1:rmk17hk6i8ZSAJkSDa7nOxamrG+SP4P0mm+DAvExv4U= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= @@ -33,14 +33,14 @@ github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VT github.com/apex/log v1.1.0 h1:J5rld6WVFi6NxA6m8GJ1LJqu3+GiTFIt3mYv27gdQWI= github.com/apex/log v1.1.0/go.mod h1:yA770aXIDQrhVOIGurT/pVdfCpSq1GQV/auzMN5fzvY= github.com/aws/aws-sdk-go v1.15.64/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= -github.com/aws/aws-sdk-go v1.16.18 h1:ZXmG9Uexu2f2kKK0Onlod3Hl4X77qQvCGx2725fSubI= -github.com/aws/aws-sdk-go v1.16.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.27.1 h1:MXnqY6SlWySaZAqNnXThOvjRFdiiOuKtC6i7baFdNdU= +github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI= github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/boltdb/bolt v0.0.0-20160719165138-5cc10bbbc5c1 h1:q9yLov1P/SSEhLUjkPInemOX1JOqnD1FwS2a5CzQu4Q= -github.com/boltdb/bolt v0.0.0-20160719165138-5cc10bbbc5c1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bouk/httprouter v0.0.0-20160817010721-ee8b3818a7f5 h1:kS0dw4K730x7cxT+bVyTyYJZHuSoH7ofSr/Ijit56Qw= github.com/bouk/httprouter v0.0.0-20160817010721-ee8b3818a7f5/go.mod h1:CDReaxg1cmLrtcasZy43l4EYPAknXLiQSrb7tLw5zXM= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= @@ -55,14 +55,16 @@ github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhr 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/dgrijalva/jwt-go v0.0.0-20160831183534-24c63f56522a h1:K2z/e+U9Bdiie++eZOQOq+ty5J4IqOO0lZtx58/4ko0= -github.com/dgrijalva/jwt-go v0.0.0-20160831183534-24c63f56522a/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4 h1:qk/FSDDxo05wdJH28W+p5yivv7LuLYLRXPPD8KQCtZs= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eclipse/paho.mqtt.golang v1.2.0 h1:1F8mhG9+aO5/xpdtFkW4SxOJB67ukuDC3t2y2qayIX0= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/elazarl/go-bindata-assetfs v0.0.0-20160822204401-9a6736ed45b4 h1:Jg5/sOI1MJzw6u2J1qA3Nu6JvdHE1ulquzMn/sscg2Y= -github.com/elazarl/go-bindata-assetfs v0.0.0-20160822204401-9a6736ed45b4/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= @@ -79,6 +81,8 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -91,6 +95,8 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -107,6 +113,7 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -129,8 +136,8 @@ github.com/influxdata/flux v0.50.2 h1:3qSoVZ5y1kjlQ0kPQ0sHZ8Wl0bi5NOxcIH0xGEG1GZ github.com/influxdata/flux v0.50.2/go.mod h1:absI6L1dQnJhd0+NFj+Kl/BVTnm/BG1dbJIHDiDQbA4= github.com/influxdata/influxdb v1.1.5 h1:mcUdmJAuYUelNpzL8sV7OKcTJK2AuawOjUOYLrjUHk0= github.com/influxdata/influxdb v1.1.5/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= -github.com/influxdata/kapacitor v1.5.0 h1:zTPfVe9Zun23yww/C5ebRmvW4jnqIBmyts15Z0fA8Pk= -github.com/influxdata/kapacitor v1.5.0/go.mod h1:vv15yTwFBi1kUhCUrM/PGdfsbh5Y5F8BaCrdOg2S+d8= +github.com/influxdata/kapacitor v1.5.3 h1:+UzRGH5j20i3ePFV9TyO95P5HpiKNwOCjGw5utcdQyo= +github.com/influxdata/kapacitor v1.5.3/go.mod h1:vv15yTwFBi1kUhCUrM/PGdfsbh5Y5F8BaCrdOg2S+d8= github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e h1:/o3vQtpWJhvnIbXley4/jwzzqNeigJK9z+LZcJZ9zfM= github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= @@ -152,6 +159,9 @@ github.com/kamilsk/retry v0.0.0-20181229152359-495c1d672c93 h1:aP888S37c3tqOCllQ github.com/kamilsk/retry v0.0.0-20181229152359-495c1d672c93/go.mod h1:vW4uuVWZOGWqkbtgGTNPGAiuN2nUBz0qYr4tb2ww4x8= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -167,6 +177,8 @@ github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRU github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/go-zglob v0.0.0-20171230104132-4959821b4817/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= @@ -175,8 +187,8 @@ github.com/mattn/go-zglob v0.0.1 h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microcosm-cc/bluemonday v1.0.1 h1:SIYunPjnlXcW+gVfvm0IlSeR5U3WZUOLfVmqg85Go44= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -206,13 +218,17 @@ github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkp github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0 h1:HtCSf6B4gN/87yc5qTl7WsxPKQIIGXLPPM1bMCPOsoY= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.3.4 h1:Mv9AcnCgU14/cU6Vd0wuRdG1FBO0HzXQLnjBduDLy70= +github.com/segmentio/kafka-go v0.3.4/go.mod h1:OT5KXBPbaJJTcvokhWR2KFmm0niEx3mnccTwjmLvSi4= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -230,23 +246,41 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/tylerb/graceful v1.2.15 h1:B0x01Y8fsJpogzZTkDg6BDi6eMf03s01lEKGdrv83oA= -github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II= github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.5.1 h1:rsqfU5vBkVknbhUGbAUwQKR2H4ItV8tjJ+6kJX4cxHM= +go.uber.org/atomic v1.5.1/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.4.0 h1:f3WCSC2KzAcBXGATIxAB1E2XuCpNU255wNKZ505qi3E= +go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876 h1:sKJQZMuxjOAR/Uo2LBfU90onWEf1dF4C+0hPJCc9Mpc= +golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522 h1:OeRHuibLsmZkFj773W4LcfAGsSxJgfPONhr8cmO+eLA= @@ -256,14 +290,22 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422 h1:QzoH/1pFpZguR8NrRHLcO6jKqfv2zpuSqZLgdm7ZmjI= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519 h1:x6rhz8Y9CjbgQkccRGmELH6K+LJj7tOoh3XWeC1yaQM= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -274,6 +316,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4 h1:99CA0JJbUX4ozCnLon680Jc9e0T1i8HCaLVJMwtI8Hc= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -300,6 +344,9 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -309,6 +356,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -317,8 +365,16 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200107050322-53017a39ae36 h1:+eY+U4SdIdum+uGmzG+Y7oP2YWTOsFRElVIBD6K3Wgo= +golang.org/x/tools v0.0.0-20200107050322-53017a39ae36/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca h1:PupagGYwj8+I4ubCxcmcBRk3VlUWtTg5huQpZR9flmE= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6 h1:4WsZyVtkthqrHTbDCJfiTs8IWNYE4uvsSDgaV6xpp+o= @@ -326,6 +382,8 @@ gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6d google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -347,6 +405,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo= gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs= @@ -358,9 +419,15 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a h1:LJwr7TCTghdatWv40WobzlKXc9c4s8oGa7QKJUtHhWA= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/influx/query_test.go b/influx/query_test.go index ca641bea97..10d2bd050b 100644 --- a/influx/query_test.go +++ b/influx/query_test.go @@ -24,19 +24,19 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_idle", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest_nice", Type: "field", }, - chronograf.Field{ + { Value: "usage_system", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest", Type: "field", }, @@ -55,19 +55,19 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_idle", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest_nice", Type: "field", }, - chronograf.Field{ + { Value: "usage_system", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest", Type: "field", }, @@ -86,7 +86,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ @@ -96,7 +96,7 @@ func TestConvert(t *testing.T) { }, }, }, - chronograf.Field{ + { Value: "median", Type: "func", Args: []chronograf.Field{ @@ -106,7 +106,7 @@ func TestConvert(t *testing.T) { }, }, }, - chronograf.Field{ + { Value: "count", Type: "func", Args: []chronograf.Field{ @@ -116,7 +116,7 @@ func TestConvert(t *testing.T) { }, }, }, - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ @@ -165,12 +165,12 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, }, - Tags: map[string][]string{"host": []string{"myhost"}}, + Tags: map[string][]string{"host": {"myhost"}}, GroupBy: chronograf.GroupBy{ Time: "", Tags: []string{}, @@ -201,12 +201,12 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, }, - Tags: map[string][]string{"host": []string{"myhost"}}, + Tags: map[string][]string{"host": {"myhost"}}, GroupBy: chronograf.GroupBy{ Time: "", Tags: []string{}, @@ -226,7 +226,7 @@ func TestConvert(t *testing.T) { RetentionPolicy: "autogen", Tags: map[string][]string{}, Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, @@ -273,7 +273,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, @@ -293,12 +293,12 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, }, - Tags: map[string][]string{"host": []string{"myhost"}}, + Tags: map[string][]string{"host": {"myhost"}}, GroupBy: chronograf.GroupBy{ Time: "", Tags: []string{}, @@ -318,16 +318,16 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "myhost", }, - "cpu": []string{ + "cpu": { "cpu-total", }, }, @@ -362,14 +362,14 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_user", Type: "field", }, }, Tags: map[string][]string{ - "host": []string{"myhost", "yourhost"}, - "these": []string{"those"}, + "host": {"myhost", "yourhost"}, + "these": {"those"}, }, GroupBy: chronograf.GroupBy{ Time: "", @@ -389,31 +389,31 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_idle", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest_nice", Type: "field", }, - chronograf.Field{ + { Value: "usage_system", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest", Type: "field", }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "dev-052978d6-us-east-2-meta-0", "dev-052978d6-us-east-2-data-5", "dev-052978d6-us-east-2-data-4", "dev-052978d6-us-east-2-data-3", }, - "cpu": []string{ + "cpu": { "cpu-total", "cpu0", }, @@ -436,31 +436,31 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_idle", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest_nice", Type: "field", }, - chronograf.Field{ + { Value: "usage_system", Type: "field", }, - chronograf.Field{ + { Value: "usage_guest", Type: "field", }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "dev-052978d6-us-east-2-meta-0", "dev-052978d6-us-east-2-data-5", "dev-052978d6-us-east-2-data-4", "dev-052978d6-us-east-2-data-3", }, - "cpu": []string{ + "cpu": { "cpu-total", "cpu0", }, @@ -483,7 +483,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ @@ -514,7 +514,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ @@ -545,7 +545,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Alias: "mean_usage_idle", @@ -577,7 +577,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "percentile", Type: "func", Alias: "mean_usage_idle", @@ -586,7 +586,7 @@ func TestConvert(t *testing.T) { Value: "usage_idle", Type: "field", }, - chronograf.Field{ + { Value: "3.14", Type: "number", }, @@ -611,7 +611,7 @@ func TestConvert(t *testing.T) { want: chronograf.QueryConfig{ Measurement: "h2o_feet", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "top", Type: "func", Args: []chronograf.Field{ @@ -619,11 +619,11 @@ func TestConvert(t *testing.T) { Value: "water_level", Type: "field", }, - chronograf.Field{ + { Value: "location", Type: "field", }, - chronograf.Field{ + { Value: "2", Type: "integer", }, @@ -643,7 +643,7 @@ func TestConvert(t *testing.T) { want: chronograf.QueryConfig{ Measurement: "h2o_feet", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "count", Type: "func", Args: []chronograf.Field{ @@ -667,7 +667,7 @@ func TestConvert(t *testing.T) { want: chronograf.QueryConfig{ Measurement: "h2o_feet", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "count", Type: "func", Alias: "count_water", @@ -692,7 +692,7 @@ func TestConvert(t *testing.T) { want: chronograf.QueryConfig{ Measurement: "h2o_feet", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "count", Type: "func", Args: []chronograf.Field{ @@ -718,7 +718,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ @@ -749,7 +749,7 @@ func TestConvert(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Args: []chronograf.Field{ diff --git a/integrations/server_test.go b/integrations/server_test.go deleted file mode 100644 index 31b05cf7ae..0000000000 --- a/integrations/server_test.go +++ /dev/null @@ -1,3180 +0,0 @@ -package integrations - -// This was intentionally added under the integrations package and not the integrations test package -// so that changes in other parts of the code base that may have an effect on these test will not -// compile until they are fixed. - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - - "net/http" - "testing" - "time" - - "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" - "github.com/influxdata/chronograf/log" - "github.com/influxdata/chronograf/oauth2" - "github.com/influxdata/chronograf/roles" - "github.com/influxdata/chronograf/server" -) - -func TestServer(t *testing.T) { - type fields struct { - Organizations []chronograf.Organization - Mappings []chronograf.Mapping - Users []chronograf.User - Sources []chronograf.Source - Servers []chronograf.Server - Layouts []chronograf.Layout - Dashboards []chronograf.Dashboard - Config *chronograf.Config - } - type args struct { - server *server.Server - method string - path string - payload interface{} // Expects this to be a json serializable struct - principal oauth2.Principal - } - type wants struct { - statusCode int - contentType string - body string - } - - tests := []struct { - name string - subName string - fields fields - args args - wants wants - }{ - { - name: "GET /sources/5000/kapacitors/5000", - subName: "Get specific kapacitors; including Canned kapacitors", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - { - Name: "viewer", - Organization: "howdy", // from canned testdata - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/sources/5000/kapacitors/5000", - principal: oauth2.Principal{ - Organization: "howdy", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "id": "5000", - "name": "Kapa 1", - "url": "http://localhost:9092", - "active": true, - "insecureSkipVerify": false, - "links": { - "proxy": "/chronograf/v1/sources/5000/kapacitors/5000/proxy", - "self": "/chronograf/v1/sources/5000/kapacitors/5000", - "rules": "/chronograf/v1/sources/5000/kapacitors/5000/rules", - "tasks": "/chronograf/v1/sources/5000/kapacitors/5000/proxy?path=/kapacitor/v1/tasks", - "ping": "/chronograf/v1/sources/5000/kapacitors/5000/proxy?path=/kapacitor/v1/ping" - } -} -`, - }, - }, - { - name: "GET /sources/5000/kapacitors", - subName: "Get all kapacitors; including Canned kapacitors", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - { - Name: "viewer", - Organization: "howdy", // from canned testdata - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/sources/5000/kapacitors", - principal: oauth2.Principal{ - Organization: "howdy", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "kapacitors": [ - { - "id": "5000", - "name": "Kapa 1", - "url": "http://localhost:9092", - "active": true, - "insecureSkipVerify": false, - "links": { - "proxy": "/chronograf/v1/sources/5000/kapacitors/5000/proxy", - "self": "/chronograf/v1/sources/5000/kapacitors/5000", - "rules": "/chronograf/v1/sources/5000/kapacitors/5000/rules", - "tasks": "/chronograf/v1/sources/5000/kapacitors/5000/proxy?path=/kapacitor/v1/tasks", - "ping": "/chronograf/v1/sources/5000/kapacitors/5000/proxy?path=/kapacitor/v1/ping" - } - } - ] -} -`, - }, - }, - { - name: "GET /organizations", - subName: "Get all organizations; including Canned organization", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations" - }, - "organizations": [ - { - "links": { - "self": "/chronograf/v1/organizations/default" - }, - "id": "default", - "name": "Default", - "defaultRole": "member" - }, - { - "links": { - "self": "/chronograf/v1/organizations/howdy" - }, - "id": "howdy", - "name": "An Organization", - "defaultRole": "viewer" - } - ] -}`, - }, - }, - { - name: "GET /organizations/howdy", - subName: "Get specific organizations; Canned organization", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations/howdy", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/howdy" - }, - "id": "howdy", - "name": "An Organization", - "defaultRole": "viewer" -}`, - }, - }, - { - name: "GET /dashboards/1000", - subName: "Get specific in the howdy organization; Using Canned testdata", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "howdy", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/dashboards/1000", - principal: oauth2.Principal{ - Organization: "howdy", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: `{"id":1000,"cells":[{"i":"8f61c619-dd9b-4761-8aa8-577f27247093","x":0,"y":0,"w":11,"h":5,"name":"Untitled Cell","queries":[{"query":"SELECT mean(\"value\") AS \"mean_value\" FROM \"telegraf\".\"autogen\".\"cpg\" WHERE time \u003e :dashboardTime: GROUP BY time(:interval:) FILL(null)","queryConfig":{"database":"telegraf","measurement":"cpg","retentionPolicy":"autogen","fields":[{"value":"mean","type":"func","alias":"mean_value","args":[{"value":"value","type":"field","alias":""}]}],"tags":{},"groupBy":{"time":"auto","tags":[]},"areTagsAccepted":false,"fill":"null","rawText":null,"range":null,"shifts":null},"source":"/chronograf/v1/sources/2","type":"influxql"}],"axes":{"x":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y2":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"}},"type":"line","colors":[{"id":"0","type":"min","hex":"#00C9FF","name":"laser","value":"0"},{"id":"1","type":"max","hex":"#9394FF","name":"comet","value":"100"}],"legend":{"type":"static","orientation":"bottom"},"tableOptions":{"verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fixFirstColumn":false},"fieldOptions":null,"timeFormat":"","decimalPlaces":{"isEnforced":false,"digits":0},"note":"","noteVisibility":"default","links":{"self":"/chronograf/v1/dashboards/1000/cells/8f61c619-dd9b-4761-8aa8-577f27247093"}}],"templates":[{"tempVar":":dbs:","values":[{"value":"_internal","type":"database","selected":true},{"value":"telegraf","type":"database","selected":false},{"value":"tensorflowdb","type":"database","selected":false},{"value":"pushgateway","type":"database","selected":false},{"value":"node_exporter","type":"database","selected":false},{"value":"mydb","type":"database","selected":false},{"value":"tiny","type":"database","selected":false},{"value":"blah","type":"database","selected":false},{"value":"test","type":"database","selected":false},{"value":"chronograf","type":"database","selected":false},{"value":"db_name","type":"database","selected":false},{"value":"demo","type":"database","selected":false},{"value":"eeg","type":"database","selected":false},{"value":"solaredge","type":"database","selected":false},{"value":"zipkin","type":"database","selected":false}],"id":"e7e498bf-5869-4874-9071-24628a2cda63","type":"databases","label":"","query":{"influxql":"SHOW DATABASES","measurement":"","tagKey":"","fieldKey":""},"links":{"self":"/chronograf/v1/dashboards/1000/templates/e7e498bf-5869-4874-9071-24628a2cda63"}}],"name":"Name This Dashboard","organization":"howdy","links":{"self":"/chronograf/v1/dashboards/1000","cells":"/chronograf/v1/dashboards/1000/cells","templates":"/chronograf/v1/dashboards/1000/templates"}} -`, - }, - }, - { - name: "GET /dashboards", - subName: "Get all dashboards in the howdy organization; Using Canned testdata", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - { - Name: "admin", - Organization: "howdy", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/dashboards", - principal: oauth2.Principal{ - Organization: "howdy", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: `{"dashboards":[{"id":1000,"cells":[{"i":"8f61c619-dd9b-4761-8aa8-577f27247093","x":0,"y":0,"w":11,"h":5,"name":"Untitled Cell","queries":[{"query":"SELECT mean(\"value\") AS \"mean_value\" FROM \"telegraf\".\"autogen\".\"cpg\" WHERE time \u003e :dashboardTime: GROUP BY time(:interval:) FILL(null)","queryConfig":{"database":"telegraf","measurement":"cpg","retentionPolicy":"autogen","fields":[{"value":"mean","type":"func","alias":"mean_value","args":[{"value":"value","type":"field","alias":""}]}],"tags":{},"groupBy":{"time":"auto","tags":[]},"areTagsAccepted":false,"fill":"null","rawText":null,"range":null,"shifts":null},"source":"/chronograf/v1/sources/2","type":"influxql"}],"axes":{"x":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y2":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"}},"type":"line","colors":[{"id":"0","type":"min","hex":"#00C9FF","name":"laser","value":"0"},{"id":"1","type":"max","hex":"#9394FF","name":"comet","value":"100"}],"legend":{"type":"static","orientation":"bottom"},"tableOptions":{"verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fixFirstColumn":false},"fieldOptions":null,"timeFormat":"","decimalPlaces":{"isEnforced":false,"digits":0},"note":"","noteVisibility":"default","links":{"self":"/chronograf/v1/dashboards/1000/cells/8f61c619-dd9b-4761-8aa8-577f27247093"}}],"templates":[{"tempVar":":dbs:","values":[{"value":"_internal","type":"database","selected":true},{"value":"telegraf","type":"database","selected":false},{"value":"tensorflowdb","type":"database","selected":false},{"value":"pushgateway","type":"database","selected":false},{"value":"node_exporter","type":"database","selected":false},{"value":"mydb","type":"database","selected":false},{"value":"tiny","type":"database","selected":false},{"value":"blah","type":"database","selected":false},{"value":"test","type":"database","selected":false},{"value":"chronograf","type":"database","selected":false},{"value":"db_name","type":"database","selected":false},{"value":"demo","type":"database","selected":false},{"value":"eeg","type":"database","selected":false},{"value":"solaredge","type":"database","selected":false},{"value":"zipkin","type":"database","selected":false}],"id":"e7e498bf-5869-4874-9071-24628a2cda63","type":"databases","label":"","query":{"influxql":"SHOW DATABASES","measurement":"","tagKey":"","fieldKey":""},"links":{"self":"/chronograf/v1/dashboards/1000/templates/e7e498bf-5869-4874-9071-24628a2cda63"}}],"name":"Name This Dashboard","organization":"howdy","links":{"self":"/chronograf/v1/dashboards/1000","cells":"/chronograf/v1/dashboards/1000/cells","templates":"/chronograf/v1/dashboards/1000/templates"}}]} -`, - }, - }, - { - name: "GET /users", - subName: "User Not Found in the Default Organization", - fields: fields{ - Users: []chronograf.User{}, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations/default/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 403, - body: `{"code":403,"message":"User is not authorized"}`, - }, - }, - { - name: "GET /users", - subName: "Single User in the Default Organization as SuperAdmin", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations/default/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users" - }, - "users": [ - { - "links": { - "self": "/chronograf/v1/organizations/default/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "default" - } - ] - } - ] -}`, - }, - }, - { - name: "GET /users", - subName: "Two users in two organizations; user making request is as SuperAdmin with out raw query param", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - { - ID: 2, // This is artificial, but should be reflective of the users actual ID - Name: "billietta", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "cool", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations/default/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users" - }, - "users": [ - { - "links": { - "self": "/chronograf/v1/organizations/default/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "default" - } - ] - } - ] -} -`, - }, - }, - { - name: "POST /users", - subName: "User making request is as SuperAdmin with raw query param; being created has wildcard role", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{ - { - Name: "*", - Organization: "default", - }, - }, - }, - method: "POST", - path: "/chronograf/v1/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": false, - "roles": [ - { - "name": "member", - "organization": "default" - } - ] -} -`, - }, - }, - { - name: "POST /users", - subName: "User making request is as SuperAdmin with raw query param; being created has no roles", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{}, - }, - method: "POST", - path: "/chronograf/v1/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": false, - "roles": [] -} -`, - }, - }, - { - name: "GET /users", - subName: "Two users in two organizations; user making request is as SuperAdmin with raw query param", - fields: fields{ - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - { - ID: 2, // This is artificial, but should be reflective of the users actual ID - Name: "billietta", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "1", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/users" - }, - "users": [ - { - "links": { - "self": "/chronograf/v1/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "default" - } - ] - }, - { - "links": { - "self": "/chronograf/v1/users/2" - }, - "id": "2", - "name": "billietta", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "1" - } - ] - } - ] -} -`, - }, - }, - { - name: "GET /users", - subName: "Two users in two organizations; user making request is as not SuperAdmin with raw query param", - fields: fields{ - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - { - ID: 2, // This is artificial, but should be reflective of the users actual ID - Name: "billietta", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - { - Name: "admin", - Organization: "1", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/users", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billieta", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 403, - body: ` -{ - "code": 403, - "message": "User is not authorized" -} -`, - }, - }, - { - name: "POST /users", - subName: "Create a New User with SuperAdmin status; SuperAdminNewUsers is true (the default case); User on Principal is a SuperAdmin", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/organizations/default/users", - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{ - { - Name: roles.EditorRoleName, - Organization: "default", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "editor", - "organization": "default" - } - ] -}`, - }, - }, - { - name: "POST /users", - subName: "Create a New User with SuperAdmin status; SuperAdminNewUsers is false; User on Principal is a SuperAdmin", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/organizations/default/users", - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{ - { - Name: roles.EditorRoleName, - Organization: "default", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": false, - "roles": [ - { - "name": "editor", - "organization": "default" - } - ] -}`, - }, - }, - { - name: "POST /users", - subName: "Create a New User with SuperAdmin status; SuperAdminNewUsers is false; User on Principal is Admin, but not a SuperAdmin", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/organizations/default/users", - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{ - { - Name: roles.EditorRoleName, - Organization: "default", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": false, - "roles": [ - { - "name": "editor", - "organization": "default" - } - ] -}`, - }, - }, - { - name: "POST /users", - subName: "Create a New User with SuperAdmin status; SuperAdminNewUsers is true; User on Principal is Admin, but not a SuperAdmin", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/organizations/default/users", - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: roles.EditorRoleName, - Organization: "default", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 401, - body: ` -{ - "code": 401, - "message": "User does not have authorization required to set SuperAdmin status. See https://github.com/influxdata/chronograf/issues/2601 for more information." -}`, - }, - }, - { - name: "POST /users", - subName: "Create a New User with in multiple organizations; User on Principal is a SuperAdmin with raw query param", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/users", - payload: &chronograf.User{ - Name: "user", - Provider: "provider", - Scheme: "oauth2", - Roles: []chronograf.Role{ - { - Name: roles.EditorRoleName, - Organization: "default", - }, - { - Name: roles.EditorRoleName, - Organization: "1", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/users/2" - }, - "id": "2", - "name": "user", - "provider": "provider", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "editor", - "organization": "default" - }, - { - "name": "editor", - "organization": "1" - } - ] -}`, - }, - }, - { - name: "PATCH /users", - subName: "Update user to have no roles", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PATCH", - path: "/chronograf/v1/users/1", - payload: map[string]interface{}{ - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": []chronograf.Role{}, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - ] -}`, - }, - }, - { - name: "PATCH /users", - subName: "Update user roles with wildcard", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PATCH", - path: "/chronograf/v1/users/1", - payload: &chronograf.User{ - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: roles.AdminRoleName, - Organization: "default", - }, - { - Name: roles.WildcardRoleName, - Organization: "1", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "default" - }, - { - "name": "viewer", - "organization": "1" - } - ] -}`, - }, - }, - { - name: "PATCH /users/1", - subName: "SuperAdmin modifying their own status", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PATCH", - path: "/chronograf/v1/organizations/default/users/1", - payload: map[string]interface{}{ - "id": "1", - "superAdmin": false, - "roles": []interface{}{ - map[string]interface{}{ - "name": "admin", - "organization": "default", - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: http.StatusUnauthorized, - body: ` -{ - "code": 401, - "message": "user cannot modify their own SuperAdmin status" -} -`, - }, - }, - { - name: "GET /organization/default/users", - subName: "Organization not set explicitly on principal", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Organizations: []chronograf.Organization{}, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/organizations/default/users", - principal: oauth2.Principal{ - Organization: "", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/organizations/default/users" - }, - "users": [ - { - "links": { - "self": "/chronograf/v1/organizations/default/users/1" - }, - "id": "1", - "name": "billibob", - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "roles": [ - { - "name": "admin", - "organization": "default" - } - ] - } - ] -} -`, - }, - }, - { - name: "PUT /me", - subName: "Change SuperAdmins current organization to org they dont belong to", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PUT", - path: "/chronograf/v1/me", - payload: map[string]string{ - "organization": "1", - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "id": "1", - "name": "billibob", - "roles": [ - { - "name": "admin", - "organization": "default" - }, - { - "name": "viewer", - "organization": "1" - } - ], - "provider": "github", - "scheme": "oauth2", - "superAdmin": true, - "links": { - "self": "/chronograf/v1/organizations/1/users/1" - }, - "organizations": [ - { - "id": "1", - "name": "Sweet", - "defaultRole": "viewer" - }, - { - "id": "default", - "name": "Default", - "defaultRole": "member" - } - ], - "currentOrganization": { - "id": "1", - "name": "Sweet", - "defaultRole": "viewer" - } -}`, - }, - }, - { - name: "PUT /me", - subName: "Change Admin current organization to org they dont belong to", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PUT", - path: "/chronograf/v1/me", - payload: map[string]string{ - "organization": "1", - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 403, - body: ` - { - "code": 403, - "message": "user not found" -}`, - }, - }, - { - name: "GET /me", - subName: "New user hits me for the first time", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Mappings: []chronograf.Mapping{ - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "influxdata", - }, - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "2", - Organization: "2", - Provider: "github", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "3", - Organization: "3", - Provider: "auth0", - Scheme: "ldap", - ProviderOrganization: "*", - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - { - ID: "2", - Name: "What", - DefaultRole: roles.EditorRoleName, - }, - { - ID: "3", - Name: "Okay", - DefaultRole: roles.AdminRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{}, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/me", - principal: oauth2.Principal{ - Subject: "billietta", - Issuer: "github", - Group: "influxdata,idk,mimi", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "id": "2", - "name": "billietta", - "roles": [ - { - "name": "viewer", - "organization": "1" - }, - { - "name": "editor", - "organization": "2" - }, - { - "name": "member", - "organization": "default" - } - ], - "provider": "github", - "scheme": "oauth2", - "links": { - "self": "/chronograf/v1/organizations/default/users/2" - }, - "organizations": [ - { - "id": "1", - "name": "Sweet", - "defaultRole": "viewer" - }, - { - "id": "2", - "name": "What", - "defaultRole": "editor" - }, - { - "id": "default", - "name": "Default", - "defaultRole": "member" - } - ], - "currentOrganization": { - "id": "default", - "name": "Default", - "defaultRole": "member" - } -} -`, - }, - }, - { - name: "GET /mappings", - subName: "get all mappings", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Mappings: []chronograf.Mapping{ - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "influxdata", - }, - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "2", - Organization: "2", - Provider: "github", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "3", - Organization: "3", - Provider: "auth0", - Scheme: "ldap", - ProviderOrganization: "*", - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - { - ID: "2", - Name: "What", - DefaultRole: roles.EditorRoleName, - }, - { - ID: "3", - Name: "Okay", - DefaultRole: roles.AdminRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/mappings", - principal: oauth2.Principal{ - Subject: "billibob", - Issuer: "github", - Group: "influxdata,idk,mimi", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/mappings" - }, - "mappings": [ - { - "links": { - "self": "/chronograf/v1/mappings/1" - }, - "id": "1", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "influxdata" - }, - { - "links": { - "self": "/chronograf/v1/mappings/2" - }, - "id": "2", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/3" - }, - "id": "3", - "organizationId": "2", - "provider": "github", - "scheme": "*", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/4" - }, - "id": "4", - "organizationId": "3", - "provider": "auth0", - "scheme": "ldap", - "providerOrganization": "*" - }, - { - "links": { - "self": "/chronograf/v1/mappings/default" - }, - "id": "default", - "organizationId": "default", - "provider": "*", - "scheme": "*", - "providerOrganization": "*" - } - ] -} -`, - }, - }, - { - name: "GET /mappings", - subName: "get all mappings - user is not super admin", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Mappings: []chronograf.Mapping{ - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "influxdata", - }, - { - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "2", - Organization: "2", - Provider: "github", - Scheme: "*", - ProviderOrganization: "*", - }, - { - ID: "3", - Organization: "3", - Provider: "auth0", - Scheme: "ldap", - ProviderOrganization: "*", - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - { - ID: "2", - Name: "What", - DefaultRole: roles.EditorRoleName, - }, - { - ID: "3", - Name: "Okay", - DefaultRole: roles.AdminRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/mappings", - principal: oauth2.Principal{ - Subject: "billibob", - Issuer: "github", - Group: "influxdata,idk,mimi", - }, - }, - wants: wants{ - statusCode: 403, - body: ` -{ - "code": 403, - "message": "User is not authorized" -} -`, - }, - }, - { - name: "POST /mappings", - subName: "create new mapping", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Mappings: []chronograf.Mapping{}, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "POST", - path: "/chronograf/v1/mappings", - payload: &chronograf.Mapping{ - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "influxdata", - }, - principal: oauth2.Principal{ - Subject: "billibob", - Issuer: "github", - Group: "influxdata,idk,mimi", - }, - }, - wants: wants{ - statusCode: 201, - body: ` -{ - "links": { - "self": "/chronograf/v1/mappings/1" - }, - "id": "1", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "influxdata" -} -`, - }, - }, - { - name: "PUT /mappings", - subName: "update new mapping", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: false, - }, - }, - Mappings: []chronograf.Mapping{ - chronograf.Mapping{ - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "influxdata", - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "Sweet", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PUT", - path: "/chronograf/v1/mappings/1", - payload: &chronograf.Mapping{ - ID: "1", - Organization: "1", - Provider: "*", - Scheme: "*", - ProviderOrganization: "*", - }, - principal: oauth2.Principal{ - Subject: "billibob", - Issuer: "github", - Group: "influxdata,idk,mimi", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "links": { - "self": "/chronograf/v1/mappings/1" - }, - "id": "1", - "organizationId": "1", - "provider": "*", - "scheme": "*", - "providerOrganization": "*" -} -`, - }, - }, - { - name: "GET /org_config", - subName: "default org", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/org_config", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` - { - "links": { - "self": "\/chronograf\/v1\/org_config", - "logViewer": "\/chronograf\/v1\/org_config\/logviewer" - }, - "organization": "default", - "logViewer": { - "columns": [ - { - "name": "time", - "position": 0, - "encodings": [ - { - "type": "visibility", - "value": "hidden" - } - ] - }, - { - "name": "severity", - "position": 1, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "label", - "value": "icon" - }, - { - "type": "label", - "value": "text" - }, - { - "type": "color", - "value": "ruby", - "name": "emerg" - }, - { - "type": "color", - "value": "fire", - "name": "alert" - }, - { - "type": "color", - "value": "curacao", - "name": "crit" - }, - { - "type": "color", - "value": "tiger", - "name": "err" - }, - { - "type": "color", - "value": "pineapple", - "name": "warning" - }, - { - "type": "color", - "value": "rainforest", - "name": "notice" - }, - { - "type": "color", - "value": "star", - "name": "info" - }, - { - "type": "color", - "value": "wolf", - "name": "debug" - } - ] - }, - { - "name": "timestamp", - "position": 2, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "message", - "position": 3, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "facility", - "position": 4, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "procid", - "position": 5, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "displayName", - "value": "Proc ID" - } - ] - }, - { - "name": "appname", - "position": 6, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "displayName", - "value": "Application" - } - ] - }, - { - "name": "hostname", - "position": 7, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "host", - "position": 8, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - } - ] - } - } - `, - }, - }, - { - name: "GET /org_config/logviewer", - subName: "default org", - fields: fields{ - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/org_config/logviewer", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` - { - "links": { - "self": "\/chronograf\/v1\/org_config/logviewer" - }, - "columns": [ - { - "name": "time", - "position": 0, - "encodings": [ - { - "type": "visibility", - "value": "hidden" - } - ] - }, - { - "name": "severity", - "position": 1, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "label", - "value": "icon" - }, - { - "type": "label", - "value": "text" - }, - { - "type": "color", - "value": "ruby", - "name": "emerg" - }, - { - "type": "color", - "value": "fire", - "name": "alert" - }, - { - "type": "color", - "value": "curacao", - "name": "crit" - }, - { - "type": "color", - "value": "tiger", - "name": "err" - }, - { - "type": "color", - "value": "pineapple", - "name": "warning" - }, - { - "type": "color", - "value": "rainforest", - "name": "notice" - }, - { - "type": "color", - "value": "star", - "name": "info" - }, - { - "type": "color", - "value": "wolf", - "name": "debug" - } - ] - }, - { - "name": "timestamp", - "position": 2, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "message", - "position": 3, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "facility", - "position": 4, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "procid", - "position": 5, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "displayName", - "value": "Proc ID" - } - ] - }, - { - "name": "appname", - "position": 6, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "displayName", - "value": "Application" - } - ] - }, - { - "name": "hostname", - "position": 7, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "host", - "position": 8, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - } - ] - } - `, - }, - }, - { - name: "PUT /org_config/logviewer", - subName: "default org", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "PUT", - path: "/chronograf/v1/org_config/logviewer", - payload: &chronograf.LogViewerConfig{ - Columns: []chronograf.LogViewerColumn{ - { - Name: "time", - Position: 0, - Encodings: []chronograf.ColumnEncoding{ - { - Type: "visibility", - Value: "hidden", - }, - }, - }, - { - Name: "severity", - Position: 1, - Encodings: []chronograf.ColumnEncoding{ - - { - Type: "visibility", - Value: "visible", - }, - { - Type: "label", - Value: "icon", - }, - { - Type: "color", - Name: "emerg", - Value: "ruby", - }, - { - Type: "color", - Name: "alert", - Value: "fire", - }, - { - Type: "color", - Name: "crit", - Value: "curacao", - }, - { - Type: "color", - Name: "err", - Value: "tiger", - }, - { - Type: "color", - Name: "warning", - Value: "pineapple", - }, - { - Type: "color", - Name: "notice", - Value: "wolf", - }, - { - Type: "color", - Name: "info", - Value: "wolf", - }, - { - Type: "color", - Name: "debug", - Value: "wolf", - }, - }, - }, - { - Name: "timestamp", - Position: 3, - Encodings: []chronograf.ColumnEncoding{ - - { - Type: "visibility", - Value: "visible", - }, - }, - }, - { - Name: "message", - Position: 2, - Encodings: []chronograf.ColumnEncoding{ - - { - Type: "visibility", - Value: "visible", - }, - }, - }, - { - Name: "facility", - Position: 4, - Encodings: []chronograf.ColumnEncoding{ - - { - Type: "visibility", - Value: "visible", - }, - }, - }, - { - Name: "procid", - Position: 5, - Encodings: []chronograf.ColumnEncoding{ - - { - Type: "visibility", - Value: "hidden", - }, - { - Type: "displayName", - Value: "ProcID!", - }, - }, - }, - { - Name: "appname", - Position: 6, - Encodings: []chronograf.ColumnEncoding{ - { - Type: "visibility", - Value: "visible", - }, - { - Type: "displayName", - Value: "Application", - }, - }, - }, - { - Name: "host", - Position: 7, - Encodings: []chronograf.ColumnEncoding{ - { - Type: "visibility", - Value: "visible", - }, - }, - }, - }, - }, - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` - { - "links": { - "self": "\/chronograf\/v1\/org_config\/logviewer" - }, - "columns": [ - { - "name": "time", - "position": 0, - "encodings": [ - { - "type": "visibility", - "value": "hidden" - } - ] - }, - { - "name": "severity", - "position": 1, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "label", - "value": "icon" - }, - { - "type": "color", - "value": "ruby", - "name": "emerg" - }, - { - "type": "color", - "value": "fire", - "name": "alert" - }, - { - "type": "color", - "value": "curacao", - "name": "crit" - }, - { - "type": "color", - "value": "tiger", - "name": "err" - }, - { - "type": "color", - "value": "pineapple", - "name": "warning" - }, - { - "type": "color", - "value": "wolf", - "name": "notice" - }, - { - "type": "color", - "value": "wolf", - "name": "info" - }, - { - "type": "color", - "value": "wolf", - "name": "debug" - } - ] - }, - { - "name": "timestamp", - "position": 3, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "message", - "position": 2, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "facility", - "position": 4, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - }, - { - "name": "procid", - "position": 5, - "encodings": [ - { - "type": "visibility", - "value": "hidden" - }, - { - "type": "displayName", - "value": "ProcID!" - } - ] - }, - { - "name": "appname", - "position": 6, - "encodings": [ - { - "type": "visibility", - "value": "visible" - }, - { - "type": "displayName", - "value": "Application" - } - ] - }, - { - "name": "host", - "position": 7, - "encodings": [ - { - "type": "visibility", - "value": "visible" - } - ] - } - ] - } - `, - }, - }, - { - name: "GET /", - subName: "signed into default org", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: true, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/", - principal: oauth2.Principal{ - Organization: "default", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "layouts": "/chronograf/v1/layouts", - "protoboards":"/chronograf/v1/protoboards", - "cells": "/chronograf/v2/cells", - "users": "/chronograf/v1/organizations/default/users", - "allUsers": "/chronograf/v1/users", - "organizations": "/chronograf/v1/organizations", - "mappings": "/chronograf/v1/mappings", - "sources": "/chronograf/v1/sources", - "me": "/chronograf/v1/me", - "environment": "/chronograf/v1/env", - "dashboards": "/chronograf/v1/dashboards", - "dashboardsv2":"/chronograf/v2/dashboards", - "config": { - "self": "/chronograf/v1/config", - "auth": "/chronograf/v1/config/auth" - }, - "auth": [ - { - "name": "github", - "label": "Github", - "login": "/oauth/github/login", - "logout": "/oauth/github/logout", - "callback": "/oauth/github/callback" - } - ], - "logout": "/oauth/logout", - "external": { - "statusFeed": "" - }, - "orgConfig": { - "logViewer": "/chronograf/v1/org_config/logviewer", - "self": "/chronograf/v1/org_config" - }, - "flux": { - "ast": "/chronograf/v1/flux/ast", - "self": "/chronograf/v1/flux", - "suggestions": "/chronograf/v1/flux/suggestions" - }, - "validateTextTemplates":"chronograf/v1/validate_text_templates" -} -`, - }, - }, - { - name: "GET /", - subName: "signed into org 1", - fields: fields{ - Config: &chronograf.Config{ - Auth: chronograf.AuthConfig{ - SuperAdminNewUsers: true, - }, - }, - Organizations: []chronograf.Organization{ - { - ID: "1", - Name: "cool", - DefaultRole: roles.ViewerRoleName, - }, - }, - Users: []chronograf.User{ - { - ID: 1, // This is artificial, but should be reflective of the users actual ID - Name: "billibob", - Provider: "github", - Scheme: "oauth2", - SuperAdmin: false, - Roles: []chronograf.Role{ - { - Name: "admin", - Organization: "default", - }, - { - Name: "member", - Organization: "1", - }, - }, - }, - }, - }, - args: args{ - server: &server.Server{ - GithubClientID: "not empty", - GithubClientSecret: "not empty", - }, - method: "GET", - path: "/chronograf/v1/", - principal: oauth2.Principal{ - Organization: "1", - Subject: "billibob", - Issuer: "github", - }, - }, - wants: wants{ - statusCode: 200, - body: ` -{ - "layouts": "/chronograf/v1/layouts", - "protoboards":"/chronograf/v1/protoboards", - "cells": "/chronograf/v2/cells", - "users": "/chronograf/v1/organizations/1/users", - "allUsers": "/chronograf/v1/users", - "organizations": "/chronograf/v1/organizations", - "mappings": "/chronograf/v1/mappings", - "sources": "/chronograf/v1/sources", - "me": "/chronograf/v1/me", - "environment": "/chronograf/v1/env", - "dashboards": "/chronograf/v1/dashboards", - "dashboardsv2":"/chronograf/v2/dashboards", - "config": { - "self": "/chronograf/v1/config", - "auth": "/chronograf/v1/config/auth" - }, - "orgConfig": { - "logViewer": "/chronograf/v1/org_config/logviewer", - "self": "/chronograf/v1/org_config" - }, - "auth": [ - { - "name": "github", - "label": "Github", - "login": "/oauth/github/login", - "logout": "/oauth/github/logout", - "callback": "/oauth/github/callback" - } - ], - "logout": "/oauth/logout", - "external": { - "statusFeed": "" - }, - "flux": { - "ast": "/chronograf/v1/flux/ast", - "self": "/chronograf/v1/flux", - "suggestions": "/chronograf/v1/flux/suggestions" - }, - "validateTextTemplates":"chronograf/v1/validate_text_templates" -} -`, - }, - }, - } - - for _, tt := range tests { - testName := fmt.Sprintf("%s: %s", tt.name, tt.subName) - t.Run(testName, func(t *testing.T) { - ctx := context.TODO() - // Create Test Server - host, port := hostAndPort() - tt.args.server.Host = host - tt.args.server.Port = port - - // Use testdata directory for the canned data - tt.args.server.CannedPath = "testdata" - tt.args.server.ResourcesPath = "testdata" - - // This is so that we can use staticly generate jwts - tt.args.server.TokenSecret = "secret" - - // Endpoint for validating RSA256 signatures when using id_token parsing for ADFS - tt.args.server.JwksURL = "" - - boltFile := newBoltFile() - tt.args.server.BoltPath = boltFile - - // Prepopulate BoltDB Database for Server - boltdb := bolt.NewClient() - boltdb.Path = boltFile - - logger := log.New(log.ParseLevel("debug")) - build := chronograf.BuildInfo{ - Version: "pre-1.4.0.0", - Commit: "", - } - _ = boltdb.Open(ctx, logger, build) - - if tt.fields.Config != nil { - if err := boltdb.ConfigStore.Update(ctx, tt.fields.Config); err != nil { - t.Fatalf("failed to update global application config %v", err) - return - } - } - - // Populate Organizations - for i, mapping := range tt.fields.Mappings { - o, err := boltdb.MappingsStore.Add(ctx, &mapping) - if err != nil { - t.Fatalf("failed to add mapping: %v", err) - return - } - tt.fields.Mappings[i] = *o - } - - // Populate Organizations - for i, organization := range tt.fields.Organizations { - o, err := boltdb.OrganizationsStore.Add(ctx, &organization) - if err != nil { - t.Fatalf("failed to add organization: %v", err) - return - } - tt.fields.Organizations[i] = *o - } - - // Populate Users - for i, user := range tt.fields.Users { - u, err := boltdb.UsersStore.Add(ctx, &user) - if err != nil { - t.Fatalf("failed to add user: %v", err) - return - } - tt.fields.Users[i] = *u - } - - // Populate Sources - for i, source := range tt.fields.Sources { - s, err := boltdb.SourcesStore.Add(ctx, source) - if err != nil { - t.Fatalf("failed to add source: %v", err) - return - } - tt.fields.Sources[i] = s - } - - // Populate Servers - for i, server := range tt.fields.Servers { - s, err := boltdb.ServersStore.Add(ctx, server) - if err != nil { - t.Fatalf("failed to add server: %v", err) - return - } - tt.fields.Servers[i] = s - } - - // Populate Layouts - for i, layout := range tt.fields.Layouts { - l, err := boltdb.LayoutsStore.Add(ctx, layout) - if err != nil { - t.Fatalf("failed to add layout: %v", err) - return - } - tt.fields.Layouts[i] = l - } - - // Populate Dashboards - for i, dashboard := range tt.fields.Dashboards { - d, err := boltdb.DashboardsStore.Add(ctx, dashboard) - if err != nil { - t.Fatalf("failed to add dashboard: %v", err) - return - } - tt.fields.Dashboards[i] = d - } - - _ = boltdb.Close() - - go tt.args.server.Serve(ctx) - serverURL := fmt.Sprintf("http://%v:%v%v", host, port, tt.args.path) - - // Wait for the server to come online - timeout := time.Now().Add(10 * time.Second) - for { - _, err := http.Get(serverURL + "/swagger.json") - if err == nil { - break - } - if time.Now().After(timeout) { - t.Log("failed to start server") - return - } - } - - // Set the Expiry time on the principal - tt.args.principal.IssuedAt = time.Now() - tt.args.principal.ExpiresAt = time.Now().Add(10 * time.Second) - - // Construct HTTP Request - buf, _ := json.Marshal(tt.args.payload) - reqBody := ioutil.NopCloser(bytes.NewReader(buf)) - req, _ := http.NewRequest(tt.args.method, serverURL, reqBody) - token, _ := oauth2.NewJWT(tt.args.server.TokenSecret, tt.args.server.JwksURL).Create(ctx, tt.args.principal) - req.AddCookie(&http.Cookie{ - Name: "session", - Value: string(token), - HttpOnly: true, - Path: "/", - }) - - // Make actual http request - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("failed to make httprequest: %v", err) - return - } - - content := resp.Header.Get("Content-Type") - body, _ := ioutil.ReadAll(resp.Body) - - if resp.StatusCode != tt.wants.statusCode { - t.Errorf( - "%s %s Status Code = %v, want %v", - tt.args.method, - tt.args.path, - resp.StatusCode, - tt.wants.statusCode, - ) - } - - if tt.wants.contentType != "" && content != tt.wants.contentType { - t.Errorf( - "%s %s Content Type = %v, want %v", - tt.args.method, - tt.args.path, - content, - tt.wants.contentType, - ) - } - - if eq, err := jsonEqual(tt.wants.body, string(body)); err != nil || !eq { - t.Errorf( - "%s %s Body = %v, want %v", - tt.args.method, - tt.args.path, - string(body), - tt.wants.body, - ) - } - - tt.args.server.Listener.Close() - }) - } -} diff --git a/integrations/testdata/example.kap b/integrations/testdata/example.kap deleted file mode 100644 index 611216d081..0000000000 --- a/integrations/testdata/example.kap +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "5000", - "srcID": "5000", - "name": "Kapa 1", - "url": "http://localhost:9092", - "active": true, - "organization": "howdy" -} diff --git a/integrations/testdata/example.org b/integrations/testdata/example.org deleted file mode 100644 index 21031e50b1..0000000000 --- a/integrations/testdata/example.org +++ /dev/null @@ -1,5 +0,0 @@ -{ - "id": "howdy", - "name": "An Organization", - "defaultRole": "viewer" -} diff --git a/integrations/testdata/example.src b/integrations/testdata/example.src deleted file mode 100644 index 2e92c7fc65..0000000000 --- a/integrations/testdata/example.src +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "5000", - "name": "Influx 1", - "username": "user1", - "password": "pass1", - "url": "http://localhost:8086", - "metaUrl": "http://metaurl.com", - "type": "influx-enterprise", - "insecureSkipVerify": false, - "default": true, - "telegraf": "telegraf", - "sharedSecret": "cubeapples", - "organization": "howdy" -} diff --git a/integrations/testdata/mydash.dashboard b/integrations/testdata/mydash.dashboard deleted file mode 100644 index 3e81b46dce..0000000000 --- a/integrations/testdata/mydash.dashboard +++ /dev/null @@ -1,189 +0,0 @@ -{ - "id": 1000, - "cells": [ - { - "i": "8f61c619-dd9b-4761-8aa8-577f27247093", - "x": 0, - "y": 0, - "w": 11, - "h": 5, - "name": "Untitled Cell", - "queries": [ - { - "query": "SELECT mean(\"value\") AS \"mean_value\" FROM \"telegraf\".\"autogen\".\"cpg\" WHERE time \u003e :dashboardTime: GROUP BY time(:interval:) FILL(null)", - "queryConfig": { - "id": "b20baa61-bacb-4a17-b27d-b904a0d18114", - "database": "telegraf", - "measurement": "cpg", - "retentionPolicy": "autogen", - "fields": [ - { - "value": "mean", - "type": "func", - "alias": "mean_value", - "args": [ - { - "value": "value", - "type": "field", - "alias": "" - } - ] - } - ], - "tags": {}, - "groupBy": { - "time": "auto", - "tags": [] - }, - "areTagsAccepted": true, - "fill": "null", - "rawText": null, - "range": null, - "shifts": [] - }, - "source": "/chronograf/v1/sources/2" - } - ], - "axes": { - "x": { - "bounds": [], - "label": "", - "prefix": "", - "suffix": "", - "base": "10", - "scale": "linear" - }, - "y": { - "bounds": [], - "label": "", - "prefix": "", - "suffix": "", - "base": "10", - "scale": "linear" - }, - "y2": { - "bounds": [], - "label": "", - "prefix": "", - "suffix": "", - "base": "10", - "scale": "linear" - } - }, - "type": "line", - "colors": [ - { - "id": "0", - "type": "min", - "hex": "#00C9FF", - "name": "laser", - "value": "0" - }, - { - "id": "1", - "type": "max", - "hex": "#9394FF", - "name": "comet", - "value": "100" - } - ], - "legend": { - "type": "static", - "orientation": "bottom" - } - } - ], - "templates": [ - { - "tempVar": ":dbs:", - "values": [ - { - "value": "_internal", - "type": "database", - "selected": true - }, - { - "value": "telegraf", - "type": "database", - "selected": false - }, - { - "value": "tensorflowdb", - "type": "database", - "selected": false - }, - { - "value": "pushgateway", - "type": "database", - "selected": false - }, - { - "value": "node_exporter", - "type": "database", - "selected": false - }, - { - "value": "mydb", - "type": "database", - "selected": false - }, - { - "value": "tiny", - "type": "database", - "selected": false - }, - { - "value": "blah", - "type": "database", - "selected": false - }, - { - "value": "test", - "type": "database", - "selected": false - }, - { - "value": "chronograf", - "type": "database", - "selected": false - }, - { - "value": "db_name", - "type": "database", - "selected": false - }, - { - "value": "demo", - "type": "database", - "selected": false - }, - { - "value": "eeg", - "type": "database", - "selected": false - }, - { - "value": "solaredge", - "type": "database", - "selected": false - }, - { - "value": "zipkin", - "type": "database", - "selected": false - } - ], - "id": "e7e498bf-5869-4874-9071-24628a2cda63", - "type": "databases", - "label": "", - "query": { - "influxql": "SHOW DATABASES", - "measurement": "", - "tagKey": "", - "fieldKey": "" - } - } - ], - "name": "Name This Dashboard", - "organization": "howdy" - } diff --git a/integrations/utils.go b/integrations/utils.go deleted file mode 100644 index 2069c09595..0000000000 --- a/integrations/utils.go +++ /dev/null @@ -1,54 +0,0 @@ -package integrations - -import ( - "encoding/json" - "io/ioutil" - "net/http/httptest" - "net/url" - "strconv" - "strings" - - "github.com/google/go-cmp/cmp" -) - -func hostAndPort() (string, int) { - s := httptest.NewServer(nil) - defer s.Close() - - u, err := url.Parse(s.URL) - if err != nil { - panic(err) - } - xs := strings.Split(u.Host, ":") - host := xs[0] - portStr := xs[1] - port, err := strconv.Atoi(portStr) - if err != nil { - panic(err) - } - return host, port - -} - -func newBoltFile() string { - f, err := ioutil.TempFile("", "chronograf-bolt-") - if err != nil { - panic(err) - } - f.Close() - - return f.Name() -} - -func jsonEqual(s1, s2 string) (eq bool, err error) { - var o1, o2 interface{} - - if err = json.Unmarshal([]byte(s1), &o1); err != nil { - return - } - if err = json.Unmarshal([]byte(s2), &o2); err != nil { - return - } - - return cmp.Equal(o1, o2), nil -} diff --git a/kapacitor/ast.go b/kapacitor/ast.go index b72e901952..8fe5b8c42a 100644 --- a/kapacitor/ast.go +++ b/kapacitor/ast.go @@ -88,6 +88,8 @@ type WhereFilter struct { Operator string // Operator is == or != } +var re = regexp.MustCompile(`(?U)"(.*)"\s+(==|!=)\s+'(.*)'`) + func varWhereFilter(vars map[string]tick.Var) (WhereFilter, bool) { // All chronograf TICKScripts have whereFilters. v, ok := vars["whereFilter"] @@ -112,7 +114,6 @@ func varWhereFilter(vars map[string]tick.Var) (WhereFilter, bool) { opSet := map[string]struct{}{} // All ops must be the same b/c queryConfig // Otherwise the lambda function will be several "tag" op 'value' expressions. - var re = regexp.MustCompile(`(?U)"(.*)"\s+(==|!=)\s+'(.*)'`) for _, match := range re.FindAllStringSubmatch(lambda, -1) { tag, op, value := match[1], match[2], match[3] opSet[op] = struct{}{} @@ -281,11 +282,15 @@ type FieldFunc struct { Func string } +var ( + effRe1 = regexp.MustCompile(`(?Um)\|(\w+)\('(.*)'\)\s*\.as\('value'\)`) + effRe2 = regexp.MustCompile(`(?Um)\|eval\(lambda: "(.*)"\)\s*\.as\('value'\)`) +) + func extractFieldFunc(script chronograf.TICKScript) FieldFunc { // If the TICKScript is relative or threshold alert with an aggregate // then the aggregate function and field is in the form |func('field').as('value') - var re = regexp.MustCompile(`(?Um)\|(\w+)\('(.*)'\)\s*\.as\('value'\)`) - for _, match := range re.FindAllStringSubmatch(string(script), -1) { + for _, match := range effRe1.FindAllStringSubmatch(string(script), -1) { fn, field := match[1], match[2] return FieldFunc{ Field: field, @@ -295,8 +300,7 @@ func extractFieldFunc(script chronograf.TICKScript) FieldFunc { // If the alert does not have an aggregate then the the value function will // be this form: |eval(lambda: "%s").as('value') - re = regexp.MustCompile(`(?Um)\|eval\(lambda: "(.*)"\)\s*\.as\('value'\)`) - for _, match := range re.FindAllStringSubmatch(string(script), -1) { + for _, match := range effRe2.FindAllStringSubmatch(string(script), -1) { field := match[1] return FieldFunc{ Field: field, @@ -311,11 +315,15 @@ type CritCondition struct { Operators []string } +var ( + ecRe1 = regexp.MustCompile(`(?Um)\.crit\(lambda:\s+"value"\s+(.*)\s+crit\)`) + ecRe2 = regexp.MustCompile(`(?Um)\.crit\(lambda:\s+"value"\s+(.*)\s+lower\s+(.*)\s+"value"\s+(.*)\s+upper\)`) +) + func extractCrit(script chronograf.TICKScript) CritCondition { // Threshold and relative alerts have the form .crit(lambda: "value" op crit) // Threshold range alerts have the form .crit(lambda: "value" op lower op "value" op upper) - var re = regexp.MustCompile(`(?Um)\.crit\(lambda:\s+"value"\s+(.*)\s+crit\)`) - for _, match := range re.FindAllStringSubmatch(string(script), -1) { + for _, match := range ecRe1.FindAllStringSubmatch(string(script), -1) { op := match[1] return CritCondition{ Operators: []string{ @@ -323,8 +331,8 @@ func extractCrit(script chronograf.TICKScript) CritCondition { }, } } - re = regexp.MustCompile(`(?Um)\.crit\(lambda:\s+"value"\s+(.*)\s+lower\s+(.*)\s+"value"\s+(.*)\s+upper\)`) - for _, match := range re.FindAllStringSubmatch(string(script), -1) { + + for _, match := range ecRe2.FindAllStringSubmatch(string(script), -1) { lower, compound, upper := match[1], match[2], match[3] return CritCondition{ Operators: []string{ diff --git a/kapacitor/ast_test.go b/kapacitor/ast_test.go index e7815ddc8d..178b2b67fb 100644 --- a/kapacitor/ast_test.go +++ b/kapacitor/ast_test.go @@ -122,10 +122,10 @@ func TestReverse(t *testing.T) { Tags: []string{"host", "cluster_id"}, }, Tags: map[string][]string{ - "cpu": []string{ + "cpu": { "cpu_total", }, - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, @@ -231,8 +231,8 @@ func TestReverse(t *testing.T) { }, }, Tags: map[string][]string{ - "cpu": []string{"cpu_total"}, - "host": []string{"acc-0eabc309-eu-west-1-data-3", "prod"}, + "cpu": {"cpu_total"}, + "host": {"acc-0eabc309-eu-west-1-data-3", "prod"}, }, GroupBy: chronograf.GroupBy{ Time: "10m0s", @@ -629,11 +629,11 @@ func TestReverse(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -766,11 +766,11 @@ func TestReverse(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -903,11 +903,11 @@ func TestReverse(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1022,11 +1022,11 @@ func TestReverse(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1169,11 +1169,11 @@ trigger }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1317,11 +1317,11 @@ trigger }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1431,11 +1431,11 @@ trigger Measurement: "cpu", RetentionPolicy: "autogen", Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, diff --git a/kapacitor/client_test.go b/kapacitor/client_test.go index 8938f37a9b..278bdb347b 100644 --- a/kapacitor/client_test.go +++ b/kapacitor/client_test.go @@ -117,13 +117,13 @@ func TestClient_All(t *testing.T) { }, listTasksOptions: &client.ListTasksOptions{}, resTasks: []client.Task{ - client.Task{ + { ID: "howdy", Status: client.Enabled, }, }, want: map[string]*Task{ - "howdy": &Task{ + "howdy": { ID: "howdy", HrefOutput: "/kapacitor/v1/tasks/howdy/output", @@ -148,7 +148,7 @@ func TestClient_All(t *testing.T) { }, listTasksOptions: &client.ListTasksOptions{}, resTasks: []client.Task{ - client.Task{ + { ID: "rule 1", Status: client.Enabled, Type: client.StreamTask, @@ -231,7 +231,7 @@ trigger }, }, want: map[string]*Task{ - "rule 1": &Task{ + "rule 1": { ID: "rule 1", HrefOutput: "/kapacitor/v1/tasks/rule 1/output", diff --git a/kapacitor/tickscripts_test.go b/kapacitor/tickscripts_test.go index 6f7a7d5053..d6272949d7 100644 --- a/kapacitor/tickscripts_test.go +++ b/kapacitor/tickscripts_test.go @@ -42,11 +42,11 @@ func TestGenerate(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -97,11 +97,11 @@ func TestThreshold(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -550,11 +550,11 @@ func TestThresholdDetail(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -710,11 +710,11 @@ func TestThresholdInsideRange(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -869,11 +869,11 @@ func TestThresholdOutsideRange(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1021,11 +1021,11 @@ func TestThresholdNoAggregate(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1171,11 +1171,11 @@ func TestRelative(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1341,11 +1341,11 @@ func TestRelativeChange(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, @@ -1508,11 +1508,11 @@ func TestDeadman(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "acc-0eabc309-eu-west-1-data-3", "prod", }, - "cpu": []string{ + "cpu": { "cpu_total", }, }, diff --git a/bolt/base.go b/kv/bolt/base.go similarity index 100% rename from bolt/base.go rename to kv/bolt/base.go diff --git a/bolt/bolt_test.go b/kv/bolt/bolt_test.go similarity index 95% rename from bolt/bolt_test.go rename to kv/bolt/bolt_test.go index a9e35b6c80..7c7a57a536 100644 --- a/bolt/bolt_test.go +++ b/kv/bolt/bolt_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" + "github.com/influxdata/chronograf/kv/bolt" "github.com/influxdata/chronograf/mocks" ) diff --git a/bolt/build.go b/kv/bolt/build.go similarity index 97% rename from bolt/build.go rename to kv/bolt/build.go index f137992c82..9af9f8da4e 100644 --- a/bolt/build.go +++ b/kv/bolt/build.go @@ -5,7 +5,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure BuildStore struct implements chronograf.BuildStore interface diff --git a/bolt/build_test.go b/kv/bolt/build_test.go similarity index 100% rename from bolt/build_test.go rename to kv/bolt/build_test.go diff --git a/bolt/cell.go b/kv/bolt/cell.go similarity index 100% rename from bolt/cell.go rename to kv/bolt/cell.go diff --git a/bolt/change_interval_to_duration.go b/kv/bolt/change_interval_to_duration.go similarity index 100% rename from bolt/change_interval_to_duration.go rename to kv/bolt/change_interval_to_duration.go diff --git a/bolt/client.go b/kv/bolt/client.go similarity index 100% rename from bolt/client.go rename to kv/bolt/client.go diff --git a/bolt/config.go b/kv/bolt/config.go similarity index 96% rename from bolt/config.go rename to kv/bolt/config.go index 432b964b5b..78ff74ee57 100644 --- a/bolt/config.go +++ b/kv/bolt/config.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure ConfigStore implements chronograf.ConfigStore. diff --git a/bolt/config_test.go b/kv/bolt/config_test.go similarity index 100% rename from bolt/config_test.go rename to kv/bolt/config_test.go diff --git a/bolt/dashboards.go b/kv/bolt/dashboards.go similarity index 98% rename from bolt/dashboards.go rename to kv/bolt/dashboards.go index c3035ee1b6..243b96a289 100644 --- a/bolt/dashboards.go +++ b/kv/bolt/dashboards.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure DashboardsStore implements chronograf.DashboardsStore. diff --git a/bolt/dashboards_test.go b/kv/bolt/dashboards_test.go similarity index 100% rename from bolt/dashboards_test.go rename to kv/bolt/dashboards_test.go diff --git a/bolt/dashboardsv2.go b/kv/bolt/dashboardsv2.go similarity index 100% rename from bolt/dashboardsv2.go rename to kv/bolt/dashboardsv2.go diff --git a/bolt/internal/internal.go b/kv/bolt/internal/internal.go similarity index 100% rename from bolt/internal/internal.go rename to kv/bolt/internal/internal.go diff --git a/bolt/internal/internal.pb.go b/kv/bolt/internal/internal.pb.go similarity index 100% rename from bolt/internal/internal.pb.go rename to kv/bolt/internal/internal.pb.go diff --git a/bolt/internal/internal.proto b/kv/bolt/internal/internal.proto similarity index 100% rename from bolt/internal/internal.proto rename to kv/bolt/internal/internal.proto diff --git a/bolt/internal/internal_test.go b/kv/bolt/internal/internal_test.go similarity index 98% rename from bolt/internal/internal_test.go rename to kv/bolt/internal/internal_test.go index 7373e77323..91bedec96c 100644 --- a/bolt/internal/internal_test.go +++ b/kv/bolt/internal/internal_test.go @@ -6,7 +6,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) func TestMarshalSource(t *testing.T) { @@ -110,7 +110,7 @@ func TestMarshalLayout(t *testing.T) { Type: "line", Name: "cell1", Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { Bounds: []string{"0", "100"}, Label: "foo", }, @@ -169,7 +169,7 @@ func Test_MarshalDashboard(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { Bounds: []string{"0", "3", "1-7", "foo"}, Label: "foo", Prefix: "M", @@ -237,7 +237,7 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { LegacyBounds: [2]int64{0, 5}, }, }, @@ -293,7 +293,7 @@ func Test_MarshalDashboard_WithLegacyBounds(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { Base: "10", Scale: "linear", }, @@ -361,7 +361,7 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { LegacyBounds: [2]int64{}, }, }, @@ -413,7 +413,7 @@ func Test_MarshalDashboard_WithEmptyLegacyBounds(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "y": chronograf.Axis{ + "y": { Base: "10", Scale: "linear", }, diff --git a/bolt/layouts.go b/kv/bolt/layouts.go similarity index 98% rename from bolt/layouts.go rename to kv/bolt/layouts.go index 0f11ecef22..15761f5158 100644 --- a/bolt/layouts.go +++ b/kv/bolt/layouts.go @@ -5,7 +5,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure LayoutsStore implements chronograf.LayoutsStore. diff --git a/bolt/mapping.go b/kv/bolt/mapping.go similarity index 98% rename from bolt/mapping.go rename to kv/bolt/mapping.go index 52e643dfc2..52e5d8cc00 100644 --- a/bolt/mapping.go +++ b/kv/bolt/mapping.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure MappingsStore implements chronograf.MappingsStore. diff --git a/bolt/mapping_test.go b/kv/bolt/mapping_test.go similarity index 96% rename from bolt/mapping_test.go rename to kv/bolt/mapping_test.go index 745f5df902..25ad57f920 100644 --- a/bolt/mapping_test.go +++ b/kv/bolt/mapping_test.go @@ -127,7 +127,7 @@ func TestMappingStore_All(t *testing.T) { name: "simple", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", @@ -137,13 +137,13 @@ func TestMappingStore_All(t *testing.T) { }, wants: wants{ mappings: []chronograf.Mapping{ - chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", ProviderOrganization: "*", }, - chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", @@ -205,13 +205,13 @@ func TestMappingStore_Delete(t *testing.T) { name: "simple", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", ProviderOrganization: "*", }, - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", @@ -236,13 +236,13 @@ func TestMappingStore_Delete(t *testing.T) { name: "mapping not found", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", ProviderOrganization: "*", }, - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", @@ -312,13 +312,13 @@ func TestMappingStore_Get(t *testing.T) { name: "simple", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", ProviderOrganization: "*", }, - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", @@ -344,13 +344,13 @@ func TestMappingStore_Get(t *testing.T) { name: "mapping not found", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", ProviderOrganization: "*", }, - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", @@ -417,13 +417,13 @@ func TestMappingStore_Update(t *testing.T) { name: "simple", fields: fields{ mappings: []*chronograf.Mapping{ - &chronograf.Mapping{ + { Organization: "default", Provider: "*", Scheme: "*", ProviderOrganization: "*", }, - &chronograf.Mapping{ + { Organization: "0", Provider: "google", Scheme: "ldap", diff --git a/bolt/org_config.go b/kv/bolt/org_config.go similarity index 99% rename from bolt/org_config.go rename to kv/bolt/org_config.go index 76e8a1494b..cc40f14606 100644 --- a/bolt/org_config.go +++ b/kv/bolt/org_config.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure OrganizationConfigStore implements chronograf.OrganizationConfigStore. diff --git a/bolt/org_config_test.go b/kv/bolt/org_config_test.go similarity index 100% rename from bolt/org_config_test.go rename to kv/bolt/org_config_test.go diff --git a/bolt/organizations.go b/kv/bolt/organizations.go similarity index 99% rename from bolt/organizations.go rename to kv/bolt/organizations.go index 458fefafee..a2935a6d54 100644 --- a/bolt/organizations.go +++ b/kv/bolt/organizations.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" "github.com/influxdata/chronograf/organizations" ) diff --git a/bolt/organizations_test.go b/kv/bolt/organizations_test.go similarity index 99% rename from bolt/organizations_test.go rename to kv/bolt/organizations_test.go index c6f5cfe66a..5d3c8ce1bb 100644 --- a/bolt/organizations_test.go +++ b/kv/bolt/organizations_test.go @@ -7,7 +7,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" + "github.com/influxdata/chronograf/kv/bolt" "github.com/influxdata/chronograf/roles" ) diff --git a/bolt/servers.go b/kv/bolt/servers.go similarity index 98% rename from bolt/servers.go rename to kv/bolt/servers.go index 46ea4504b0..df5f32a388 100644 --- a/bolt/servers.go +++ b/kv/bolt/servers.go @@ -5,7 +5,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure ServersStore implements chronograf.ServersStore. diff --git a/bolt/servers_test.go b/kv/bolt/servers_test.go similarity index 98% rename from bolt/servers_test.go rename to kv/bolt/servers_test.go index 312b1b5261..620515e842 100644 --- a/bolt/servers_test.go +++ b/kv/bolt/servers_test.go @@ -19,7 +19,7 @@ func TestServerStore(t *testing.T) { s := c.ServersStore srcs := []chronograf.Server{ - chronograf.Server{ + { Name: "Of Truth", SrcID: 10, Username: "marty", @@ -29,7 +29,7 @@ func TestServerStore(t *testing.T) { Organization: "133", InsecureSkipVerify: true, }, - chronograf.Server{ + { Name: "HipToBeSquare", SrcID: 12, Username: "calvinklein", diff --git a/bolt/sources.go b/kv/bolt/sources.go similarity index 99% rename from bolt/sources.go rename to kv/bolt/sources.go index 8656a1b7bd..50af2090ea 100644 --- a/bolt/sources.go +++ b/kv/bolt/sources.go @@ -5,7 +5,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" "github.com/influxdata/chronograf/roles" ) diff --git a/bolt/sources_test.go b/kv/bolt/sources_test.go similarity index 98% rename from bolt/sources_test.go rename to kv/bolt/sources_test.go index f619cd75fa..f8a905e7d5 100644 --- a/bolt/sources_test.go +++ b/kv/bolt/sources_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" + "github.com/influxdata/chronograf/kv/bolt" ) // Ensure an SourceStore can store, retrieve, update, and delete sources. @@ -20,7 +20,7 @@ func TestSourceStore(t *testing.T) { s := c.SourcesStore srcs := []chronograf.Source{ - chronograf.Source{ + { Name: "Of Truth", Type: "influx", Username: "marty", @@ -30,7 +30,7 @@ func TestSourceStore(t *testing.T) { Organization: "1337", DefaultRP: "pineapple", }, - chronograf.Source{ + { Name: "HipToBeSquare", Type: "influx", Username: "calvinklein", @@ -39,7 +39,7 @@ func TestSourceStore(t *testing.T) { Default: true, Organization: "1337", }, - chronograf.Source{ + { Name: "HipToBeSquare", Type: "influx", Username: "calvinklein", diff --git a/bolt/users.go b/kv/bolt/users.go similarity index 98% rename from bolt/users.go rename to kv/bolt/users.go index d0658f8977..6110b720e0 100644 --- a/bolt/users.go +++ b/kv/bolt/users.go @@ -6,7 +6,7 @@ import ( "github.com/boltdb/bolt" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt/internal" + "github.com/influxdata/chronograf/kv/bolt/internal" ) // Ensure UsersStore implements chronograf.UsersStore. diff --git a/bolt/users_test.go b/kv/bolt/users_test.go similarity index 100% rename from bolt/users_test.go rename to kv/bolt/users_test.go diff --git a/bolt/util.go b/kv/bolt/util.go similarity index 100% rename from bolt/util.go rename to kv/bolt/util.go diff --git a/kv/kv.go b/kv/kv.go new file mode 100644 index 0000000000..b600bdeacc --- /dev/null +++ b/kv/kv.go @@ -0,0 +1,2 @@ +// Package kv provides the interface for chronograf backends. +package kv diff --git a/log/log.go b/log/log.go index 1b00e33326..55e1b1933a 100644 --- a/log/log.go +++ b/log/log.go @@ -4,7 +4,7 @@ import ( "io" "os" - "github.com/Sirupsen/logrus" + "github.com/sirupsen/logrus" "github.com/influxdata/chronograf" ) diff --git a/mocks/cells.go b/mocks/cells.go index ab27bcbc6c..de516a62e4 100644 --- a/mocks/cells.go +++ b/mocks/cells.go @@ -3,7 +3,7 @@ package mocks import ( "context" - "github.com/influxdata/chronograf/v2" + platform "github.com/influxdata/chronograf/v2" ) var _ platform.CellService = &CellService{} diff --git a/oauth2/mux_test.go b/oauth2/mux_test.go index 446bc5c5bf..9da9e7d323 100644 --- a/oauth2/mux_test.go +++ b/oauth2/mux_test.go @@ -85,7 +85,7 @@ func Test_AuthMux_Logout_DeletesSessionCookie(t *testing.T) { tsURL, _ := url.Parse(ts.URL) hc.Jar.SetCookies(tsURL, []*http.Cookie{ - &http.Cookie{ + { Name: DefaultCookieName, Value: "", }, diff --git a/organizations/users_test.go b/organizations/users_test.go index 4f350adea8..779c33083b 100644 --- a/organizations/users_test.go +++ b/organizations/users_test.go @@ -496,7 +496,7 @@ func TestUsersStore_Add(t *testing.T) { Provider: "github", Scheme: "oauth2", Roles: []chronograf.Role{ - chronograf.Role{}, + {}, }, }, orgID: "1337", diff --git a/server/cells_test.go b/server/cells_test.go index 086b45a88a..a6e282dcc8 100644 --- a/server/cells_test.go +++ b/server/cells_test.go @@ -30,13 +30,13 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "correct axes", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"0", "100"}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"0", "100"}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"0", "100"}, }, }, @@ -46,10 +46,10 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "invalid axes present", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "axis of evil": chronograf.Axis{ + "axis of evil": { Bounds: []string{"666", "666"}, }, - "axis of awesome": chronograf.Axis{ + "axis of awesome": { Bounds: []string{"1337", "31337"}, }, }, @@ -60,7 +60,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "linear scale value", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Scale: "linear", Bounds: []string{"0", "100"}, }, @@ -71,7 +71,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "log scale value", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Scale: "log", Bounds: []string{"0", "100"}, }, @@ -82,7 +82,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "invalid scale value", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Scale: "potatoes", Bounds: []string{"0", "100"}, }, @@ -94,7 +94,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "base 10 axis", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Base: "10", Bounds: []string{"0", "100"}, }, @@ -105,7 +105,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "base 2 axis", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Base: "2", Bounds: []string{"0", "100"}, }, @@ -116,7 +116,7 @@ func Test_Cells_CorrectAxis(t *testing.T) { name: "invalid base", cell: &chronograf.DashboardCell{ Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Base: "all your base are belong to us", Bounds: []string{"0", "100"}, }, @@ -192,13 +192,13 @@ func Test_Service_DashboardCells(t *testing.T) { Queries: []chronograf.DashboardQuery{}, CellColors: []chronograf.CellColor{}, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, @@ -705,7 +705,7 @@ func Test_newCellResponses(t *testing.T) { name: "all fields set", dID: chronograf.DashboardID(1), dcells: []chronograf.DashboardCell{ - chronograf.DashboardCell{ + { ID: "445f8dc0-4d73-4168-8477-f628690d18a3", X: 0, Y: 0, @@ -735,7 +735,7 @@ func Test_newCellResponses(t *testing.T) { }, }, }, - Tags: map[string][]string{"cpu": []string{"ChristohersMBP2.lan"}}, + Tags: map[string][]string{"cpu": {"ChristohersMBP2.lan"}}, GroupBy: chronograf.GroupBy{ Time: "2s", }, @@ -751,20 +751,20 @@ func Test_newCellResponses(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, Type: "line", CellColors: []chronograf.CellColor{ - chronograf.CellColor{ID: "0", Type: "min", Hex: "#00C9FF", Name: "laser", Value: "0"}, - chronograf.CellColor{ID: "1", Type: "max", Hex: "#9394FF", Name: "comet", Value: "100"}, + {ID: "0", Type: "min", Hex: "#00C9FF", Name: "laser", Value: "0"}, + {ID: "1", Type: "max", Hex: "#9394FF", Name: "comet", Value: "100"}, }, Legend: chronograf.Legend{ Type: "static", @@ -817,13 +817,13 @@ func Test_newCellResponses(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, @@ -860,7 +860,7 @@ func Test_newCellResponses(t *testing.T) { name: "nothing set", dID: chronograf.DashboardID(1), dcells: []chronograf.DashboardCell{ - chronograf.DashboardCell{ + { ID: "445f8dc0-4d73-4168-8477-f628690d18a3", X: 0, Y: 0, @@ -878,13 +878,13 @@ func Test_newCellResponses(t *testing.T) { Name: "Untitled Cell", Queries: []chronograf.DashboardQuery{}, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, diff --git a/server/cellsv2.go b/server/cellsv2.go index b1e9672dde..287df236a4 100644 --- a/server/cellsv2.go +++ b/server/cellsv2.go @@ -7,7 +7,7 @@ import ( "net/http" "github.com/bouk/httprouter" - "github.com/influxdata/chronograf/v2" + platform "github.com/influxdata/chronograf/v2" ) type cellV2Links struct { diff --git a/server/dashboards_test.go b/server/dashboards_test.go index 2ecf994c4b..161d9ef639 100644 --- a/server/dashboards_test.go +++ b/server/dashboards_test.go @@ -240,10 +240,10 @@ func Test_newDashboardResponse(t *testing.T) { }, }, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"0", "100"}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"2", "95"}, Label: "foo", }, @@ -267,7 +267,7 @@ func Test_newDashboardResponse(t *testing.T) { Organization: "0", Templates: []templateResponse{}, Cells: []dashboardCellResponse{ - dashboardCellResponse{ + { Links: dashboardCellLinks{ Self: "/chronograf/v1/dashboards/0/cells/a", }, @@ -300,21 +300,21 @@ func Test_newDashboardResponse(t *testing.T) { }, CellColors: []chronograf.CellColor{}, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"0", "100"}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"2", "95"}, Label: "foo", }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, NoteVisibility: "default", }, }, - dashboardCellResponse{ + { Links: dashboardCellLinks{ Self: "/chronograf/v1/dashboards/0/cells/b", }, @@ -323,13 +323,13 @@ func Test_newDashboardResponse(t *testing.T) { W: 4, H: 4, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, }, }, diff --git a/server/databases_test.go b/server/databases_test.go index f703a90b78..99b7e44829 100644 --- a/server/databases_test.go +++ b/server/databases_test.go @@ -35,7 +35,7 @@ func TestService_GetDatabases(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -78,7 +78,7 @@ func TestService_NewDatabase(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -121,7 +121,7 @@ func TestService_DropDatabase(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -164,7 +164,7 @@ func TestService_RetentionPolicies(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -207,7 +207,7 @@ func TestService_NewRetentionPolicy(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -250,7 +250,7 @@ func TestService_UpdateRetentionPolicy(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -293,7 +293,7 @@ func TestService_DropRetentionPolicy(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -616,7 +616,7 @@ func TestValidDatabaseRequest(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -636,7 +636,7 @@ func TestValidRetentionPolicyRequest(t *testing.T) { args args wantErr bool }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/server/helpers.go b/server/helpers.go index 8952734982..36e027e133 100644 --- a/server/helpers.go +++ b/server/helpers.go @@ -1,7 +1,46 @@ package server -import "net/http" +import ( + "net/http" + "path" +) func location(w http.ResponseWriter, self string) { w.Header().Add("Location", self) } + +// hsts add HTTP Strict Transport Security header with a max-age of two years +// Inspired from https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go +func hsts(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains") + next.ServeHTTP(w, r) + }) +} + +// version handler adds X-Chronograf-Version header to responses +func version(version string, h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("X-Chronograf-Version", version) + h.ServeHTTP(w, r) + } + return http.HandlerFunc(fn) +} + +// logout chooses the correct provider logout route and redirects to it +func logout(nextURL, basepath string, routes AuthRoutes) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + principal, err := getPrincipal(ctx) + if err != nil { + http.Redirect(w, r, path.Join(basepath, nextURL), http.StatusTemporaryRedirect) + return + } + route, ok := routes.Lookup(principal.Issuer) + if !ok { + http.Redirect(w, r, path.Join(basepath, nextURL), http.StatusTemporaryRedirect) + return + } + http.Redirect(w, r, route.Logout, http.StatusTemporaryRedirect) + } +} diff --git a/server/hsts.go b/server/hsts.go deleted file mode 100644 index 1b6f54d71a..0000000000 --- a/server/hsts.go +++ /dev/null @@ -1,12 +0,0 @@ -package server - -import "net/http" - -// HSTS add HTTP Strict Transport Security header with a max-age of two years -// Inspired from https://blog.bracebin.com/achieving-perfect-ssl-labs-score-with-go -func HSTS(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains") - next.ServeHTTP(w, r) - }) -} diff --git a/server/layout_test.go b/server/layout_test.go index 9ff1dbbabe..15b143e93a 100644 --- a/server/layout_test.go +++ b/server/layout_test.go @@ -37,7 +37,7 @@ func Test_Layouts(t *testing.T) { Measurement: "influxdb", }, []chronograf.Layout{ - chronograf.Layout{ + { ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", Application: "influxdb", Measurement: "influxdb", @@ -54,12 +54,12 @@ func Test_Layouts(t *testing.T) { Measurement: "influxdb", }, []chronograf.Layout{ - chronograf.Layout{ + { ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", Application: "influxdb", Measurement: "influxdb", }, - chronograf.Layout{ + { ID: "b020101b-ea6b-4c8c-9f0e-db0ba501f4ef", Application: "chronograf", Measurement: "chronograf", @@ -84,13 +84,13 @@ func Test_Layouts(t *testing.T) { Name: "A Graph", CellColors: []chronograf.CellColor{}, Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{}, }, - "y": chronograf.Axis{ + "y": { Bounds: []string{}, }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{}, }, }, @@ -98,7 +98,7 @@ func Test_Layouts(t *testing.T) { }, }, []chronograf.Layout{ - chronograf.Layout{ + { ID: "d20a21c8-69f1-4780-90fe-e69f5e4d138c", Application: "influxdb", Measurement: "influxdb", diff --git a/server/logout.go b/server/logout.go deleted file mode 100644 index dd7c2cabe4..0000000000 --- a/server/logout.go +++ /dev/null @@ -1,24 +0,0 @@ -package server - -import ( - "net/http" - "path" -) - -// Logout chooses the correct provider logout route and redirects to it -func Logout(nextURL, basepath string, routes AuthRoutes) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - principal, err := getPrincipal(ctx) - if err != nil { - http.Redirect(w, r, path.Join(basepath, nextURL), http.StatusTemporaryRedirect) - return - } - route, ok := routes.Lookup(principal.Issuer) - if !ok { - http.Redirect(w, r, path.Join(basepath, nextURL), http.StatusTemporaryRedirect) - return - } - http.Redirect(w, r, route.Logout, http.StatusTemporaryRedirect) - } -} diff --git a/server/me.go b/server/me.go index 4d4575efc7..807e6eb2db 100644 --- a/server/me.go +++ b/server/me.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "sort" "golang.org/x/net/context" @@ -43,7 +44,7 @@ func newMeResponse(usr *chronograf.User, org string) meResponse { name := "me" if usr != nil { base = fmt.Sprintf("/chronograf/v1/organizations/%s/users", org) - name = PathEscape(fmt.Sprintf("%d", usr.ID)) + name = url.PathEscape(fmt.Sprintf("%d", usr.ID)) } return meResponse{ @@ -378,7 +379,7 @@ func (s *Service) usersOrganizations(ctx context.Context, u *chronograf.User) ([ } orgs := []chronograf.Organization{} - for orgID, _ := range orgIDs { + for orgID := range orgIDs { org, err := s.Store.Organizations(ctx).Get(ctx, chronograf.OrganizationQuery{ID: &orgID}) // There can be race conditions between deleting a organization and the me query diff --git a/server/me_test.go b/server/me_test.go index 71522cbdcd..e15f9c461a 100644 --- a/server/me_test.go +++ b/server/me_test.go @@ -295,7 +295,7 @@ func TestService_Me(t *testing.T) { }, AllF: func(ctx context.Context) ([]chronograf.Organization, error) { return []chronograf.Organization{ - chronograf.Organization{ + { ID: "0", Name: "The Gnarly Default", DefaultRole: roles.ViewerRoleName, @@ -375,7 +375,7 @@ func TestService_Me(t *testing.T) { }, AllF: func(ctx context.Context) ([]chronograf.Organization, error) { return []chronograf.Organization{ - chronograf.Organization{ + { ID: "0", Name: "The Gnarly Default", DefaultRole: roles.ViewerRoleName, @@ -455,7 +455,7 @@ func TestService_Me(t *testing.T) { }, AllF: func(ctx context.Context) ([]chronograf.Organization, error) { return []chronograf.Organization{ - chronograf.Organization{ + { ID: "0", Name: "The Gnarly Default", DefaultRole: roles.ViewerRoleName, @@ -525,7 +525,7 @@ func TestService_Me(t *testing.T) { }, AllF: func(ctx context.Context) ([]chronograf.Organization, error) { return []chronograf.Organization{ - chronograf.Organization{ + { ID: "0", Name: "The Bad Place", DefaultRole: roles.ViewerRoleName, diff --git a/server/mux.go b/server/mux.go index d6b8e30f4f..6bf9eb79ed 100644 --- a/server/mux.go +++ b/server/mux.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/http" + "net/url" "path" "strconv" "strings" @@ -11,8 +12,8 @@ import ( _ "net/http/pprof" "github.com/NYTimes/gziphandler" - "github.com/bouk/httprouter" - "github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch + "github.com/bouk/httprouter" // When julienschmidt/httprouter v2 w/ context is out, switch + "github.com/influxdata/chronograf" "github.com/influxdata/chronograf/oauth2" "github.com/influxdata/chronograf/roles" ) @@ -30,10 +31,10 @@ type MuxOpts struct { UseAuth bool // UseAuth turns on Github OAuth and JWT Auth oauth2.Authenticator // Auth is used to authenticate and authorize ProviderFuncs []func(func(oauth2.Provider, oauth2.Mux)) - StatusFeedURL string // JSON Feed URL for the client Status page News Feed - CustomLinks map[string]string // Any custom external links for client's User menu - PprofEnabled bool // Mount pprof routes for profiling - DisableGZip bool // Optionally disable gzip. + StatusFeedURL string // JSON Feed URL for the client Status page News Feed + CustomLinks []CustomLink // Any custom external links for client's User menu + PprofEnabled bool // Mount pprof routes for profiling + DisableGZip bool // Optionally disable gzip. } // NewMux attaches all the route handlers; handler returned servers chronograf. @@ -380,7 +381,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler { allRoutes.LogoutLink = path.Join(opts.Basepath, "/oauth/logout") // Create middleware that redirects to the appropriate provider logout - router.GET("/oauth/logout", Logout("/", opts.Basepath, allRoutes.AuthRoutes)) + router.GET("/oauth/logout", logout("/", opts.Basepath, allRoutes.AuthRoutes)) out = Logger(opts.Logger, FlushingHandler(auth)) } else { out = Logger(opts.Logger, FlushingHandler(router)) @@ -394,7 +395,7 @@ func AuthAPI(opts MuxOpts, router chronograf.Router) (http.Handler, AuthRoutes) routes := AuthRoutes{} for _, pf := range opts.ProviderFuncs { pf(func(p oauth2.Provider, m oauth2.Mux) { - urlName := PathEscape(strings.ToLower(p.Name())) + urlName := url.PathEscape(strings.ToLower(p.Name())) loginPath := path.Join("/oauth", urlName, "login") logoutPath := path.Join("/oauth", urlName, "logout") diff --git a/server/organizations_test.go b/server/organizations_test.go index 51dfd3b0fd..2f134acc0e 100644 --- a/server/organizations_test.go +++ b/server/organizations_test.go @@ -168,11 +168,11 @@ func TestService_Organizations(t *testing.T) { OrganizationsStore: &mocks.OrganizationsStore{ AllF: func(ctx context.Context) ([]chronograf.Organization, error) { return []chronograf.Organization{ - chronograf.Organization{ + { ID: "1337", Name: "The Good Place", }, - chronograf.Organization{ + { ID: "100", Name: "The Bad Place", }, diff --git a/server/path.go b/server/path.go deleted file mode 100644 index c1293e3cca..0000000000 --- a/server/path.go +++ /dev/null @@ -1,10 +0,0 @@ -package server - -import "net/url" - -// PathEscape escapes the string so it can be safely placed inside a URL path segment. -// Change to url.PathEscape for go 1.8 -func PathEscape(str string) string { - u := &url.URL{Path: str} - return u.String() -} diff --git a/server/protoboards_test.go b/server/protoboards_test.go index 8235c29129..40e8e031f5 100644 --- a/server/protoboards_test.go +++ b/server/protoboards_test.go @@ -45,7 +45,7 @@ func Test_Protoboards(t *testing.T) { contentType: "application/json", body: `{"protoboards":[{"id":"1","meta":{"name":"protodashboard 1","icon":"http://example.com/icon.png","version":"1.2.3","measurements":["m1","m2"],"dashboardVersion":"1.7.0","description":"this is great","author":"Chronogiraffe","license":"Apache-2.0","url":"http://example.com"},"data":{"cells":[{"x":0,"y":0,"w":0,"h":0,"name":"","queries":null,"axes":null,"type":"","colors":null,"legend":{},"tableOptions":{"verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fixFirstColumn":false},"fieldOptions":null,"timeFormat":"","decimalPlaces":{"isEnforced":false,"digits":0},"note":"","noteVisibility":""}],"templates":[{"tempVar":"","values":null,"id":"","type":"","label":""}]},"links":{"self":"/chronograf/v1/protoboards/1"}},{"id":"2","meta":{"name":"protodashboard 2","icon":"http://example.com/icon.png","version":"1.2.3","measurements":["m1","m2"],"dashboardVersion":"1.7.0","description":"this is great","author":"Chronogiraffe","license":"Apache-2.0","url":"http://example.com"},"data":{"cells":[{"x":8,"y":0,"w":3,"h":5,"name":"Untitled Cell","queries":[{"query":"SELECT mean(\"usage_steal\") AS \"mean_usage_steal\", mean(\"usage_system\") AS \"mean_usage_system\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time \u003e :dashboardTime: AND \"host\"='denizs-MacBook-Pro.local' GROUP BY time(:interval:) FILL(null)","queryConfig":{"database":"telegraf","measurement":"cpu","retentionPolicy":"autogen","fields":[{"value":"mean","type":"func","alias":"mean_usage_steal","args":[{"value":"usage_steal","type":"field","alias":""}]},{"value":"mean","type":"func","alias":"mean_usage_system","args":[{"value":"usage_steal","type":"field","alias":""}]}],"tags":{"host":["denizs-MacBook-Pro.local"]},"groupBy":{"time":"auto","tags":[]},"areTagsAccepted":true,"fill":"null","rawText":null,"range":null,"shifts":null},"source":"","type":"influxql"}],"axes":{"x":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"},"y2":{"bounds":["",""],"label":"","prefix":"","suffix":"","base":"10","scale":"linear"}},"type":"line","colors":[],"legend":{},"tableOptions":{"verticalTimeAxis":false,"sortBy":{"internalName":"","displayName":"","visible":false},"wrapping":"","fixFirstColumn":false},"fieldOptions":[],"timeFormat":"","decimalPlaces":{"isEnforced":true,"digits":2},"note":"","noteVisibility":""}],"templates":null},"links":{"self":"/chronograf/v1/protoboards/2"}}]}`}, arg: []chronograf.Protoboard{ - chronograf.Protoboard{ + { ID: "1", Meta: chronograf.ProtoboardMeta{ Name: "protodashboard 1", @@ -58,18 +58,18 @@ func Test_Protoboards(t *testing.T) { License: "Apache-2.0", URL: "http://example.com", }, - Data: chronograf.ProtoboardData{Cells: []chronograf.ProtoboardCell{chronograf.ProtoboardCell{}}, Templates: []chronograf.Template{chronograf.Template{}}}}, - chronograf.Protoboard{ + Data: chronograf.ProtoboardData{Cells: []chronograf.ProtoboardCell{{}}, Templates: []chronograf.Template{{}}}}, + { ID: "2", Meta: chronograf.ProtoboardMeta{Name: "protodashboard 2", Measurements: []string{"m1", "m2"}, Icon: "http://example.com/icon.png", Version: "1.2.3", DashboardVersion: "1.7.0", Description: "this is great", Author: "Chronogiraffe", License: "Apache-2.0", URL: "http://example.com"}, - Data: chronograf.ProtoboardData{Cells: []chronograf.ProtoboardCell{chronograf.ProtoboardCell{ + Data: chronograf.ProtoboardData{Cells: []chronograf.ProtoboardCell{{ X: 8, Y: 0, W: 3, H: 5, Name: "Untitled Cell", Axes: map[string]chronograf.Axis{ - "x": chronograf.Axis{ + "x": { Bounds: []string{"", ""}, Label: "", Prefix: "", @@ -77,7 +77,7 @@ func Test_Protoboards(t *testing.T) { Base: "10", Scale: "linear", }, - "y": chronograf.Axis{ + "y": { Bounds: []string{"", ""}, Label: "", Prefix: "", @@ -85,7 +85,7 @@ func Test_Protoboards(t *testing.T) { Base: "10", Scale: "linear", }, - "y2": chronograf.Axis{ + "y2": { Bounds: []string{"", ""}, Label: "", Prefix: "", @@ -119,7 +119,7 @@ func Test_Protoboards(t *testing.T) { Note: "", NoteVisibility: "", Queries: []chronograf.DashboardQuery{ - chronograf.DashboardQuery{ + { Command: "SELECT mean(\"usage_steal\") AS \"mean_usage_steal\", mean(\"usage_system\") AS \"mean_usage_system\" FROM \"telegraf\".\"autogen\".\"cpu\" WHERE time > :dashboardTime: AND \"host\"='denizs-MacBook-Pro.local' GROUP BY time(:interval:) FILL(null)", Label: "", QueryConfig: chronograf.QueryConfig{ @@ -128,24 +128,24 @@ func Test_Protoboards(t *testing.T) { Measurement: "cpu", RetentionPolicy: "autogen", Fields: []chronograf.Field{ - chronograf.Field{ + { Value: "mean", Type: "func", Alias: "mean_usage_steal", Args: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_steal", Type: "field", Alias: "", }, }, }, - chronograf.Field{ + { Value: "mean", Type: "func", Alias: "mean_usage_system", Args: []chronograf.Field{ - chronograf.Field{ + { Value: "usage_steal", Type: "field", Alias: "", @@ -154,7 +154,7 @@ func Test_Protoboards(t *testing.T) { }, }, Tags: map[string][]string{ - "host": []string{ + "host": { "denizs-MacBook-Pro.local", }, }, diff --git a/server/redoc.go b/server/redoc.go index 77f4e83c0a..7a74cc80de 100644 --- a/server/redoc.go +++ b/server/redoc.go @@ -28,7 +28,7 @@ const index = ` ` -// Redoc servers the swagger JSON using the redoc package. +// Redoc serves the swagger JSON using the redoc package. func Redoc(swagger string) http.HandlerFunc { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { rw.Header().Set("Content-Type", "text/html; charset=utf-8") diff --git a/server/routes.go b/server/routes.go index 2cdc412e3f..8c1637098f 100644 --- a/server/routes.go +++ b/server/routes.go @@ -60,18 +60,12 @@ type AllRoutes struct { AuthRoutes []AuthRoute // Location of all auth routes. If no auth, this can be empty. LogoutLink string // Location of the logout route for all auth routes. If no auth, this can be empty. StatusFeed string // External link to the JSON Feed for the News Feed on the client's Status Page - CustomLinks map[string]string // Custom external links for client's User menu, as passed in via CLI/ENV + CustomLinks []CustomLink // Custom external links for client's User menu, as passed in via CLI/ENV Logger chronograf.Logger } // serveHTTP returns all top level routes and external links within chronograf func (a *AllRoutes) ServeHTTP(w http.ResponseWriter, r *http.Request) { - customLinks, err := NewCustomLinks(a.CustomLinks) - if err != nil { - Error(w, http.StatusInternalServerError, err.Error(), a.Logger) - return - } - org := "default" if a.GetPrincipal != nil { // If there is a principal, use the organization to populate the users routes @@ -105,7 +99,7 @@ func (a *AllRoutes) ServeHTTP(w http.ResponseWriter, r *http.Request) { Auth: make([]AuthRoute, len(a.AuthRoutes)), // We want to return at least an empty array, rather than null ExternalLinks: getExternalLinksResponse{ StatusFeed: &a.StatusFeed, - CustomLinks: customLinks, + CustomLinks: a.CustomLinks, }, Flux: getFluxLinksResponse{ Self: "/chronograf/v1/flux", diff --git a/server/routes_test.go b/server/routes_test.go index 258b0ec21b..ca2ede9959 100644 --- a/server/routes_test.go +++ b/server/routes_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/influxdata/chronograf/log" + "github.com/stretchr/testify/require" ) func TestAllRoutes(t *testing.T) { @@ -85,9 +86,12 @@ func TestAllRoutesWithAuth(t *testing.T) { func TestAllRoutesWithExternalLinks(t *testing.T) { statusFeedURL := "http://pineapple.life/feed.json" - customLinks := map[string]string{ + + customLinks, err := NewCustomLinks(map[string]string{ "cubeapple": "https://cube.apple", - } + }) + require.NoError(t, err) + logger := log.New(log.DebugLevel) handler := &AllRoutes{ StatusFeed: statusFeedURL, diff --git a/server/server.go b/server/server.go index 89dfc1f5bb..53c94250e6 100644 --- a/server/server.go +++ b/server/server.go @@ -17,14 +17,13 @@ import ( "time" "github.com/influxdata/chronograf" - "github.com/influxdata/chronograf/bolt" idgen "github.com/influxdata/chronograf/id" "github.com/influxdata/chronograf/influx" + "github.com/influxdata/chronograf/kv/bolt" clog "github.com/influxdata/chronograf/log" "github.com/influxdata/chronograf/oauth2" client "github.com/influxdata/usage-client/v1" flags "github.com/jessevdk/go-flags" - "github.com/tylerb/graceful" ) var ( @@ -54,8 +53,6 @@ type Server struct { KapacitorUsername string `long:"kapacitor-username" description:"Username of your Kapacitor instance" env:"KAPACITOR_USERNAME"` KapacitorPassword string `long:"kapacitor-password" description:"Password of your Kapacitor instance" env:"KAPACITOR_PASSWORD"` - NewSources string `long:"new-sources" description:"Config for adding a new InfluxDB source and Kapacitor server, in JSON as an array of objects, and surrounded by single quotes. E.g. --new-sources='[{\"influxdb\":{\"name\":\"Influx 1\",\"username\":\"user1\",\"password\":\"pass1\",\"url\":\"http://localhost:8086\",\"metaUrl\":\"http://metaurl.com\",\"type\":\"influx-enterprise\",\"insecureSkipVerify\":false,\"default\":true,\"telegraf\":\"telegraf\",\"sharedSecret\":\"cubeapples\"},\"kapacitor\":{\"name\":\"Kapa 1\",\"url\":\"http://localhost:9092\",\"active\":true}}]'" env:"NEW_SOURCES" hidden:"true"` - Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (e.g. './chronograf-v1.db')" env:"BOLT_PATH" default:"chronograf-v1.db"` CannedPath string `short:"c" long:"canned-path" description:"Path to directory of pre-canned application layouts (/usr/share/chronograf/canned)" env:"CANNED_PATH" default:"canned"` @@ -105,8 +102,6 @@ type Server struct { Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted. (Note: PREFIX_ROUTES has been deprecated. Now, if basepath is set, all routes will be prefixed with it.)" env:"BASE_PATH"` ShowVersion bool `short:"v" long:"version" description:"Show Chronograf version info"` BuildInfo chronograf.BuildInfo - Listener net.Listener - handler http.Handler } func provide(p oauth2.Provider, m oauth2.Mux, ok func() bool) func(func(oauth2.Provider, oauth2.Mux)) { @@ -249,7 +244,7 @@ func (s *Server) useTLS() bool { return s.Cert != "" } -// NewListener will an http or https listener depending useTLS() +// NewListener will return an http or https listener depending useTLS(). func (s *Server) NewListener() (net.Listener, error) { addr := net.JoinHostPort(s.Host, strconv.Itoa(s.Port)) if !s.useTLS() { @@ -273,10 +268,10 @@ func (s *Server) NewListener() (net.Listener, error) { listener, err := tls.Listen("tcp", addr, &tls.Config{ Certificates: []tls.Certificate{cert}, }) - if err != nil { return nil, err } + return listener, nil } @@ -330,16 +325,17 @@ func (s *Server) newBuilders(logger chronograf.Logger) builders { } // Serve starts and runs the chronograf server -func (s *Server) Serve(ctx context.Context) error { +func (s *Server) Serve(ctx context.Context) { logger := clog.New(clog.ParseLevel(s.LogLevel)) - _, err := NewCustomLinks(s.CustomLinks) + customLinks, err := NewCustomLinks(s.CustomLinks) if err != nil { logger. WithField("component", "server"). WithField("CustomLink", "invalid"). Error(err) - return err + return } + service := openService(ctx, s.BuildInfo, s.BoltPath, s.newBuilders(logger), s.ProtoboardsPath, logger, s.useAuth()) service.SuperAdminProviderGroups = superAdminProviderGroups{ auth0: s.Auth0SuperAdminOrg, @@ -347,13 +343,6 @@ func (s *Server) Serve(ctx context.Context) error { service.Env = chronograf.Environment{ TelegrafSystemInterval: s.TelegrafSystemInterval, } - if err := service.HandleNewSources(ctx, s.NewSources); err != nil { - logger. - WithField("component", "server"). - WithField("new-sources", "invalid"). - Error(err) - return err - } if !validBasepath(s.Basepath) { err := fmt.Errorf("Invalid basepath, must follow format \"/mybasepath\"") @@ -361,19 +350,19 @@ func (s *Server) Serve(ctx context.Context) error { WithField("component", "server"). WithField("basepath", "invalid"). Error(err) - return err + return } - providerFuncs := []func(func(oauth2.Provider, oauth2.Mux)){} - auth := oauth2.NewCookieJWT(s.TokenSecret, s.AuthDuration) - providerFuncs = append(providerFuncs, provide(s.githubOAuth(logger, auth))) - providerFuncs = append(providerFuncs, provide(s.googleOAuth(logger, auth))) - providerFuncs = append(providerFuncs, provide(s.herokuOAuth(logger, auth))) - providerFuncs = append(providerFuncs, provide(s.genericOAuth(logger, auth))) - providerFuncs = append(providerFuncs, provide(s.auth0OAuth(logger, auth))) + providerFuncs := []func(func(oauth2.Provider, oauth2.Mux)){ + provide(s.githubOAuth(logger, auth)), + provide(s.googleOAuth(logger, auth)), + provide(s.herokuOAuth(logger, auth)), + provide(s.genericOAuth(logger, auth)), + provide(s.auth0OAuth(logger, auth)), + } - s.handler = NewMux(MuxOpts{ + handler := NewMux(MuxOpts{ Develop: s.Develop, Auth: auth, Logger: logger, @@ -381,42 +370,30 @@ func (s *Server) Serve(ctx context.Context) error { ProviderFuncs: providerFuncs, Basepath: s.Basepath, StatusFeedURL: s.StatusFeedURL, - CustomLinks: s.CustomLinks, + CustomLinks: customLinks, PprofEnabled: s.PprofEnabled, DisableGZip: s.DisableGZip, }, service) // Add chronograf's version header to all requests - s.handler = Version(s.BuildInfo.Version, s.handler) + handler = version(s.BuildInfo.Version, handler) if s.useTLS() { // Add HSTS to instruct all browsers to change from http to https - s.handler = HSTS(s.handler) + handler = hsts(handler) } - listener, err := s.NewListener() - if err != nil { - logger. - WithField("component", "server"). - Error(err) - return err - } - s.Listener = listener - // Using a log writer for http server logging w := logger.Writer() defer w.Close() stdLog := log.New(w, "", 0) - // TODO: Remove graceful when changing to go 1.8 - httpServer := &graceful.Server{ - Server: &http.Server{ - ErrorLog: stdLog, - Handler: s.handler, - }, - Logger: stdLog, - TCPKeepAlive: 5 * time.Second, + httpServer := &http.Server{ + ErrorLog: stdLog, + Handler: handler, + IdleTimeout: 5 * time.Second, } + httpServer.SetKeepAlivesEnabled(true) if !s.ReportingDisabled { @@ -426,22 +403,30 @@ func (s *Server) Serve(ctx context.Context) error { if s.useTLS() { scheme = "https" } + + listener, err := s.NewListener() + if err != nil { + logger. + WithField("component", "server"). + Error(err) + return + } + defer listener.Close() + logger. WithField("component", "server"). - Info("Serving chronograf at ", scheme, "://", s.Listener.Addr()) + Info("Serving chronograf at ", scheme, "://", listener.Addr()) - if err := httpServer.Serve(s.Listener); err != nil { + if err := httpServer.Serve(listener); err != nil { logger. WithField("component", "server"). Error(err) - return err + return } logger. WithField("component", "server"). - Info("Stopped serving chronograf at ", scheme, "://", s.Listener.Addr()) - - return nil + Info("Stopped serving chronograf at ", scheme, "://", listener.Addr()) } func openService(ctx context.Context, buildInfo chronograf.BuildInfo, boltPath string, builder builders, protoboardsPath string, logger chronograf.Logger, useAuth bool) Service { @@ -540,7 +525,7 @@ func reportUsageStats(bi chronograf.BuildInfo, logger chronograf.Logger) { WithField("freq", "24h"). WithField("stats", "os,arch,version,cluster_id,uptime") l.Info("Reporting usage stats") - _, _ = reporter.Save(clientUsage(values)) + reporter.Save(clientUsage(values)) ticker := time.NewTicker(24 * time.Hour) defer ticker.Stop() @@ -563,7 +548,8 @@ func clientUsage(values client.Values) *client.Usage { } } +var re = regexp.MustCompile(`(\/{1}[\w-]+)+`) + func validBasepath(basepath string) bool { - re := regexp.MustCompile(`(\/{1}[\w-]+)+`) return re.ReplaceAllLiteralString(basepath, "") == "" } diff --git a/server/sources.go b/server/sources.go index 94de481b58..acf90b8463 100644 --- a/server/sources.go +++ b/server/sources.go @@ -11,7 +11,6 @@ import ( "github.com/influxdata/chronograf/enterprise" "github.com/influxdata/chronograf/flux" - "github.com/influxdata/chronograf/organizations" "github.com/bouk/httprouter" "github.com/influxdata/chronograf" @@ -486,80 +485,6 @@ func ValidSourceRequest(s *chronograf.Source, defaultOrgID string) error { return nil } -// HandleNewSources parses and persists new sources passed in via server flag -func (s *Service) HandleNewSources(ctx context.Context, input string) error { - if input == "" { - return nil - } - - s.Logger.Error("--new-sources is deprecated and will be removed in a future version.") - - var srcsKaps []struct { - Source chronograf.Source `json:"influxdb"` - Kapacitor chronograf.Server `json:"kapacitor"` - } - if err := json.Unmarshal([]byte(input), &srcsKaps); err != nil { - s.Logger. - WithField("component", "server"). - WithField("NewSources", "invalid"). - Error(err) - return err - } - - ctx = context.WithValue(ctx, organizations.ContextKey, "default") - defaultOrg, err := s.Store.Organizations(ctx).DefaultOrganization(ctx) - if err != nil { - return err - } - - for _, sk := range srcsKaps { - if err := ValidSourceRequest(&sk.Source, defaultOrg.ID); err != nil { - return err - } - // Add any new sources and kapacitors as specified via server flag - if err := s.newSourceKapacitor(ctx, sk.Source, sk.Kapacitor); err != nil { - // Continue with server run even if adding NewSource fails - s.Logger. - WithField("component", "server"). - WithField("NewSource", "invalid"). - Error(err) - return err - } - } - return nil -} - -// newSourceKapacitor adds sources to BoltDB idempotently by name, as well as respective kapacitors -func (s *Service) newSourceKapacitor(ctx context.Context, src chronograf.Source, kapa chronograf.Server) error { - srcs, err := s.Store.Sources(ctx).All(ctx) - if err != nil { - return err - } - - for _, source := range srcs { - // If source already exists, do nothing - if source.Name == src.Name { - s.Logger. - WithField("component", "server"). - WithField("NewSource", source.Name). - Info("Source already exists") - return nil - } - } - - src, err = s.Store.Sources(ctx).Add(ctx, src) - if err != nil { - return err - } - - kapa.SrcID = src.ID - if _, err := s.Store.Servers(ctx).Add(ctx, kapa); err != nil { - return err - } - - return nil -} - // NewSourceUser adds user to source func (s *Service) NewSourceUser(w http.ResponseWriter, r *http.Request) { var req sourceUserRequest diff --git a/server/sources_test.go b/server/sources_test.go index b7bf9546a4..961f13b7e6 100644 --- a/server/sources_test.go +++ b/server/sources_test.go @@ -224,185 +224,6 @@ func Test_newSourceResponse(t *testing.T) { } } -func TestService_newSourceKapacitor(t *testing.T) { - type fields struct { - SourcesStore chronograf.SourcesStore - ServersStore chronograf.ServersStore - Logger chronograf.Logger - } - type args struct { - ctx context.Context - src chronograf.Source - kapa chronograf.Server - } - srcCount := 0 - srvCount := 0 - tests := []struct { - name string - fields fields - args args - wantSrc int - wantSrv int - wantErr bool - }{ - { - name: "Add when no existing sources", - fields: fields{ - SourcesStore: &mocks.SourcesStore{ - AllF: func(ctx context.Context) ([]chronograf.Source, error) { - return []chronograf.Source{}, nil - }, - AddF: func(ctx context.Context, src chronograf.Source) (chronograf.Source, error) { - srcCount++ - src.ID = srcCount - return src, nil - }, - }, - ServersStore: &mocks.ServersStore{ - AddF: func(ctx context.Context, srv chronograf.Server) (chronograf.Server, error) { - srvCount++ - return srv, nil - }, - }, - }, - args: args{ - ctx: context.Background(), - src: chronograf.Source{ - Name: "Influx 1", - }, - kapa: chronograf.Server{ - Name: "Kapa 1", - }, - }, - wantSrc: 1, - wantSrv: 1, - }, - { - name: "Should not add if existing source", - fields: fields{ - SourcesStore: &mocks.SourcesStore{ - AllF: func(ctx context.Context) ([]chronograf.Source, error) { - return []chronograf.Source{ - { - Name: "Influx 1", - }, - }, nil - }, - AddF: func(ctx context.Context, src chronograf.Source) (chronograf.Source, error) { - srcCount++ - src.ID = srcCount - return src, nil - }, - }, - ServersStore: &mocks.ServersStore{ - AddF: func(ctx context.Context, srv chronograf.Server) (chronograf.Server, error) { - srvCount++ - return srv, nil - }, - }, - Logger: &mocks.TestLogger{}, - }, - args: args{ - ctx: context.Background(), - src: chronograf.Source{ - Name: "Influx 1", - }, - kapa: chronograf.Server{ - Name: "Kapa 1", - }, - }, - wantSrc: 0, - wantSrv: 0, - }, - { - name: "Error if All returns error", - fields: fields{ - SourcesStore: &mocks.SourcesStore{ - AllF: func(ctx context.Context) ([]chronograf.Source, error) { - return nil, fmt.Errorf("error") - }, - }, - Logger: &mocks.TestLogger{}, - }, - args: args{ - ctx: context.Background(), - }, - wantErr: true, - }, - { - name: "Error if Add returns error", - fields: fields{ - SourcesStore: &mocks.SourcesStore{ - AllF: func(ctx context.Context) ([]chronograf.Source, error) { - return []chronograf.Source{}, nil - }, - AddF: func(ctx context.Context, src chronograf.Source) (chronograf.Source, error) { - return chronograf.Source{}, fmt.Errorf("error") - }, - }, - Logger: &mocks.TestLogger{}, - }, - args: args{ - ctx: context.Background(), - }, - wantErr: true, - }, - { - name: "Error if kapa add is error", - fields: fields{ - SourcesStore: &mocks.SourcesStore{ - AllF: func(ctx context.Context) ([]chronograf.Source, error) { - return []chronograf.Source{}, nil - }, - AddF: func(ctx context.Context, src chronograf.Source) (chronograf.Source, error) { - srcCount++ - src.ID = srcCount - return src, nil - }, - }, - ServersStore: &mocks.ServersStore{ - AddF: func(ctx context.Context, srv chronograf.Server) (chronograf.Server, error) { - srvCount++ - return chronograf.Server{}, fmt.Errorf("error") - }, - }, - Logger: &mocks.TestLogger{}, - }, - args: args{ - ctx: context.Background(), - src: chronograf.Source{ - Name: "Influx 1", - }, - kapa: chronograf.Server{ - Name: "Kapa 1", - }, - }, - wantSrc: 1, - wantSrv: 1, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - srcCount = 0 - srvCount = 0 - h := &Service{ - Store: &mocks.Store{ - SourcesStore: tt.fields.SourcesStore, - ServersStore: tt.fields.ServersStore, - }, - Logger: tt.fields.Logger, - } - if err := h.newSourceKapacitor(tt.args.ctx, tt.args.src, tt.args.kapa); (err != nil) != tt.wantErr { - t.Errorf("Service.newSourceKapacitor() error = %v, wantErr %v", err, tt.wantErr) - } - if tt.wantSrc != srcCount { - t.Errorf("Service.newSourceKapacitor() count = %d, wantSrc %d", srcCount, tt.wantSrc) - } - }) - } -} - func TestService_SourcesID(t *testing.T) { type fields struct { SourcesStore chronograf.SourcesStore @@ -2122,7 +1943,7 @@ func TestService_SourceRoles(t *testing.T) { return &mocks.RolesStore{ AllF: func(ctx context.Context) ([]chronograf.Role, error) { return []chronograf.Role{ - chronograf.Role{ + { Name: "biffsgang", Permissions: chronograf.Permissions{ { diff --git a/server/swagger.go b/server/swagger.go index 2308fc7f26..a447cbca05 100644 --- a/server/swagger.go +++ b/server/swagger.go @@ -15,6 +15,6 @@ func Spec() http.HandlerFunc { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - _, _ = w.Write(swagger) + w.Write(swagger) }) } diff --git a/server/version.go b/server/version.go deleted file mode 100644 index e7fc4c9013..0000000000 --- a/server/version.go +++ /dev/null @@ -1,14 +0,0 @@ -package server - -import ( - "net/http" -) - -// Version handler adds X-Chronograf-Version header to responses -func Version(version string, h http.Handler) http.Handler { - fn := func(w http.ResponseWriter, r *http.Request) { - w.Header().Add("X-Chronograf-Version", version) - h.ServeHTTP(w, r) - } - return http.HandlerFunc(fn) -}