feat: add etcd as backend store (#5352)
* Add some comments about unused v2 stuff * Add etcd as kv backend * Add configuration options to utilize etcd backendpull/5353/head
parent
f0d5e5abef
commit
56353bee05
20
go.mod
20
go.mod
|
@ -5,28 +5,43 @@ require (
|
|||
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/coreos/bbolt v1.3.3 // indirect
|
||||
github.com/coreos/etcd v3.3.18+incompatible
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000 // indirect
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
||||
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/golang/groupcache v0.0.0-20191227052852-215e87163ea7 // indirect
|
||||
github.com/google/go-cmp v0.3.0
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/uuid v1.1.1 // indirect
|
||||
github.com/goreleaser/goreleaser v0.97.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.1 // indirect
|
||||
github.com/influxdata/flux v0.50.2
|
||||
github.com/influxdata/influxdb v1.1.5
|
||||
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/jonboulle/clockwork v0.1.0 // indirect
|
||||
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.2
|
||||
github.com/opentracing/opentracing-go v1.1.0 // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/segmentio/kafka-go v0.3.4 // indirect
|
||||
github.com/sergi/go-diff v1.1.0
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/soheilhy/cmux v0.1.4 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
go.etcd.io/bbolt v1.3.3 // indirect
|
||||
go.uber.org/atomic v1.5.1 // indirect
|
||||
go.uber.org/multierr v1.4.0 // indirect
|
||||
go.uber.org/zap v1.13.0 // indirect
|
||||
|
@ -37,9 +52,8 @@ require (
|
|||
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
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c // indirect
|
||||
google.golang.org/grpc v1.24.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.2.7 // indirect
|
||||
sigs.k8s.io/yaml v1.1.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
|
||||
|
|
46
go.sum
46
go.sum
|
@ -28,6 +28,7 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg
|
|||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db h1:nxAtV4VajJDhKysp2kdcJZsq8Ss1xSA0vZTkVHHJd0E=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
|
||||
github.com/apex/log v1.1.0 h1:J5rld6WVFi6NxA6m8GJ1LJqu3+GiTFIt3mYv27gdQWI=
|
||||
|
@ -52,6 +53,16 @@ github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMS
|
|||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.18+incompatible h1:Zz1aXgDrFFi1nadh58tA9ktt06cmPTwNNP3dXwIq1lE=
|
||||
github.com/coreos/etcd v3.3.18+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
|
||||
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=
|
||||
|
@ -72,6 +83,7 @@ github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
|||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
|
@ -80,12 +92,16 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
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.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
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/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
|
@ -115,6 +131,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
|||
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/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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=
|
||||
|
@ -123,6 +141,14 @@ github.com/goreleaser/goreleaser v0.97.0 h1:2/GZKg0cLk5HgIiiSaW/lbDfj0T/GMgF6qEF
|
|||
github.com/goreleaser/goreleaser v0.97.0/go.mod h1:MnjA0e0Uq6ISqjG1WxxMAl+3VS1QYjILSWVnMYDxasE=
|
||||
github.com/goreleaser/nfpm v0.9.7 h1:h8RQMDztu6cW7b0/s4PGbdeMYykAbJG0UMXaWG5uBMI=
|
||||
github.com/goreleaser/nfpm v0.9.7/go.mod h1:F2yzin6cBAL9gb+mSiReuXdsfTrOQwDMsuSpULof+y4=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
@ -153,6 +179,8 @@ github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJS
|
|||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
|
@ -161,6 +189,7 @@ 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.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
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=
|
||||
|
@ -226,6 +255,7 @@ github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+
|
|||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
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=
|
||||
|
@ -240,6 +270,8 @@ github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
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=
|
||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||
|
@ -257,17 +289,24 @@ 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/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
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=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
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.4.0/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=
|
||||
|
@ -280,6 +319,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEa
|
|||
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.10.0/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=
|
||||
|
@ -327,6 +367,7 @@ 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-20191002035440-2ec189313ef0/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=
|
||||
|
@ -367,6 +408,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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=
|
||||
|
@ -411,6 +453,7 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn
|
|||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU=
|
||||
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c h1:hrpEMCZ2O7DR5gC1n2AJGVhrwiEjOi35+jxtIuZpTMo=
|
||||
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
@ -437,6 +480,7 @@ 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.3/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=
|
||||
|
@ -450,3 +494,5 @@ honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXe
|
|||
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=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package kv
|
||||
|
||||
// todo: this isn't tested because it isn't really used*.
|
||||
// *there are api routes that use this, but it doesn't integrate with anything.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
|
|
@ -0,0 +1,464 @@
|
|||
package etcd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/etcd/clientv3"
|
||||
"github.com/coreos/etcd/clientv3/concurrency"
|
||||
"github.com/coreos/etcd/mvcc/mvccpb"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/influxdata/chronograf/kv"
|
||||
"github.com/influxdata/chronograf/mocks"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultDialTimeout is the default dial timeout for the etc client.
|
||||
DefaultDialTimeout = 5 * time.Second
|
||||
// DefaultRequestTimeout is the default request timeout for the etc client.
|
||||
DefaultRequestTimeout = 5 * time.Second
|
||||
// DefaultCacheTimeout is the default timeout for a health check when waiting for a response from the cache.
|
||||
DefaultCacheTimeout = 2 * time.Second
|
||||
)
|
||||
|
||||
var _ kv.Store = (*client)(nil)
|
||||
|
||||
// client is a client for the boltDB data store.
|
||||
type client struct {
|
||||
db *clientv3.Client
|
||||
config clientv3.Config
|
||||
logger chronograf.Logger
|
||||
requestTimeout time.Duration
|
||||
}
|
||||
|
||||
// NewClient creates an etcd client implementing the kv.Store interface.
|
||||
func NewClient(ctx context.Context, opts ...Option) (*client, error) {
|
||||
c := &client{
|
||||
logger: mocks.NewLogger(),
|
||||
config: clientv3.Config{
|
||||
Endpoints: []string{"localhost:2379"},
|
||||
DialTimeout: DefaultDialTimeout,
|
||||
},
|
||||
requestTimeout: DefaultRequestTimeout,
|
||||
}
|
||||
|
||||
for i := range opts {
|
||||
if err := opts[i](c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
e, err := clientv3.New(c.config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.db = e
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Option to change behavior of Open()
|
||||
type Option func(c *client) error
|
||||
|
||||
// WithEndpoints allows for setting the etcd hosts.
|
||||
func WithEndpoints(h []string) Option {
|
||||
return func(c *client) error {
|
||||
if len(h) == 0 {
|
||||
return nil
|
||||
}
|
||||
c.config.Endpoints = h
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDialTimeout allows for setting the etcd dial timeout.
|
||||
func WithDialTimeout(d time.Duration) Option {
|
||||
return func(c *client) error {
|
||||
if d < 0 {
|
||||
return nil
|
||||
}
|
||||
c.config.DialTimeout = d
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithRequestTimeout allows for setting the etcd request timeout.
|
||||
func WithRequestTimeout(d time.Duration) Option {
|
||||
return func(c *client) error {
|
||||
if d < 0 {
|
||||
return nil
|
||||
}
|
||||
c.requestTimeout = d
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogger allows for setting this chronograf's logger.
|
||||
func WithLogger(logger chronograf.Logger) Option {
|
||||
return func(c *client) error {
|
||||
if logger == nil {
|
||||
return nil
|
||||
}
|
||||
c.logger = logger
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogin allows for setting the username and password to connect to the etcd cluster.
|
||||
func WithLogin(u, p string) Option {
|
||||
return func(c *client) error {
|
||||
c.config.Username = u
|
||||
c.config.Password = p
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Close closes the backing etcd client.
|
||||
func (c *client) Close() error {
|
||||
return c.db.Close()
|
||||
}
|
||||
|
||||
// View opens up a view transaction against the database. This operation
|
||||
// likely does not need to be an STM.
|
||||
func (c *client) View(ctx context.Context, fn func(kv.Tx) error) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, c.requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
return c.Apply(ctx, func(m concurrency.STM) error {
|
||||
return fn(&Tx{
|
||||
m: m,
|
||||
ctx: ctx,
|
||||
client: c,
|
||||
writable: false,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Update opens up a mutable transaction against the database. Get range
|
||||
// is not supported with etcd STMs. This might be an issue, we should consider
|
||||
// if this functionality works for us.
|
||||
func (c *client) Update(ctx context.Context, fn func(kv.Tx) error) error {
|
||||
ctx, cancel := context.WithTimeout(ctx, c.requestTimeout)
|
||||
defer cancel()
|
||||
|
||||
return c.Apply(ctx, func(m concurrency.STM) error {
|
||||
return fn(&Tx{
|
||||
m: m,
|
||||
ctx: ctx,
|
||||
client: c,
|
||||
writable: true,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (c *client) Apply(ctx context.Context, callback func(stm concurrency.STM) error) error {
|
||||
_, err := concurrency.NewSTM(c.db, func(stm concurrency.STM) error {
|
||||
return c.recoverCallback(callback, stm)
|
||||
}, concurrency.WithAbortContext(ctx))
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *client) recoverCallback(callback func(stm concurrency.STM) error, stm concurrency.STM) (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = errors.New("unknown internal transaction error")
|
||||
c.logger.Error("panic while in STM")
|
||||
}
|
||||
}()
|
||||
err = callback(stm)
|
||||
return err
|
||||
}
|
||||
|
||||
// Tx is a etcd transaction.
|
||||
type Tx struct {
|
||||
m concurrency.STM
|
||||
client *client
|
||||
ctx context.Context
|
||||
writable bool
|
||||
}
|
||||
|
||||
// Context returns the context from the transaction.
|
||||
func (t *Tx) Context() context.Context {
|
||||
return t.ctx
|
||||
}
|
||||
|
||||
// WithContext sets the provided context on transaction.
|
||||
func (t *Tx) WithContext(ctx context.Context) {
|
||||
t.ctx = ctx
|
||||
}
|
||||
|
||||
// Bucket creates a bucket struct with the provided bucket.
|
||||
func (t *Tx) Bucket(b []byte) kv.Bucket {
|
||||
return &Bucket{
|
||||
tx: t,
|
||||
prefix: b,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateBucketIfNotExists creates a bucket with the provided byte slice.
|
||||
func (t *Tx) CreateBucketIfNotExists(b []byte) (kv.Bucket, error) {
|
||||
return &Bucket{
|
||||
tx: t,
|
||||
prefix: b,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Bucket is a key value bucket.
|
||||
type Bucket struct {
|
||||
tx *Tx
|
||||
prefix []byte
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrKeyNotFound is the error returned when the key requested is not found.
|
||||
ErrKeyNotFound = errors.New("key not found")
|
||||
// ErrTxNotWritable is the error returned when an mutable operation is called during
|
||||
// a non-writable transaction.
|
||||
ErrTxNotWritable = errors.New("transaction is not writable")
|
||||
)
|
||||
|
||||
// Get gets the value at the provided key.
|
||||
func (b *Bucket) Get(key []byte) ([]byte, error) {
|
||||
v := b.tx.m.Get(b.encodeKey(key))
|
||||
if len(v) == 0 {
|
||||
return nil, ErrKeyNotFound
|
||||
}
|
||||
return []byte(v), nil
|
||||
}
|
||||
|
||||
// Put puts the provided key and value in the store.
|
||||
func (b *Bucket) Put(key []byte, value []byte) error {
|
||||
if b.tx.writable {
|
||||
b.tx.m.Put(b.encodeKey(key), string(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrTxNotWritable
|
||||
}
|
||||
|
||||
// Delete removes the key from the database.
|
||||
func (b *Bucket) Delete(key []byte) error {
|
||||
if b.tx.writable {
|
||||
b.tx.m.Del(b.encodeKey(key))
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrTxNotWritable
|
||||
}
|
||||
|
||||
func (b *Bucket) encodeKey(key []byte) string {
|
||||
k := append([]byte{}, b.prefix...)
|
||||
k = append(k, '/')
|
||||
k = append(k, key...)
|
||||
return string(k)
|
||||
}
|
||||
|
||||
// Cursor retrieves all keys from the bucket and creates a static cursor from them.
|
||||
func (b *Bucket) Cursor() (kv.Cursor, error) {
|
||||
ps, err := b.getAll(string(b.prefix))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// This creates a cursor from a static set of items
|
||||
return NewStaticCursor(ps), nil
|
||||
}
|
||||
|
||||
// Pair is a struct for key value pairs.
|
||||
type Pair struct {
|
||||
Key []byte
|
||||
Value []byte
|
||||
}
|
||||
|
||||
// ForEach loops over all bucket entries and applies fn to them.
|
||||
func (b *Bucket) ForEach(fn func(k, v []byte) error) error {
|
||||
pairs, err := b.getAll(string(b.prefix))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i := range pairs {
|
||||
err = fn(pairs[i].Key, pairs[i].Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NextSequence generates a universally unique uint64.
|
||||
//
|
||||
// todo: create thing that returns a universally unique uint64.
|
||||
func (b *Bucket) NextSequence() (uint64, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func (b *Bucket) getAll(prefix string) ([]Pair, error) {
|
||||
var startKey = prefix + "/"
|
||||
|
||||
kvOpts := []clientv3.OpOption{
|
||||
clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend),
|
||||
clientv3.WithPrefix(),
|
||||
}
|
||||
|
||||
r, err := b.tx.client.db.Get(context.TODO(), startKey, kvOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prefixBytes := []byte(startKey)
|
||||
|
||||
ps := []Pair{}
|
||||
for _, k := range r.Kvs {
|
||||
key := bytes.TrimPrefix(k.Key, prefixBytes)
|
||||
ps = append(ps, Pair{Key: key, Value: k.Value})
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
// ForwardCursor retrieves all keys from the bucket and creates a static cursor from them.
|
||||
func (b *Bucket) ForwardCursor(seek []byte) (kv.ForwardCursor, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
kvs, err := fetch(ctx, b.tx.client, string(b.prefix), seek)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cursor := &ForwardCursor{
|
||||
kvs: kvs,
|
||||
prefix: append(b.prefix, '/'),
|
||||
}
|
||||
|
||||
return cursor, nil
|
||||
}
|
||||
|
||||
// ForwardCursor is a directional cursor.
|
||||
// It has a single Next method for iteration which goes over a range response from etcd.
|
||||
type ForwardCursor struct {
|
||||
kvs []*mvccpb.KeyValue
|
||||
prefix []byte
|
||||
|
||||
n int
|
||||
closed bool
|
||||
}
|
||||
|
||||
// Next returns the next key/value pair in the cursor.
|
||||
func (f *ForwardCursor) Next() ([]byte, []byte) {
|
||||
if f.closed || f.n >= len(f.kvs) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kv := f.kvs[f.n]
|
||||
|
||||
f.n++
|
||||
|
||||
return bytes.TrimPrefix(kv.Key, f.prefix), kv.Value
|
||||
}
|
||||
|
||||
// Err returns nil as no errors can occur during iteration.
|
||||
func (f *ForwardCursor) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close marks the cursor as closed if it hasn't already been closed.
|
||||
func (f *ForwardCursor) Close() error {
|
||||
if f.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
f.closed = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetch(ctx context.Context, client *client, prefix string, seek []byte) ([]*mvccpb.KeyValue, error) {
|
||||
var (
|
||||
rnge = clientv3.WithFromKey()
|
||||
sort = clientv3.SortAscend
|
||||
startKey = prefix + "/" + string(seek)
|
||||
)
|
||||
|
||||
r, err := client.db.Get(ctx, startKey,
|
||||
clientv3.WithSort(clientv3.SortByKey, sort),
|
||||
rnge,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.Kvs, nil
|
||||
}
|
||||
|
||||
// staticCursor implements the Cursor interface for a slice of
|
||||
// static key value pairs.
|
||||
type staticCursor struct {
|
||||
idx int
|
||||
pairs []Pair
|
||||
}
|
||||
|
||||
// NewStaticCursor returns an instance of a StaticCursor. It
|
||||
// destructively sorts the provided pairs to be in key ascending order.
|
||||
func NewStaticCursor(pairs []Pair) kv.Cursor {
|
||||
sort.Slice(pairs, func(i, j int) bool {
|
||||
return bytes.Compare(pairs[i].Key, pairs[j].Key) < 0
|
||||
})
|
||||
return &staticCursor{
|
||||
pairs: pairs,
|
||||
}
|
||||
}
|
||||
|
||||
// Seek searches the slice for the first key with the provided prefix.
|
||||
func (c *staticCursor) Seek(prefix []byte) ([]byte, []byte) {
|
||||
// TODO: do binary search for prefix since pairs are ordered.
|
||||
for i, pair := range c.pairs {
|
||||
if bytes.HasPrefix(pair.Key, prefix) {
|
||||
c.idx = i
|
||||
return pair.Key, pair.Value
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *staticCursor) getValueAtIndex(delta int) ([]byte, []byte) {
|
||||
idx := c.idx + delta
|
||||
if idx < 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if idx >= len(c.pairs) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
c.idx = idx
|
||||
|
||||
pair := c.pairs[c.idx]
|
||||
|
||||
return pair.Key, pair.Value
|
||||
}
|
||||
|
||||
// First retrieves the first element in the cursor.
|
||||
func (c *staticCursor) First() ([]byte, []byte) {
|
||||
return c.getValueAtIndex(-c.idx)
|
||||
}
|
||||
|
||||
// Last retrieves the last element in the cursor.
|
||||
func (c *staticCursor) Last() ([]byte, []byte) {
|
||||
return c.getValueAtIndex(len(c.pairs) - 1 - c.idx)
|
||||
}
|
||||
|
||||
// Next retrieves the next entry in the cursor.
|
||||
func (c *staticCursor) Next() ([]byte, []byte) {
|
||||
return c.getValueAtIndex(1)
|
||||
}
|
||||
|
||||
// Prev retrieves the previous entry in the cursor.
|
||||
func (c *staticCursor) Prev() ([]byte, []byte) {
|
||||
return c.getValueAtIndex(-1)
|
||||
}
|
|
@ -39,8 +39,8 @@ func (s *organizationsStore) CreateDefault(ctx context.Context) error {
|
|||
|
||||
return s.client.kv.Update(ctx, func(tx Tx) error {
|
||||
b := tx.Bucket(organizationsBucket)
|
||||
v, err := b.Get(DefaultOrganizationID)
|
||||
if v != nil || err != nil {
|
||||
v, _ := b.Get(DefaultOrganizationID)
|
||||
if v != nil {
|
||||
return nil
|
||||
}
|
||||
if v, err := internal.MarshalOrganization(&o); err != nil {
|
||||
|
@ -49,20 +49,18 @@ func (s *organizationsStore) CreateDefault(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
m := chronograf.Mapping{
|
||||
ID: string(DefaultOrganizationID),
|
||||
Organization: string(DefaultOrganizationID),
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
ProviderOrganization: chronograf.MappingWildcard,
|
||||
}
|
||||
|
||||
b = tx.Bucket(mappingsBucket)
|
||||
v, _ = b.Get(DefaultOrganizationID)
|
||||
if v != nil {
|
||||
return nil
|
||||
}
|
||||
if v, err := internal.MarshalMapping(&m); err != nil {
|
||||
if v, err := internal.MarshalMapping(&chronograf.Mapping{
|
||||
ID: string(DefaultOrganizationID),
|
||||
Organization: string(DefaultOrganizationID),
|
||||
Provider: chronograf.MappingWildcard,
|
||||
Scheme: chronograf.MappingWildcard,
|
||||
ProviderOrganization: chronograf.MappingWildcard,
|
||||
}); err != nil {
|
||||
return err
|
||||
} else if err := b.Put(DefaultOrganizationID, v); err != nil {
|
||||
return err
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/influxdata/chronograf"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Level type
|
||||
|
|
|
@ -342,6 +342,7 @@ func NewMux(opts MuxOpts, service Service) http.Handler {
|
|||
// Validates go templates for the js client
|
||||
router.POST("/chronograf/v1/validate_text_templates", EnsureViewer(service.ValidateTextTemplate))
|
||||
|
||||
// todo(glinton): remove cell/dashboardv2 stuff as these aren't actually integrated anywhere.
|
||||
/// V2 Cells
|
||||
router.GET("/chronograf/v2/cells", EnsureViewer(service.CellsV2))
|
||||
router.POST("/chronograf/v2/cells", EnsureEditor(service.NewCellV2))
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/influxdata/chronograf/influx"
|
||||
"github.com/influxdata/chronograf/kv"
|
||||
"github.com/influxdata/chronograf/kv/bolt"
|
||||
"github.com/influxdata/chronograf/kv/etcd"
|
||||
clog "github.com/influxdata/chronograf/log"
|
||||
"github.com/influxdata/chronograf/oauth2"
|
||||
client "github.com/influxdata/usage-client/v1"
|
||||
|
@ -69,9 +70,11 @@ type Server struct {
|
|||
GithubClientSecret string `short:"s" long:"github-client-secret" description:"Github Client Secret for OAuth 2 support" env:"GH_CLIENT_SECRET"`
|
||||
GithubOrgs []string `short:"o" long:"github-organization" description:"Github organization user is required to have active membership" env:"GH_ORGS" env-delim:","`
|
||||
|
||||
// EtcdUsername string `short:"i" long:"github-client-id" description:"Github Client ID for OAuth 2 support" env:"GH_CLIENT_ID"`
|
||||
// EtcdPassword string `short:"s" long:"github-client-secret" description:"Github Client Secret for OAuth 2 support" env:"GH_CLIENT_SECRET"`
|
||||
// EtcdEndpoints []string `short:"o" long:"github-organization" description:"Github organization user is required to have active membership" env:"GH_ORGS" env-delim:","`
|
||||
EtcdEndpoints []string `short:"e" long:"etcd-endpoints" description:"List of etcd endpoints" env:"ETCD_HOSTS" env-delim:","`
|
||||
EtcdUsername string `long:"etcd-username" description:"Username to log into etcd." env:"ETCD_USERNAME"`
|
||||
EtcdPassword string `long:"etcd-password" description:"Password to log into etcd." env:"ETCD_PASSWORD"`
|
||||
EtcdDialTimeout time.Duration `long:"etcd-dial-timeout" default:"-1s" description:"Total time to wait before timing out while connecting to etcd endpoints. 0 means no timeout. " env:"ETCD_DIAL_TIMEOUT"`
|
||||
EtcdRequestTimeout time.Duration `long:"etcd-request-timeout" default:"-1s" description:"Total time to wait before timing out the etcd view or update. 0 means no timeout." env:"ETCD_REQUEST_TIMEOUT"`
|
||||
|
||||
GoogleClientID string `long:"google-client-id" description:"Google Client ID for OAuth 2 support" env:"GOOGLE_CLIENT_ID"`
|
||||
GoogleClientSecret string `long:"google-client-secret" description:"Google Client Secret for OAuth 2 support" env:"GOOGLE_CLIENT_SECRET"`
|
||||
|
@ -340,7 +343,34 @@ func (s *Server) Serve(ctx context.Context) {
|
|||
Error(err)
|
||||
return
|
||||
}
|
||||
service := openService(ctx, s.BuildInfo, s.BoltPath, s.newBuilders(logger), logger, s.useAuth())
|
||||
|
||||
var db kv.Store
|
||||
if len(s.EtcdEndpoints) == 0 {
|
||||
db, err = bolt.NewClient(ctx,
|
||||
bolt.WithPath(s.BoltPath),
|
||||
bolt.WithLogger(logger),
|
||||
bolt.WithBuildInfo(s.BuildInfo),
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("Unable to create bolt client", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
} else {
|
||||
db, err = etcd.NewClient(ctx,
|
||||
etcd.WithEndpoints(s.EtcdEndpoints),
|
||||
etcd.WithLogin(s.EtcdUsername, s.EtcdPassword),
|
||||
etcd.WithRequestTimeout(s.EtcdRequestTimeout),
|
||||
etcd.WithDialTimeout(s.EtcdDialTimeout),
|
||||
etcd.WithLogger(logger),
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("Unable to create etcd client", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
service := openService(ctx, db, s.newBuilders(logger), logger, s.useAuth())
|
||||
service.SuperAdminProviderGroups = superAdminProviderGroups{
|
||||
auth0: s.Auth0SuperAdminOrg,
|
||||
}
|
||||
|
@ -433,19 +463,7 @@ func (s *Server) Serve(ctx context.Context) {
|
|||
Info("Stopped serving chronograf at ", scheme, "://", listener.Addr())
|
||||
}
|
||||
|
||||
// todo: add etcd connection details as arg.
|
||||
// todo: return error. make chronograf error type that has fields and error. .Error() will logger.Error print it.
|
||||
func openService(ctx context.Context, buildInfo chronograf.BuildInfo, boltPath string, builder builders, logger chronograf.Logger, useAuth bool) Service {
|
||||
db, err := bolt.NewClient(ctx,
|
||||
bolt.WithPath(boltPath),
|
||||
bolt.WithLogger(logger),
|
||||
bolt.WithBuildInfo(buildInfo),
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error("Unable to create bolt client", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func openService(ctx context.Context, db kv.Store, builder builders, logger chronograf.Logger, useAuth bool) Service {
|
||||
svc, err := kv.NewService(ctx, db, kv.WithLogger(logger))
|
||||
if err != nil {
|
||||
logger.Error("Unable to create kv service", err)
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// todo: remove as cellv2 stuff is not used.
|
||||
|
||||
// ErrCellNotFound is the error for a missing cell.
|
||||
const ErrCellNotFound = Error("cell not found")
|
||||
|
||||
|
|
Loading…
Reference in New Issue