feat(vault): add vault implementation of secret service

test(platform): run testcontainer integration tests for nightly release

Integration tests for the vault secret service using testcontiners
should not run along with unit tests, however, they should run on some
regular schedule. This commit introduces `make test-integration` which
runs integration tests for vault using testcontainers. The command introduced
relies on docker being available on the host it is executed on.

chore(platform): make go modules tidy

chore: try to fix go mod

chore(platform): remove explicit logrus dependency

chore(platform): run go mod tidy

chore(platform): replace github.com/Sirupsen/logrus with github.com/sirupsen/logrus

chore(platform): update docker dependency

feat(vault): add vault implementation of secret service

test(platform): run testcontainer integration tests for nightly release

Integration tests for the vault secret service using testcontiners
should not run along with unit tests, however, they should run on some
regular schedule. This commit introduces `make test-integration` which
runs integration tests for vault using testcontainers. The command introduced
relies on docker being available on the host it is executed on.

chore(platform): make go modules tidy

chore: try to fix go mod

chore(platform): run go mod tidy

feat(vault): add vault implementation of secret service

chore(platform): make go modules tidy

feat(platform): add Put/Patch/Delete methods on secret service

feat(vault): add Put/Patch/Delete methods on vault secret service

feat(http): add http handler methods for secret service

feat(bolt): add Put/Delete/Patch methods to bolt secret service

feat(testing): add tests for Put/Patch/Delete methods in secret service

feat(mock): add mock secret service

feat(http): add tests for secrets endpoints

feat(http): update swagger for secrets endpoints

chore: run go mod tidy
pull/10616/head
Michael Desa 2018-11-16 11:45:00 -05:00
parent b0fc331c6d
commit 56de056085
39 changed files with 1587 additions and 310 deletions

View File

@ -100,6 +100,7 @@ jobs:
- chronograf-yarn-packages-{{ checksum "ui/yarn.lock" }}
- setup_remote_docker
- run: make test-integration
- run: |
docker login -u "$QUAY_USER" -p $QUAY_PASS quay.io
make nightly

View File

@ -113,6 +113,10 @@ test-js: node_modules
test-go:
$(GO_TEST) ./...
test-integration: GO_TAGS=integration
test-integration:
$(GO_TEST) -count=1 ./...
test: test-go test-js
test-go-race:

View File

@ -190,3 +190,58 @@ func encodeSecretValue(v string) []byte {
base64.StdEncoding.Encode(val, []byte(v))
return val
}
// PutSecrets puts all provided secrets and overwrites any previous values.
func (c *Client) PutSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
return c.db.Update(func(tx *bolt.Tx) error {
keys, err := c.getSecretKeys(ctx, tx, orgID)
if err != nil {
return err
}
for k, v := range m {
if err := c.putSecret(ctx, tx, orgID, k, v); err != nil {
return err
}
}
for _, k := range keys {
if _, ok := m[k]; !ok {
if err := c.deleteSecret(ctx, tx, orgID, k); err != nil {
return err
}
}
}
return nil
})
}
// PatchSecrets patches all provided secrets and updates any previous values.
func (c *Client) PatchSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
return c.db.Update(func(tx *bolt.Tx) error {
for k, v := range m {
if err := c.putSecret(ctx, tx, orgID, k, v); err != nil {
return err
}
}
return nil
})
}
// DeleteSecret removes secrets from the secret store.
func (c *Client) DeleteSecret(ctx context.Context, orgID platform.ID, ks ...string) error {
return c.db.Update(func(tx *bolt.Tx) error {
for _, k := range ks {
if err := c.deleteSecret(ctx, tx, orgID, k); err != nil {
return err
}
}
return nil
})
}
func (c *Client) deleteSecret(ctx context.Context, tx *bolt.Tx, orgID platform.ID, k string) error {
key, err := encodeSecretKey(orgID, k)
if err != nil {
return err
}
return tx.Bucket(secretBucket).Delete(key)
}

View File

@ -10,7 +10,6 @@ import (
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/enterprise"
"github.com/influxdata/platform/chronograf/influx"
"github.com/influxdata/platform/chronograf/log"
)
func Test_Enterprise_FetchesDataNodes(t *testing.T) {
@ -54,7 +53,7 @@ func Test_Enterprise_IssuesQueries(t *testing.T) {
cl := &enterprise.Client{
Ctrl: NewMockControlClient(ts.URL),
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
err := cl.Connect(context.Background(), &chronograf.Source{})
@ -77,7 +76,7 @@ func Test_Enterprise_AdvancesDataNodes(t *testing.T) {
m1 := NewMockTimeSeries("http://host-1.example.com:8086")
m2 := NewMockTimeSeries("http://host-2.example.com:8086")
cl, err := enterprise.NewClientWithTimeSeries(
log.New(log.DebugLevel),
&chronograf.NoopLogger{},
"http://meta.example.com:8091",
&influx.BasicAuth{
Username: "marty",
@ -173,7 +172,7 @@ func Test_Enterprise_NewClientWithURL(t *testing.T) {
},
testURL.tls,
testURL.insecureSkipVerify,
log.New(log.DebugLevel))
&chronograf.NoopLogger{})
if err != nil && !testURL.wantErr {
t.Errorf("Unexpected error creating Client with URL %s and TLS preference %t. err: %s", testURL.url, testURL.tls, err.Error())
} else if err == nil && testURL.wantErr {
@ -185,7 +184,7 @@ func Test_Enterprise_NewClientWithURL(t *testing.T) {
func Test_Enterprise_ComplainsIfNotOpened(t *testing.T) {
m1 := NewMockTimeSeries("http://host-1.example.com:8086")
cl, err := enterprise.NewClientWithTimeSeries(
log.New(log.DebugLevel),
&chronograf.NoopLogger{},
"http://meta.example.com:8091",
&influx.BasicAuth{
Username: "docbrown",

View File

@ -14,7 +14,6 @@ import (
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/filestore"
clog "github.com/influxdata/platform/chronograf/log"
)
func TestAll(t *testing.T) {
@ -374,6 +373,6 @@ func MockApps(existing []chronograf.Layout, expected error) (filestore.Apps, *ma
IDs: &MockID{
id: len(existing),
},
Logger: clog.New(clog.ParseLevel("debug")),
Logger: &chronograf.NoopLogger{},
}, &layouts
}

View File

@ -13,7 +13,6 @@ import (
gojwt "github.com/dgrijalva/jwt-go"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/influx"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
)
@ -45,7 +44,7 @@ func Test_Influx_MakesRequestsToQueryEndpoint(t *testing.T) {
defer ts.Close()
var series chronograf.TimeSeries
series, err := NewClient(ts.URL, log.New(log.DebugLevel))
series, err := NewClient(ts.URL, &chronograf.NoopLogger{})
if err != nil {
t.Fatal("Unexpected error initializing client: err:", err)
}
@ -106,7 +105,7 @@ func Test_Influx_AuthorizationBearer(t *testing.T) {
SharedSecret: "42",
}
series := &influx.Client{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
series.Connect(context.Background(), src)
@ -155,7 +154,7 @@ func Test_Influx_AuthorizationBearerCtx(t *testing.T) {
defer ts.Close()
series := &influx.Client{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
err := series.Connect(context.Background(), &chronograf.Source{
@ -188,7 +187,7 @@ func Test_Influx_AuthorizationBearerFailure(t *testing.T) {
series := &influx.Client{
URL: u,
Authorizer: bearer,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
query := chronograf.Query{
@ -209,7 +208,7 @@ func Test_Influx_HTTPS_Failure(t *testing.T) {
ctx := context.Background()
var series chronograf.TimeSeries
series, err := NewClient(ts.URL, log.New(log.DebugLevel))
series, err := NewClient(ts.URL, &chronograf.NoopLogger{})
if err != nil {
t.Fatal("Unexpected error initializing client: err:", err)
}
@ -252,7 +251,7 @@ func Test_Influx_HTTPS_InsecureSkipVerify(t *testing.T) {
ctx := context.Background()
var series chronograf.TimeSeries
series, err := NewClient(ts.URL, log.New(log.DebugLevel))
series, err := NewClient(ts.URL, &chronograf.NoopLogger{})
if err != nil {
t.Fatal("Unexpected error initializing client: err:", err)
}
@ -310,7 +309,7 @@ func Test_Influx_CancelsInFlightRequests(t *testing.T) {
ts.Close()
}()
series, _ := NewClient(ts.URL, log.New(log.DebugLevel))
series, _ := NewClient(ts.URL, &chronograf.NoopLogger{})
ctx, cancel := context.WithCancel(context.Background())
errs := make(chan (error))
@ -353,7 +352,7 @@ func Test_Influx_CancelsInFlightRequests(t *testing.T) {
}
func Test_Influx_RejectsInvalidHosts(t *testing.T) {
_, err := NewClient(":", log.New(log.DebugLevel))
_, err := NewClient(":", &chronograf.NoopLogger{})
if err == nil {
t.Fatal("Expected err but was nil")
}
@ -365,7 +364,7 @@ func Test_Influx_ReportsInfluxErrs(t *testing.T) {
}))
defer ts.Close()
cl, err := NewClient(ts.URL, log.New(log.DebugLevel))
cl, err := NewClient(ts.URL, &chronograf.NoopLogger{})
if err != nil {
t.Fatal("Encountered unexpected error while initializing influx client: err:", err)
}

View File

@ -10,7 +10,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
)
func TestClient_userPermissions(t *testing.T) {
@ -75,7 +74,7 @@ func TestClient_userPermissions(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
@ -194,7 +193,7 @@ func TestClient_Add(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
got, err := c.Add(tt.args.ctx, tt.args.u)
@ -289,7 +288,7 @@ func TestClient_Delete(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
@ -389,7 +388,7 @@ func TestClient_Get(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
got, err := c.Get(tt.args.ctx, chronograf.UserQuery{Name: &tt.args.name})
@ -476,7 +475,7 @@ func TestClient_grantPermission(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
if err := c.grantPermission(tt.args.ctx, tt.args.username, tt.args.perm); (err != nil) != tt.wantErr {
@ -561,7 +560,7 @@ func TestClient_revokePermission(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
if err := c.revokePermission(tt.args.ctx, tt.args.username, tt.args.perm); (err != nil) != tt.wantErr {
@ -655,7 +654,7 @@ func TestClient_Num(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
got, err := c.Num(tt.args.ctx)
@ -771,7 +770,7 @@ func TestClient_All(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
got, err := c.All(tt.args.ctx)
@ -1108,7 +1107,7 @@ func TestClient_Update(t *testing.T) {
u, _ := url.Parse(ts.URL)
c := &Client{
URL: u,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
defer ts.Close()
if err := c.Update(tt.args.ctx, tt.args.u); (err != nil) != tt.wantErr {

View File

@ -17,7 +17,6 @@ import (
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/bolt"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/oauth2"
"github.com/influxdata/platform/chronograf/server"
)
@ -3567,7 +3566,7 @@ func TestServer(t *testing.T) {
boltdb := bolt.NewClient()
boltdb.Path = boltFile
logger := log.New(log.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
build := chronograf.BuildInfo{
Version: "pre-1.4.0.0",
Commit: "",

View File

@ -1,101 +0,0 @@
package log
import (
"io"
"os"
"github.com/influxdata/platform/chronograf"
"github.com/sirupsen/logrus"
)
// Level type
type Level uint8
// These are the different logging levels.
const (
// PanicLevel level, highest level of severity. Logs and then calls panic with the
// message passed to Debug, Info, ...
PanicLevel Level = iota
// FatalLevel level. Logs and then calls `os.Exit(1)`. It will exit even if the
// logging level is set to Panic.
FatalLevel
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
// Commonly used for hooks to send errors to an error tracking service.
ErrorLevel
// WarnLevel level. Non-critical entries that deserve eyes.
WarnLevel
// InfoLevel level. General operational entries about what's going on inside the
// application.
InfoLevel
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
DebugLevel
)
// ParseLevel takes a string level and returns the Logrus log level constant.
func ParseLevel(lvl string) Level {
switch lvl {
case "panic":
return PanicLevel
case "fatal":
return FatalLevel
case "error":
return ErrorLevel
case "warn":
return WarnLevel
case "info":
return InfoLevel
default:
return DebugLevel
}
}
// LogrusLogger is a chronograf.Logger that uses logrus to process logs
type logrusLogger struct {
l *logrus.Entry
}
func (ll *logrusLogger) Debug(items ...interface{}) {
ll.l.Debug(items...)
}
func (ll *logrusLogger) Info(items ...interface{}) {
ll.l.Info(items...)
}
func (ll *logrusLogger) Warn(items ...interface{}) {
ll.l.Warn(items...)
}
func (ll *logrusLogger) Error(items ...interface{}) {
ll.l.Error(items...)
}
func (ll *logrusLogger) Fatal(items ...interface{}) {
ll.l.Fatal(items...)
}
func (ll *logrusLogger) Panic(items ...interface{}) {
ll.l.Panic(items...)
}
func (ll *logrusLogger) WithField(key string, value interface{}) chronograf.Logger {
return &logrusLogger{ll.l.WithField(key, value)}
}
func (ll *logrusLogger) Writer() *io.PipeWriter {
return ll.l.Logger.WriterLevel(logrus.ErrorLevel)
}
// New wraps a logrus Logger
func New(l Level) chronograf.Logger {
logger := &logrus.Logger{
Out: os.Stderr,
Formatter: new(logrus.TextFormatter),
Hooks: make(logrus.LevelHooks),
Level: logrus.Level(l),
}
return &logrusLogger{
l: logrus.NewEntry(logger),
}
}

View File

@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -94,7 +94,7 @@ func Test_Auth0_PrincipalID_RestrictsByOrganization(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov, err := oauth2.NewAuth0(mockAPI.URL, "id", "secret", mockAPI.URL+"/callback", test.allowedOrgs, logger)
if err != nil {
tt.Fatal("Unexpected error instantiating Auth0 provider: err:", err)
@ -131,7 +131,7 @@ func Test_Auth0_PrincipalID_RestrictsByOrganization(t *testing.T) {
func Test_Auth0_ErrsWithBadDomain(t *testing.T) {
t.Parallel()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
_, err := oauth2.NewAuth0("!!@#$!@$%@#$%", "id", "secret", "http://example.com", []string{}, logger)
if err == nil {
t.Fatal("Expected err with bad domain but received none")

View File

@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -30,7 +30,7 @@ func TestGenericGroup_withNotEmail(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Generic{
Logger: logger,
APIURL: mockAPI.URL,
@ -76,7 +76,7 @@ func TestGenericGroup_withEmail(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Generic{
Logger: logger,
APIURL: mockAPI.URL,
@ -122,7 +122,7 @@ func TestGenericPrincipalID(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Generic{
Logger: logger,
APIURL: mockAPI.URL,
@ -175,7 +175,7 @@ func TestGenericPrincipalIDDomain(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Generic{
Logger: logger,
Domains: []string{"pinheads.rok"},

View File

@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -34,7 +34,7 @@ func TestGithubPrincipalID(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Github{
Logger: logger,
}
@ -90,7 +90,7 @@ func TestGithubPrincipalIDOrganization(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Github{
Logger: logger,
Orgs: []string{"Hill Valley Preservation Society"},

View File

@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -30,7 +30,7 @@ func TestGooglePrincipalID(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Google{
Logger: logger,
}
@ -75,7 +75,7 @@ func TestGooglePrincipalIDDomain(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Google{
Logger: logger,
Domains: []string{"Hill Valley Preservation Society"},

View File

@ -6,7 +6,7 @@ import (
"net/http/httptest"
"testing"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -31,7 +31,7 @@ func Test_Heroku_PrincipalID_ExtractsEmailAddress(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Heroku{
Logger: logger,
}
@ -80,7 +80,7 @@ func Test_Heroku_PrincipalID_RestrictsByOrganization(t *testing.T) {
}))
defer mockAPI.Close()
logger := clog.New(clog.ParseLevel("debug"))
logger := &chronograf.NoopLogger{}
prov := oauth2.Heroku{
Logger: logger,
Organizations: []string{"enchantment-under-the-sea-dance-committee"},

View File

@ -9,7 +9,7 @@ import (
"testing"
"time"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
)
var testTime = time.Date(1985, time.October, 25, 18, 0, 0, 0, time.UTC)
@ -53,7 +53,7 @@ func setupMuxTest(response interface{}, selector func(*AuthMux) http.Handler) (*
useidtoken := false
jm := NewAuthMux(mp, auth, mt, "", clog.New(clog.ParseLevel("debug")), useidtoken)
jm := NewAuthMux(mp, auth, mt, "", &chronograf.NoopLogger{}, useidtoken)
ts := httptest.NewServer(selector(jm))
jar, _ := cookiejar.New(nil)
hc := http.Client{

View File

@ -9,7 +9,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/oauth2"
"github.com/influxdata/platform/chronograf/roles"
@ -53,7 +52,7 @@ func TestAuthorizedToken(t *testing.T) {
ValidateErr: test.ValidateErr,
}
logger := clog.New(clog.DebugLevel)
logger := &chronograf.NoopLogger{}
handler := AuthorizedToken(a, logger, next)
handler.ServeHTTP(w, req)
if w.Code != test.Code {
@ -96,7 +95,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
useAuth: false,
@ -145,7 +144,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -201,7 +200,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -257,7 +256,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -313,7 +312,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -369,7 +368,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -425,7 +424,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -481,7 +480,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -537,7 +536,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -589,7 +588,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -645,7 +644,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -701,7 +700,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -753,7 +752,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -805,7 +804,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -856,7 +855,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -903,7 +902,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -950,7 +949,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1001,7 +1000,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1052,7 +1051,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1103,7 +1102,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1155,7 +1154,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1207,7 +1206,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1259,7 +1258,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1312,7 +1311,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1369,7 +1368,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1426,7 +1425,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1483,7 +1482,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1539,7 +1538,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: nil,
@ -1587,7 +1586,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1638,7 +1637,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1695,7 +1694,7 @@ func TestAuthorizedUser(t *testing.T) {
}
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1752,7 +1751,7 @@ func TestAuthorizedUser(t *testing.T) {
}, nil
},
},
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
principal: &oauth2.Principal{
@ -1857,7 +1856,7 @@ func TestRawStoreAccess(t *testing.T) {
{
name: "middleware already has server context",
fields: fields{
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
serverContext: true,
@ -1870,7 +1869,7 @@ func TestRawStoreAccess(t *testing.T) {
{
name: "user on context is a SuperAdmin",
fields: fields{
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
user: &chronograf.User{
@ -1885,7 +1884,7 @@ func TestRawStoreAccess(t *testing.T) {
{
name: "user on context is a not SuperAdmin",
fields: fields{
Logger: clog.New(clog.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
args: args{
user: &chronograf.User{

View File

@ -8,7 +8,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
)
@ -52,7 +51,7 @@ func TestConfig(t *testing.T) {
Store: &mocks.Store{
ConfigStore: tt.fields.ConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -117,7 +116,7 @@ func TestAuthConfig(t *testing.T) {
Store: &mocks.Store{
ConfigStore: tt.fields.ConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -191,7 +190,7 @@ func TestReplaceAuthConfig(t *testing.T) {
Store: &mocks.Store{
ConfigStore: tt.fields.ConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()

View File

@ -9,7 +9,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/julienschmidt/httprouter"
)
@ -547,7 +546,7 @@ func TestService_Measurements(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
logger := log.New(log.DebugLevel)
logger := &chronograf.NoopLogger{}
h := &Service{
Store: &mocks.Store{
SourcesStore: tt.fields.SourcesStore,

View File

@ -7,7 +7,6 @@ import (
"time"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
)
func TestEnvironment(t *testing.T) {
@ -44,7 +43,7 @@ func TestEnvironment(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
Env: tt.fields.Environment,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()

View File

@ -10,7 +10,6 @@ import (
"github.com/bouk/httprouter"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/roles"
)
@ -60,7 +59,7 @@ func TestMappings_All(t *testing.T) {
Store: &mocks.Store{
MappingsStore: tt.fields.MappingsStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -146,7 +145,7 @@ func TestMappings_Add(t *testing.T) {
MappingsStore: tt.fields.MappingsStore,
OrganizationsStore: tt.fields.OrganizationsStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -236,7 +235,7 @@ func TestMappings_Update(t *testing.T) {
MappingsStore: tt.fields.MappingsStore,
OrganizationsStore: tt.fields.OrganizationsStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -322,7 +321,7 @@ func TestMappings_Remove(t *testing.T) {
Store: &mocks.Store{
MappingsStore: tt.fields.MappingsStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()

View File

@ -11,7 +11,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/oauth2"
"github.com/influxdata/platform/chronograf/roles"
@ -48,7 +47,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -129,7 +128,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
MappingsStore: &mocks.MappingsStore{
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
return []chronograf.Mapping{}, nil
@ -197,7 +196,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
MappingsStore: &mocks.MappingsStore{
AllF: func(ctx context.Context) ([]chronograf.Mapping, error) {
return []chronograf.Mapping{}, nil
@ -256,7 +255,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -336,7 +335,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -416,7 +415,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -546,7 +545,7 @@ func TestService_Me(t *testing.T) {
return nil
},
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
principal: oauth2.Principal{
Subject: "secret",
@ -571,7 +570,7 @@ func TestService_Me(t *testing.T) {
},
},
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
wantStatus: http.StatusOK,
wantContentType: "application/json",
@ -592,7 +591,7 @@ func TestService_Me(t *testing.T) {
},
},
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
wantStatus: http.StatusUnprocessableEntity,
principal: oauth2.Principal{
@ -608,7 +607,7 @@ func TestService_Me(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -668,7 +667,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -736,7 +735,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -804,7 +803,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -879,7 +878,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -954,7 +953,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{},
},
@ -1035,7 +1034,7 @@ func TestService_Me(t *testing.T) {
SuperAdminProviderGroups: superAdminProviderGroups{
auth0: "example",
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: mocks.ConfigStore{
Config: &chronograf.Config{},
},
@ -1176,7 +1175,7 @@ func TestService_UpdateMe(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
@ -1247,7 +1246,7 @@ func TestService_UpdateMe(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
@ -1319,7 +1318,7 @@ func TestService_UpdateMe(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
if q.Name == nil || q.Provider == nil || q.Scheme == nil {
@ -1379,7 +1378,7 @@ func TestService_UpdateMe(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
if q.Name == nil || q.Provider == nil || q.Scheme == nil {

View File

@ -8,7 +8,6 @@ import (
"github.com/bouk/httprouter"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/oauth2"
)
@ -35,7 +34,7 @@ func TestRouteMatchesPrincipal(t *testing.T) {
{
name: "route matches request params",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
return &chronograf.Organization{
@ -65,7 +64,7 @@ func TestRouteMatchesPrincipal(t *testing.T) {
{
name: "route does not match request params",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
return &chronograf.Organization{
@ -95,7 +94,7 @@ func TestRouteMatchesPrincipal(t *testing.T) {
{
name: "missing principal",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
return &chronograf.Organization{
@ -121,7 +120,7 @@ func TestRouteMatchesPrincipal(t *testing.T) {
{
name: "not using auth",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
DefaultOrganizationF: func(ctx context.Context) (*chronograf.Organization, error) {
return &chronograf.Organization{

View File

@ -9,7 +9,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/organizations"
)
@ -171,7 +170,7 @@ func TestOrganizationConfig(t *testing.T) {
Store: &mocks.Store{
OrganizationConfigStore: tt.fields.organizationConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -273,7 +272,7 @@ func TestLogViewerOrganizationConfig(t *testing.T) {
Store: &mocks.Store{
OrganizationConfigStore: tt.fields.organizationConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()
@ -673,7 +672,7 @@ func TestReplaceLogViewerOrganizationConfig(t *testing.T) {
Store: &mocks.Store{
OrganizationConfigStore: tt.fields.organizationConfigStore,
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
}
w := httptest.NewRecorder()

View File

@ -12,7 +12,6 @@ import (
"github.com/bouk/httprouter"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/roles"
)
@ -46,7 +45,7 @@ func TestService_OrganizationID(t *testing.T) {
),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -77,7 +76,7 @@ func TestService_OrganizationID(t *testing.T) {
),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -164,7 +163,7 @@ func TestService_Organizations(t *testing.T) {
),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
AllF: func(ctx context.Context) ([]chronograf.Organization, error) {
return []chronograf.Organization{
@ -247,7 +246,7 @@ func TestService_UpdateOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -278,7 +277,7 @@ func TestService_UpdateOrganization(t *testing.T) {
org: &organizationRequest{},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -311,7 +310,7 @@ func TestService_UpdateOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -342,7 +341,7 @@ func TestService_UpdateOrganization(t *testing.T) {
org: &organizationRequest{},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -371,7 +370,7 @@ func TestService_UpdateOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
UpdateF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -453,7 +452,7 @@ func TestService_RemoveOrganization(t *testing.T) {
),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
DeleteF: func(ctx context.Context, o *chronograf.Organization) error {
return nil
@ -543,7 +542,7 @@ func TestService_NewOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
return &chronograf.User{
@ -585,7 +584,7 @@ func TestService_NewOrganization(t *testing.T) {
org: &organizationRequest{},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
return &chronograf.User{
@ -620,7 +619,7 @@ func TestService_NewOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
return &chronograf.User{
@ -667,7 +666,7 @@ func TestService_NewOrganization(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AddF: func(ctx context.Context, u *chronograf.User) (*chronograf.User, error) {
return nil, fmt.Errorf("failed to add user to org")

View File

@ -9,7 +9,6 @@ import (
"testing"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/julienschmidt/httprouter"
)
@ -46,7 +45,7 @@ func TestService_Permissions(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{

View File

@ -6,11 +6,11 @@ import (
"net/http/httptest"
"testing"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf"
)
func TestAllRoutes(t *testing.T) {
logger := log.New(log.DebugLevel)
logger := &chronograf.NoopLogger{}
handler := &AllRoutes{
Logger: logger,
}
@ -43,7 +43,7 @@ func TestAllRoutes(t *testing.T) {
}
func TestAllRoutesWithAuth(t *testing.T) {
logger := log.New(log.DebugLevel)
logger := &chronograf.NoopLogger{}
handler := &AllRoutes{
AuthRoutes: []AuthRoute{
{
@ -88,7 +88,7 @@ func TestAllRoutesWithExternalLinks(t *testing.T) {
customLinks := map[string]string{
"cubeapple": "https://cube.apple",
}
logger := log.New(log.DebugLevel)
logger := &chronograf.NoopLogger{}
handler := &AllRoutes{
StatusFeed: statusFeedURL,
CustomLinks: customLinks,

View File

@ -21,7 +21,6 @@ import (
"github.com/influxdata/platform/chronograf/bolt"
idgen "github.com/influxdata/platform/chronograf/id"
"github.com/influxdata/platform/chronograf/influx"
clog "github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/oauth2"
client "github.com/influxdata/usage-client/v1"
flags "github.com/jessevdk/go-flags"
@ -323,7 +322,7 @@ func (s *Server) newBuilders(logger chronograf.Logger) builders {
// Serve starts and runs the chronograf server
func (s *Server) Serve(ctx context.Context) error {
logger := clog.New(clog.ParseLevel(s.LogLevel))
logger := &chronograf.NoopLogger{}
_, err := NewCustomLinks(s.CustomLinks)
if err != nil {
logger.

View File

@ -12,7 +12,6 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/julienschmidt/httprouter"
)
@ -439,7 +438,7 @@ func TestService_SourcesID(t *testing.T) {
}, nil
},
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "1",
wantStatusCode: 200,
@ -529,7 +528,7 @@ func TestService_UpdateSource(t *testing.T) {
}, nil
},
},
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "1",
wantStatusCode: 200,
@ -619,7 +618,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -665,7 +664,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -711,7 +710,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -753,7 +752,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -788,7 +787,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{}, fmt.Errorf("no McFly ever amounted to anything in the history of Hill Valley")
@ -812,7 +811,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "BAD",
wantStatus: http.StatusUnprocessableEntity,
@ -831,7 +830,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "BAD",
wantStatus: http.StatusUnprocessableEntity,
@ -850,7 +849,7 @@ func TestService_NewSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "BAD",
wantStatus: http.StatusBadRequest,
@ -927,7 +926,7 @@ func TestService_SourceUsers(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -983,7 +982,7 @@ func TestService_SourceUsers(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1097,7 +1096,7 @@ func TestService_SourceUserID(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1152,7 +1151,7 @@ func TestService_SourceUserID(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1265,7 +1264,7 @@ func TestService_RemoveSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1363,7 +1362,7 @@ func TestService_UpdateSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1415,7 +1414,7 @@ func TestService_UpdateSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1467,7 +1466,7 @@ func TestService_UpdateSourceUser(t *testing.T) {
},
fields: fields{
UseAuth: true,
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "1",
UID: "marty",
@ -1541,7 +1540,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{BAD}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
wantStatus: http.StatusBadRequest,
wantContentType: "application/json",
@ -1558,7 +1557,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": ""}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "1",
wantStatus: http.StatusUnprocessableEntity,
@ -1576,7 +1575,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": "newrole"}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
},
ID: "BADROLE",
wantStatus: http.StatusUnprocessableEntity,
@ -1594,7 +1593,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": "role"}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1631,7 +1630,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": "role"}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1675,7 +1674,7 @@ func TestService_NewSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": "biffsgang","users": [{"name": "match"},{"name": "skinhead"},{"name": "3-d"}]}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1777,7 +1776,7 @@ func TestService_UpdateSourceRole(t *testing.T) {
bytes.NewReader([]byte(`{"name": "biffsgang","users": [{"name": "match"},{"name": "skinhead"},{"name": "3-d"}]}`)))),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -1893,7 +1892,7 @@ func TestService_SourceRoleID(t *testing.T) {
nil),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -2013,7 +2012,7 @@ func TestService_RemoveSourceRole(t *testing.T) {
nil),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{
@ -2101,7 +2100,7 @@ func TestService_SourceRoles(t *testing.T) {
nil),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
SourcesStore: &mocks.SourcesStore{
GetF: func(ctx context.Context, ID int) (chronograf.Source, error) {
return chronograf.Source{

View File

@ -12,7 +12,6 @@ import (
"github.com/bouk/httprouter"
"github.com/influxdata/platform/chronograf"
"github.com/influxdata/platform/chronograf/log"
"github.com/influxdata/platform/chronograf/mocks"
"github.com/influxdata/platform/chronograf/roles"
)
@ -46,7 +45,7 @@ func TestService_UserID(t *testing.T) {
),
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
switch *q.ID {
@ -147,7 +146,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -197,7 +196,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -275,7 +274,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -332,7 +331,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -380,7 +379,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -428,7 +427,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -473,7 +472,7 @@ func TestService_NewUser(t *testing.T) {
},
},
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
ConfigStore: &mocks.ConfigStore{
Config: &chronograf.Config{
Auth: chronograf.AuthConfig{
@ -588,7 +587,7 @@ func TestService_RemoveUser(t *testing.T) {
{
name: "Delete a Chronograf User",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
switch *q.ID {
@ -628,7 +627,7 @@ func TestService_RemoveUser(t *testing.T) {
{
name: "Deleting yourself",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
GetF: func(ctx context.Context, q chronograf.UserQuery) (*chronograf.User, error) {
switch *q.ID {
@ -734,7 +733,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user - no roles",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
UpdateF: func(ctx context.Context, user *chronograf.User) error {
return nil
@ -787,7 +786,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -858,7 +857,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user roles different orgs",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -936,7 +935,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user roles same org",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
UpdateF: func(ctx context.Context, user *chronograf.User) error {
return nil
@ -988,7 +987,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "SuperAdmin modifying their own SuperAdmin Status - user missing from context",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -1054,7 +1053,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "SuperAdmin modifying their own SuperAdmin Status",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -1127,7 +1126,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a SuperAdmin's Roles - without super admin context",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -1200,7 +1199,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user to super admin - without super admin context",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -1269,7 +1268,7 @@ func TestService_UpdateUser(t *testing.T) {
{
name: "Update a Chronograf user to super admin - with super admin context",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
OrganizationsStore: &mocks.OrganizationsStore{
GetF: func(ctx context.Context, q chronograf.OrganizationQuery) (*chronograf.Organization, error) {
switch *q.ID {
@ -1402,7 +1401,7 @@ func TestService_Users(t *testing.T) {
{
name: "Get all Chronograf users",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AllF: func(ctx context.Context) ([]chronograf.User, error) {
return []chronograf.User{
@ -1440,7 +1439,7 @@ func TestService_Users(t *testing.T) {
{
name: "Get all Chronograf users, ensuring order of users in response",
fields: fields{
Logger: log.New(log.DebugLevel),
Logger: &chronograf.NoopLogger{},
UsersStore: &mocks.UsersStore{
AllF: func(ctx context.Context) ([]chronograf.User, error) {
return []chronograf.User{

67
go.mod
View File

@ -1,29 +1,54 @@
module github.com/influxdata/platform
require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/BurntSushi/toml v0.3.1
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895 // indirect
github.com/Jeffail/gabs v1.1.1 // indirect
github.com/Masterminds/semver v1.4.2 // indirect
github.com/Microsoft/go-winio v0.4.11 // indirect
github.com/NYTimes/gziphandler v1.0.1
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/RoaringBitmap/roaring v0.4.16
github.com/SAP/go-hdb v0.13.1 // indirect
github.com/SermoDigital/jose v0.9.1 // indirect
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
github.com/apex/log v1.1.0 // indirect
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf // indirect
github.com/aws/aws-sdk-go v1.15.59 // indirect
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/bouk/httprouter v0.0.0-20160817010721-ee8b3818a7f5
github.com/caarlos0/ctrlc v1.0.0 // indirect
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e // indirect
github.com/cenkalti/backoff v2.0.0+incompatible // indirect
github.com/cespare/xxhash v1.1.0
github.com/circonus-labs/circonus-gometrics v2.2.4+incompatible // indirect
github.com/circonus-labs/circonusllhist v0.1.1 // indirect
github.com/containerd/continuity v0.0.0-20181027224239-bea7585dbfac // indirect
github.com/coreos/bbolt v1.3.1-coreos.6
github.com/davecgh/go-spew v1.1.1
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8
github.com/docker/distribution v2.6.2+incompatible // indirect
github.com/docker/docker v0.0.0-20180422163414-57142e89befe // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.3.3 // indirect
github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc // indirect
github.com/elazarl/go-bindata-assetfs v1.0.0
github.com/fatih/color v1.7.0 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/getkin/kin-openapi v0.1.0
github.com/ghodss/yaml v1.0.0 // indirect
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd // indirect
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493 // indirect
github.com/go-ldap/ldap v2.5.1+incompatible // indirect
github.com/go-test/deep v1.0.1 // indirect
github.com/gocql/gocql v0.0.0-20181117210152-33c0e89ca93a // indirect
github.com/gogo/protobuf v1.1.1
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db
github.com/google/go-cmp v0.2.0
@ -32,14 +57,30 @@ require (
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
github.com/goreleaser/goreleaser v0.91.1
github.com/goreleaser/nfpm v0.9.7 // indirect
github.com/gotestyourself/gotestyourself v2.2.0+incompatible // indirect
github.com/hashicorp/consul v1.4.0 // indirect
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f // indirect
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-memdb v0.0.0-20181108192425-032f93b25bec // indirect
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c // indirect
github.com/hashicorp/go-multierror v1.0.0 // indirect
github.com/hashicorp/go-plugin v0.0.0-20181030172320-54b6ff97d818 // indirect
github.com/hashicorp/go-retryablehttp v0.5.0 // indirect
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 // indirect
github.com/hashicorp/go-version v1.0.0 // indirect
github.com/hashicorp/memberlist v0.1.0 // indirect
github.com/hashicorp/raft v1.0.0 // indirect
github.com/hashicorp/serf v0.8.1 // indirect
github.com/hashicorp/vault v0.11.5
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e // indirect
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/influxdata/flux v0.7.1
github.com/influxdata/influxql v0.0.0-20180925231337-1cbfca8e56b6
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368
github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee // indirect
github.com/jessevdk/go-flags v1.4.0
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/jsternberg/zap-logfmt v1.2.0
@ -47,11 +88,14 @@ require (
github.com/julienschmidt/httprouter v1.2.0
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef
github.com/kevinburke/go-bindata v3.11.0+incompatible
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
github.com/keybase/go-crypto v0.0.0-20181031135447-f919bfda4fc1 // indirect
github.com/mattn/go-isatty v0.0.4
github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/miekg/dns v1.0.15 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.0.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.1.2 // indirect
github.com/mna/pigeon v1.0.1-0.20180808201053-bb0192cfc2ae
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae // indirect
@ -60,22 +104,32 @@ require (
github.com/nats-io/go-nats-streaming v0.4.0
github.com/nats-io/nats-streaming-server v0.11.2
github.com/nats-io/nuid v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v0.1.1 // indirect
github.com/opentracing/opentracing-go v1.0.2
github.com/ory/dockertest v3.3.2+incompatible // indirect
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/philhofer/fwd v1.0.0 // indirect
github.com/pkg/errors v0.8.0
github.com/prometheus/client_golang v0.9.0
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 // indirect
github.com/satori/go.uuid v1.2.0
github.com/sirupsen/logrus v1.1.1
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/sirupsen/logrus v1.2.0 // indirect
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a // indirect
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
github.com/spf13/viper v1.2.1
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 // indirect
github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8
github.com/testcontainers/testcontainer-go v0.0.0-20181115231424-8e868ca12c0f
github.com/tinylib/msgp v1.0.2 // indirect
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect
github.com/tylerb/graceful v1.2.15
github.com/willf/bitset v1.1.9 // indirect
go.uber.org/zap v1.9.1
@ -88,11 +142,18 @@ require (
google.golang.org/api v0.0.0-20181021000519-a2651947f503
google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e // indirect
google.golang.org/grpc v1.15.0
gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 // indirect
gopkg.in/ldap.v2 v2.5.1 // indirect
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce // indirect
gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect
gotest.tools v2.2.0+incompatible // indirect
honnef.co/go/tools v0.0.0-20181108184350-ae8f1f9103cc
labix.org/v2/mgo v0.0.0-20140701140051-000000000287 // indirect
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect
)
replace github.com/goreleaser/goreleaser => github.com/influxdata/goreleaser v0.86.2-0.20181010170531-0fd209ba67f5
replace (
github.com/Sirupsen/logrus => github.com/sirupsen/logrus v1.2.0
github.com/goreleaser/goreleaser => github.com/influxdata/goreleaser v0.86.2-0.20181010170531-0fd209ba67f5
)

166
go.sum
View File

@ -1,14 +1,29 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895 h1:dmc/C8bpE5VkQn65PNbbyACDC8xw8Hpp/NEurdPmQDQ=
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.11 h1:zoIOcVf0xPN1tnMVbTtEdI+P8OofVk3NObnwOQ6nK2Q=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/NYTimes/gziphandler v1.0.1 h1:iLrQrdwjDd52kHDA5op2UBJFjmOb9g+7scBan4RN8F0=
github.com/NYTimes/gziphandler v1.0.1/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/RoaringBitmap/roaring v0.4.16 h1:NholfewybRLOwACgfqfzn/N5xa6keKNs4fP00t0cwLo=
github.com/RoaringBitmap/roaring v0.4.16/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/SAP/go-hdb v0.13.1 h1:BuZlUZtqbF/oVSQ8Vp+/+wOtcBLh55zwMV7XnvYcz8g=
github.com/SAP/go-hdb v0.13.1/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0=
github.com/SermoDigital/jose v0.9.1 h1:atYaHPD3lPICcbK1owly3aPm0iaJGSGPi0WD4vLznv8=
github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
@ -21,12 +36,20 @@ 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/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf h1:eg0MeVzsP1G42dRafH3vf+al2vQIJU0YHX+1Tw87oco=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.59 h1:K/Jy1OfHttpKHHQEy1V0713bb6XMRiA1HO1aAi/sMNg=
github.com/aws/aws-sdk-go v1.15.59/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
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/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
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=
@ -37,22 +60,49 @@ github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw=
github.com/caarlos0/ctrlc v1.0.0/go.mod h1:CdXpj4rmq0q/1Eb44M9zi2nKB0QraNKuRGYGrrHhcQw=
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e h1:V9a67dfYqPLAvzk5hMQOXYJlZ4SLIXgyKIE+ZiHzgGQ=
github.com/campoy/unique v0.0.0-20180121183637-88950e537e7e/go.mod h1:9IOqJGCPMSc6E5ydlp5NIonxObaeu/Iub/X03EKPVYo=
github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY=
github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/circonus-labs/circonus-gometrics v2.2.4+incompatible h1:+ZwGzyJGsOwSxIEDDOXzPagR167tQak/1P5wBwH+/dM=
github.com/circonus-labs/circonus-gometrics v2.2.4+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.1 h1:MNPpugofgAFpPY/hTULMZIRfN18c5EQc8B8+4oFBx+4=
github.com/circonus-labs/circonusllhist v0.1.1/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/containerd/continuity v0.0.0-20181027224239-bea7585dbfac h1:PThQaO4yCvJzJBUW1XoFQxLotWRhvX2fgljJX8yrhFI=
github.com/containerd/continuity v0.0.0-20181027224239-bea7585dbfac/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/coreos/bbolt v1.3.1-coreos.6 h1:uTXKg9gY70s9jMAKdfljFQcuh4e/BXOM+V+d00KFj3A=
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
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/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f h1:WH0w/R4Yoey+04HhFxqZ6VX6I0d7RMyw5aXQ9UTvQPs=
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
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/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8 h1:akOQj8IVgoeFfBTzGOEQakCYshWD6RNo1M5pivFXt70=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/docker/distribution v2.6.2+incompatible h1:4FI6af79dfCS/CYb+RRtkSHw3q1L/bnDjG1PcPZtQhM=
github.com/docker/distribution v2.6.2+incompatible h1:4FI6af79dfCS/CYb+RRtkSHw3q1L/bnDjG1PcPZtQhM=
github.com/docker/distribution v2.6.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.6.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.6.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.0.0-20180422163414-57142e89befe h1:kst0/J/kJ8R3a1Q/xbW0uzX08TRH58AOXR3FrwnuzK8=
github.com/docker/docker v0.0.0-20180422163414-57142e89befe/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.3.3 h1:Xk8S3Xj5sLGlG5g67hJmYMmUgXv5N4PhkjJHHqrwnTk=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc h1:WBHvoAWoLWz5Zsg9ubIG+Y71gDvoVK5Wd/ON1EXA1Zc=
github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc h1:WBHvoAWoLWz5Zsg9ubIG+Y71gDvoVK5Wd/ON1EXA1Zc=
github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=
github.com/duosecurity/duo_api_golang v0.0.0-20181024123116-92fea9203dbc/go.mod h1:UqXY1lYT/ERa4OEAywUqdok1T4RCRdArkhic1Opuavo=
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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/getkin/kin-openapi v0.1.0 h1:uLHHTCEksmwf3frJv/GZEz9PX5KNT9qdXphr0j3n4P8=
@ -63,8 +113,14 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd h1:r04M
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493 h1:OTanQnFt0bi5iLFSdbEVA/idR6Q2WhCm+deb7ir2CcM=
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-ldap/ldap v2.5.1+incompatible h1:Opaoft5zMW8IU/VRULB0eGMBQ9P5buRvCW6sFTRmMn8=
github.com/go-ldap/ldap v2.5.1+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-test/deep v1.0.1 h1:UQhStjbkDClarlmv0am7OXXO4/GaPdCGiUiMTvi28sg=
github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gocql/gocql v0.0.0-20181117210152-33c0e89ca93a h1:B5gyGsJJmFKS7examblxFXz3ltm0mN3u0l1JgbMuy5E=
github.com/gocql/gocql v0.0.0-20181117210152-33c0e89ca93a/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
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/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
@ -73,6 +129,7 @@ github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200j
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
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/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
@ -85,18 +142,72 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
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/gotestyourself/gotestyourself v2.2.0+incompatible h1:1yOKgt0XYKUg1HOKunGOSt2ocU4bxLCjmIHt0vRtVHM=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/consul v1.4.0 h1:PQTW4xCuAExEiSbhrsFsikzbW5gVBoi74BjUvYFyKHw=
github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho=
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-memdb v0.0.0-20181108192425-032f93b25bec h1:A1nDk9UOKWPTQh5YcCnbwNbqj23e5pggf4HxGBulhr8=
github.com/hashicorp/go-memdb v0.0.0-20181108192425-032f93b25bec/go.mod h1:kbfItVoBJwCfKXDXN4YoAXjxcFVZ7MRrJzyTX6H4giE=
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c h1:BTAbnbegUIMB6xmQCwWE8yRzbA4XSpnZY5hvRJC188I=
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v0.0.0-20181030172320-54b6ff97d818 h1:wA1XRGBHMdpio0gcKUtnmkwSIlCAG1qzpsr+iPyi3Y8=
github.com/hashicorp/go-plugin v0.0.0-20181030172320-54b6ff97d818/go.mod h1:Ft7ju2vWzhO0ETMKUVo12XmXmII6eSUS4rsPTkY/siA=
github.com/hashicorp/go-retryablehttp v0.5.0 h1:aVN0FYnPwAgZI/hVzqwfMiM86ttcHTlQKbBVeVmXPIs=
github.com/hashicorp/go-retryablehttp v0.5.0/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:9HVkPxOpo+yO93Ah4yrO67d/qh0fbLLWbKqhYjyHq9A=
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 h1:7YOlAIO2YWnJZkQp7B5eFykaIY7C9JndqAFQyVV5BhM=
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/memberlist v0.1.0 h1:qSsCiC0WYD39lbSitKNt40e30uorm2Ss/d4JGU1hzH8=
github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE=
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
github.com/hashicorp/serf v0.8.1 h1:mYs6SMzu72+90OcPa5wr3nfznA4Dw9UyR791ZFNOIf4=
github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
github.com/hashicorp/vault v0.11.5 h1:6G3922BuHAxy3icIgSTJiv6GQCqFgdmXBvn3L9bNrZA=
github.com/hashicorp/vault v0.11.5/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0=
github.com/hashicorp/vault v0.11.5/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e h1:2Hwd2Yi0/qjAC6ujOu6WBVXAak9Snuw0LTYdZkqIdKM=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e h1:2Hwd2Yi0/qjAC6ujOu6WBVXAak9Snuw0LTYdZkqIdKM=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e h1:2Hwd2Yi0/qjAC6ujOu6WBVXAak9Snuw0LTYdZkqIdKM=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e h1:2Hwd2Yi0/qjAC6ujOu6WBVXAak9Snuw0LTYdZkqIdKM=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0=
github.com/hashicorp/vault-plugin-secrets-kv v0.0.0-20181106190520-2236f141171e/go.mod h1:VJHHT2SC1tAPrfENQeBhLlb5FbZoKZM+oC/ROmEftz0=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
@ -113,6 +224,8 @@ github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9 h1:MHTrDWmQpHq/
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368 h1:+TUUmaFa4YD1Q+7bH9o5NCHQGPMqZCYJiNW6lIIS9z4=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee h1:AQ/QmCk6x8ECPpf2pkPtA4lyncEEBbs8VFnVXPYKhIs=
github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM=
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
@ -129,10 +242,10 @@ github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef h1:2jNeR4YUziVtsw
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
github.com/kevinburke/go-bindata v3.11.0+incompatible h1:GiPs9jxaG2xY1B5Dt/d/yHUOMlTk14uS35VcmHrdo4I=
github.com/kevinburke/go-bindata v3.11.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM=
github.com/keybase/go-crypto v0.0.0-20181031135447-f919bfda4fc1 h1:60mtH2Zn7ZFaAd2bO636Q8xPMhSm3b9E49mNmGM+iJY=
github.com/keybase/go-crypto v0.0.0-20181031135447-f919bfda4fc1/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs=
github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
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/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
@ -157,12 +270,21 @@ github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53 h1:tGfIHhDghvEnneeR
github.com/mattn/go-zglob v0.0.0-20180803001819-2ea3427bfa53/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/miekg/dns v1.0.15 h1:9+UupePBQCG6zf1q/bGmTO1vumoG13jsrbWOSX1W6Tw=
github.com/miekg/dns v1.0.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mna/pigeon v1.0.1-0.20180808201053-bb0192cfc2ae h1:mQO+oxi0kpii/TX+ltfTCFuYkOjEn53JhaOObiMuvnk=
github.com/mna/pigeon v1.0.1-0.20180808201053-bb0192cfc2ae/go.mod h1:Iym28+kJVnC1hfQvv5MUtI6AiFFzvQjHcvI4RFTG/04=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae h1:VeRdUYdCw49yizlSbMEn2SZ+gT+3IUKx8BqxyQdz+BY=
@ -177,10 +299,22 @@ github.com/nats-io/nats-streaming-server v0.11.2 h1:UCqZbfXUKs9Ejw7KiNaFZEbbiVbK
github.com/nats-io/nats-streaming-server v0.11.2/go.mod h1:RyqtDJZvMZO66YmyjIYdIvS69zu/wDAkyNWa8PIUa5c=
github.com/nats-io/nuid v1.0.0 h1:44QGdhbiANq8ZCbUkdn6W5bqtg+mHuDE4wOUuxxndFs=
github.com/nats-io/nuid v1.0.0/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.1.1 h1:GlxAyO6x8rfZYN9Tt0Kti5a/cP41iuiO2yYT0IJGY8Y=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/ory/dockertest v3.3.2+incompatible h1:uO+NcwH6GuFof/Uz8yzjNi1g0sGT5SLAJbdBvD8bUYc=
github.com/ory/dockertest v3.3.2+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
@ -205,14 +339,20 @@ github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39 h1:Cto4X6SVMWRPB
github.com/prometheus/common v0.0.0-20181020173914-7e9e6cabbd39/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d h1:GoAlyOgbOEIFdaDqxJVlbOQ1DtGmZWs/Qau0hIlk+WQ=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735 h1:7YvPJVmEeFHR1Tj9sZEYsmarJEQfMVYpd/Vyy/A8dqE=
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/segmentio/kafka-go v0.1.0 h1:IXCHG+sXPNiIR5pC/vTEItZduPKu4cnpr85YgxpxlW0=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
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/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg=
github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
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.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a h1:JSvGDIbmil4Ui/dDdFBExb7/cmkNjyX5F97oglmvCDo=
@ -233,13 +373,20 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.2.1 h1:bIcUwXqLseLF3BDAZduuNfekWG87ibtFxi59Bq+oI9M=
github.com/spf13/viper v1.2.1/go.mod h1:P4AexN0a+C9tGAnUFNwDMYYZv3pjFuvmeiMyKRaNVlI=
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50 h1:4bT0pPowCpQImewr+BjzfUKcuFW+KVyB8d1OF3b6oTI=
github.com/stevvooe/resumable v0.0.0-20180830230917-22b14a53ba50/go.mod h1:1pdIZTAHUz+HDKDVZ++5xg/duPlhKAIzw9qy42CWYp4=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8 h1:RB0v+/pc8oMzPsN97aZYEwNuJ6ouRJ2uhjxemJ9zvrY=
github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8/go.mod h1:IlWNj9v/13q7xFbaK4mbyzMNwrZLaWSHx/aibKIZuIg=
github.com/testcontainers/testcontainer-go v0.0.0-20181115231424-8e868ca12c0f h1:O50XufNIw4FIpSi+/IOGyXTjlVyOgQkaq1MgbgXUtFE=
github.com/testcontainers/testcontainer-go v0.0.0-20181115231424-8e868ca12c0f/go.mod h1:SrG3IY071gtmZJjGbKO+POJ57a/MMESerYNWt6ZRtKs=
github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/tylerb/graceful v1.2.15 h1:B0x01Y8fsJpogzZTkDg6BDi6eMf03s01lEKGdrv83oA=
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
github.com/willf/bitset v1.1.9 h1:GBtFynGY9ZWZmEC9sWuu41/7VBXPFCOAbCbqTflOg9c=
@ -296,17 +443,28 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e h1:I5s8aUkxqPjgAssfOv+dVr+4/7BC40WV6JhcVoORltI=
google.golang.org/genproto v0.0.0-20181016170114-94acd270e44e/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.15.0 h1:Az/KuahOM4NAidTEuJCv/RonAA7rYsTPkqXVjr+8OOw=
google.golang.org/grpc v1.15.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 h1:JBwmEvLfCqgPcIq8MjVMQxsF3LVL4XG/HH0qiG0+IFY=
gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 h1:E846t8CnR+lv5nE+VuiKTDG/v1U2stad0QzddfJC7kY=
gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5/go.mod h1:hiOFpYm0ZJbusNj2ywpbrXowU3G8U6GIQzqn2mw1UIE=
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 h1:kb0VV7NuIojvRfzwslQeP3yArBqJHW9tOl4t38VS1jM=
gopkg.in/vmihailenco/msgpack.v2 v2.9.1/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:y0IMTfclpMdsdIbr6uwmJn5/WZ7vFuObxDMdrylFM3A=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858 h1:wN+eVZ7U+gqdqkec6C6VXR1OFf9a5Ul9ETzeYsYv20g=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20181108184350-ae8f1f9103cc h1:VdiEcF0DrrUbDdrLBceS0h7LE60ebD5yRYLLXi0ezIs=

View File

@ -22,6 +22,7 @@ type OrgHandler struct {
OrganizationOperationLogService platform.OrganizationOperationLogService
BucketService platform.BucketService
UserResourceMappingService platform.UserResourceMappingService
SecretService platform.SecretService
}
const (
@ -32,6 +33,9 @@ const (
organizationsIDMembersIDPath = "/api/v2/orgs/:id/members/:userID"
organizationsIDOwnersPath = "/api/v2/orgs/:id/owners"
organizationsIDOwnersIDPath = "/api/v2/orgs/:id/owners/:userID"
organizationsIDSecretsPath = "/api/v2/orgs/:id/secrets"
// TODO(desa): need a way to specify which secrets to delete. this should work for now
organizationsIDSecretsDeletePath = "/api/v2/orgs/:id/secrets/delete"
)
// NewOrgHandler returns a new instance of OrgHandler.
@ -56,6 +60,11 @@ func NewOrgHandler(mappingService platform.UserResourceMappingService) *OrgHandl
h.HandlerFunc("GET", organizationsIDOwnersPath, newGetMembersHandler(h.UserResourceMappingService, platform.Owner))
h.HandlerFunc("DELETE", organizationsIDOwnersIDPath, newDeleteMemberHandler(h.UserResourceMappingService, platform.Owner))
h.HandlerFunc("GET", organizationsIDSecretsPath, h.handleGetSecrets)
h.HandlerFunc("PATCH", organizationsIDSecretsPath, h.handlePatchSecrets)
// TODO(desa): need a way to specify which secrets to delete. this should work for now
h.HandlerFunc("POST", organizationsIDSecretsDeletePath, h.handleDeleteSecrets)
return h
}
@ -104,6 +113,21 @@ func newOrgResponse(o *platform.Organization) *orgResponse {
}
}
type secretsResponse struct {
Links map[string]string `json:"links"`
Secrets []string `json:"secrets"`
}
func newSecretsResponse(orgID platform.ID, ks []string) *secretsResponse {
return &secretsResponse{
Links: map[string]string{
"org": fmt.Sprintf("/api/v2/orgs/%s", orgID),
"secrets": fmt.Sprintf("/api/v2/orgs/%s/secrets", orgID),
},
Secrets: ks,
}
}
// handlePostOrg is the HTTP handler for the POST /api/v2/orgs route.
func (h *OrgHandler) handlePostOrg(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
@ -320,6 +344,139 @@ func decodePatchOrgRequest(ctx context.Context, r *http.Request) (*patchOrgReque
}, nil
}
// handleGetSecrets is the HTTP handler for the GET /api/v2/orgs/:id/secrets route.
func (h *OrgHandler) handleGetSecrets(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
req, err := decodeGetSecretsRequest(ctx, r)
if err != nil {
EncodeError(ctx, err, w)
return
}
ks, err := h.SecretService.GetSecretKeys(ctx, req.orgID)
if err != nil {
EncodeError(ctx, err, w)
return
}
if err := encodeResponse(ctx, w, http.StatusOK, newSecretsResponse(req.orgID, ks)); err != nil {
EncodeError(ctx, err, w)
return
}
}
type getSecretsRequest struct {
orgID platform.ID
}
func decodeGetSecretsRequest(ctx context.Context, r *http.Request) (*getSecretsRequest, error) {
req := &getSecretsRequest{}
params := httprouter.ParamsFromContext(ctx)
id := params.ByName("id")
if id == "" {
return nil, kerrors.InvalidDataf("url missing id")
}
var i platform.ID
if err := i.DecodeFromString(id); err != nil {
return nil, err
}
req.orgID = i
return req, nil
}
// handleGetPatchSecrets is the HTTP handler for the PATCH /api/v2/orgs/:id/secrets route.
func (h *OrgHandler) handlePatchSecrets(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
req, err := decodePatchSecretsRequest(ctx, r)
if err != nil {
EncodeError(ctx, err, w)
return
}
if err := h.SecretService.PatchSecrets(ctx, req.orgID, req.secrets); err != nil {
EncodeError(ctx, err, w)
return
}
w.WriteHeader(http.StatusNoContent)
}
type patchSecretsRequest struct {
orgID platform.ID
secrets map[string]string
}
func decodePatchSecretsRequest(ctx context.Context, r *http.Request) (*patchSecretsRequest, error) {
req := &patchSecretsRequest{}
params := httprouter.ParamsFromContext(ctx)
id := params.ByName("id")
if id == "" {
return nil, kerrors.InvalidDataf("url missing id")
}
var i platform.ID
if err := i.DecodeFromString(id); err != nil {
return nil, err
}
req.orgID = i
req.secrets = map[string]string{}
if err := json.NewDecoder(r.Body).Decode(&req.secrets); err != nil {
return nil, err
}
return req, nil
}
// handleDeleteSecrets is the HTTP handler for the DELETE /api/v2/orgs/:id/secrets route.
func (h *OrgHandler) handleDeleteSecrets(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
req, err := decodeDeleteSecretsRequest(ctx, r)
if err != nil {
EncodeError(ctx, err, w)
return
}
if err := h.SecretService.DeleteSecret(ctx, req.orgID, req.secrets...); err != nil {
EncodeError(ctx, err, w)
return
}
w.WriteHeader(http.StatusNoContent)
}
type deleteSecretsRequest struct {
orgID platform.ID
secrets []string
}
func decodeDeleteSecretsRequest(ctx context.Context, r *http.Request) (*deleteSecretsRequest, error) {
req := &deleteSecretsRequest{}
params := httprouter.ParamsFromContext(ctx)
id := params.ByName("id")
if id == "" {
return nil, kerrors.InvalidDataf("url missing id")
}
var i platform.ID
if err := i.DecodeFromString(id); err != nil {
return nil, err
}
req.orgID = i
req.secrets = []string{}
if err := json.NewDecoder(r.Body).Decode(&req.secrets); err != nil {
return nil, err
}
return req, nil
}
const (
organizationPath = "/api/v2/orgs"
)

View File

@ -1,7 +1,12 @@
package http
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
@ -39,3 +44,263 @@ func TestOrganizationService(t *testing.T) {
t.Parallel()
platformtesting.OrganizationService(initOrganizationService, t)
}
func TestSecretService_handleGetSecrets(t *testing.T) {
type fields struct {
SecretService platform.SecretService
}
type args struct {
orgID platform.ID
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get basic secrets",
fields: fields{
&mock.SecretService{
GetSecretKeysFn: func(ctx context.Context, orgID platform.ID) ([]string, error) {
return []string{"hello", "world"}, nil
},
},
},
args: args{
orgID: 1,
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"org": "/api/v2/orgs/0000000000000001",
"secrets": "/api/v2/orgs/0000000000000001/secrets"
},
"secrets": [
"hello",
"world"
]
}
`,
},
},
{
name: "get secrets when there are none",
fields: fields{
&mock.SecretService{
GetSecretKeysFn: func(ctx context.Context, orgID platform.ID) ([]string, error) {
return []string{}, nil
},
},
},
args: args{
orgID: 1,
},
wants: wants{
statusCode: http.StatusOK,
contentType: "application/json; charset=utf-8",
body: `
{
"links": {
"org": "/api/v2/orgs/0000000000000001",
"secrets": "/api/v2/orgs/0000000000000001/secrets"
},
"secrets": []
}
`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mappingService := mock.NewUserResourceMappingService()
h := NewOrgHandler(mappingService)
h.SecretService = tt.fields.SecretService
u := fmt.Sprintf("http://any.url/api/v2/orgs/%s/secrets", tt.args.orgID)
r := httptest.NewRequest("GET", u, nil)
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(res.Body)
if res.StatusCode != tt.wants.statusCode {
t.Errorf("handleGetSecrets() = %v, want %v", res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("handleGetSecrets() = %v, want %v", content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("handleGetSecrets() = \n***%v***\n,\nwant\n***%v***", string(body), tt.wants.body)
}
})
}
}
func TestSecretService_handlePatchSecrets(t *testing.T) {
type fields struct {
SecretService platform.SecretService
}
type args struct {
orgID platform.ID
secrets map[string]string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get basic secrets",
fields: fields{
&mock.SecretService{
PatchSecretsFn: func(ctx context.Context, orgID platform.ID, s map[string]string) error {
return nil
},
},
},
args: args{
orgID: 1,
secrets: map[string]string{
"abc": "123",
},
},
wants: wants{
statusCode: http.StatusNoContent,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mappingService := mock.NewUserResourceMappingService()
h := NewOrgHandler(mappingService)
h.SecretService = tt.fields.SecretService
b, err := json.Marshal(tt.args.secrets)
if err != nil {
t.Fatalf("failed to marshal secrets: %v", err)
}
buf := bytes.NewReader(b)
u := fmt.Sprintf("http://any.url/api/v2/orgs/%s/secrets", tt.args.orgID)
r := httptest.NewRequest("PATCH", u, buf)
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(res.Body)
if res.StatusCode != tt.wants.statusCode {
t.Errorf("handlePatchSecrets() = %v, want %v", res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("handlePatchSecrets() = %v, want %v", content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("handlePatchSecrets() = \n***%v***\n,\nwant\n***%v***", string(body), tt.wants.body)
}
})
}
}
func TestSecretService_handleDeleteSecrets(t *testing.T) {
type fields struct {
SecretService platform.SecretService
}
type args struct {
orgID platform.ID
secrets []string
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "get basic secrets",
fields: fields{
&mock.SecretService{
DeleteSecretFn: func(ctx context.Context, orgID platform.ID, s ...string) error {
return nil
},
},
},
args: args{
orgID: 1,
secrets: []string{
"abc",
},
},
wants: wants{
statusCode: http.StatusNoContent,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mappingService := mock.NewUserResourceMappingService()
h := NewOrgHandler(mappingService)
h.SecretService = tt.fields.SecretService
b, err := json.Marshal(tt.args.secrets)
if err != nil {
t.Fatalf("failed to marshal secrets: %v", err)
}
buf := bytes.NewReader(b)
u := fmt.Sprintf("http://any.url/api/v2/orgs/%s/secrets/delete", tt.args.orgID)
r := httptest.NewRequest("POST", u, buf)
w := httptest.NewRecorder()
h.ServeHTTP(w, r)
res := w.Result()
content := res.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(res.Body)
if res.StatusCode != tt.wants.statusCode {
t.Errorf("handleDeleteSecrets() = %v, want %v", res.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("handleDeleteSecrets() = %v, want %v", content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("handleDeleteSecrets() = \n***%v***\n,\nwant\n***%v***", string(body), tt.wants.body)
}
})
}
}

View File

@ -1492,6 +1492,10 @@ paths:
description: Abstract syntax tree of flux query.
content:
application/json: #TODO(goller): document the AST JSON schema
schema:
properties:
todo:
type: string # swagger editor was yelling at me here
default:
description: Any response other than 200 is an internal server error
content:
@ -2290,6 +2294,89 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/orgs/{orgID}/secrets':
get:
tags:
- Secrets
- Organizations
summary: List all secret keys for an organization
parameters:
- in: path
name: orgID
schema:
type: string
required: true
description: ID of the organization
responses:
'200':
description: a list of all secret keys
content:
application/json:
schema:
$ref: "#/components/schemas/SecretKeys"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
patch:
tags:
- Secrets
- Organizations
summary: Apply patch to the provided secrets
parameters:
- in: path
name: orgID
schema:
type: string
required: true
description: ID of the organization
requestBody:
description: secret key value pairs to update/add
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Secrets"
responses:
'204':
description: keys successfully patched
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/orgs/{orgID}/secrets/delete': # had to make this because swagger wouldn't let me have a request body with a DELETE
post:
tags:
- Secrets
- Organizations
summary: delete provided secrets
parameters:
- in: path
name: orgID
schema:
type: string
required: true
description: ID of the organization
requestBody:
description: secret key to deleted
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SecretKeys"
responses:
'204':
description: keys successfully patched
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/orgs/{orgID}/members':
get:
tags:
@ -4620,6 +4707,24 @@ components:
type: array
items:
$ref: "#/components/schemas/Cell"
Secrets:
additionalProperties:
type: string
example:
apikey: abc123xyz
SecretKeys:
properties:
links:
type: object
properties:
self:
type: string
org:
type: string
secrets:
type: array
items:
type: string
Dashboard:
properties:
links:

74
mock/secret_service.go Normal file
View File

@ -0,0 +1,74 @@
package mock
import (
"context"
"fmt"
"github.com/influxdata/platform"
)
// SecretService is a mock implementation of a retention.SecretService, which
// also makes it a suitable mock to use wherever an platform.SecretService is required.
type SecretService struct {
LoadSecretFn func(ctx context.Context, orgID platform.ID, k string) (string, error)
GetSecretKeysFn func(ctx context.Context, orgID platform.ID) ([]string, error)
PutSecretFn func(ctx context.Context, orgID platform.ID, k string, v string) error
PutSecretsFn func(ctx context.Context, orgID platform.ID, m map[string]string) error
PatchSecretsFn func(ctx context.Context, orgID platform.ID, m map[string]string) error
DeleteSecretFn func(ctx context.Context, orgID platform.ID, ks ...string) error
}
// NewSecretService returns a mock SecretService where its methods will return
// zero values.
func NewSecretService() *SecretService {
return &SecretService{
LoadSecretFn: func(ctx context.Context, orgID platform.ID, k string) (string, error) {
return "", fmt.Errorf("not implmemented")
},
GetSecretKeysFn: func(ctx context.Context, orgID platform.ID) ([]string, error) {
return nil, fmt.Errorf("not implmemented")
},
PutSecretFn: func(ctx context.Context, orgID platform.ID, k string, v string) error {
return fmt.Errorf("not implmemented")
},
PutSecretsFn: func(ctx context.Context, orgID platform.ID, m map[string]string) error {
return fmt.Errorf("not implmemented")
},
PatchSecretsFn: func(ctx context.Context, orgID platform.ID, m map[string]string) error {
return fmt.Errorf("not implmemented")
},
DeleteSecretFn: func(ctx context.Context, orgID platform.ID, ks ...string) error {
return fmt.Errorf("not implmemented")
},
}
}
// LoadSecret retrieves the secret value v found at key k for organization orgID.
func (s *SecretService) LoadSecret(ctx context.Context, orgID platform.ID, k string) (string, error) {
return s.LoadSecretFn(ctx, orgID, k)
}
// GetSecretKeys retrieves all secret keys that are stored for the organization orgID.
func (s *SecretService) GetSecretKeys(ctx context.Context, orgID platform.ID) ([]string, error) {
return s.GetSecretKeysFn(ctx, orgID)
}
// PutSecret stores the secret pair (k,v) for the organization orgID.
func (s *SecretService) PutSecret(ctx context.Context, orgID platform.ID, k string, v string) error {
return s.PutSecretFn(ctx, orgID, k, v)
}
// PutSecrets puts all provided secrets and overwrites any previous values.
func (s *SecretService) PutSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
return s.PutSecretsFn(ctx, orgID, m)
}
// PatchSecrets patches all provided secrets and updates any previous values.
func (s *SecretService) PatchSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
return s.PatchSecretsFn(ctx, orgID, m)
}
// DeleteSecret removes a single secret from the secret store.
func (s *SecretService) DeleteSecret(ctx context.Context, orgID platform.ID, ks ...string) error {
return s.DeleteSecretFn(ctx, orgID, ks...)
}

View File

@ -12,4 +12,13 @@ type SecretService interface {
// PutSecret stores the secret pair (k,v) for the organization orgID.
PutSecret(ctx context.Context, orgID ID, k string, v string) error
// PutSecrets puts all provided secrets and overwrites any previous values.
PutSecrets(ctx context.Context, orgID ID, m map[string]string) error
// PatchSecrets patches all provided secrets and updates any previous values.
PatchSecrets(ctx context.Context, orgID ID, m map[string]string) error
// DeleteSecret removes a single secret from the secret store.
DeleteSecret(ctx context.Context, orgID ID, ks ...string) error
}

View File

@ -1,13 +1,26 @@
package testing
import (
"bytes"
"context"
"sort"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/platform"
)
var secretCmpOptions = cmp.Options{
cmp.Comparer(func(x, y []byte) bool {
return bytes.Equal(x, y)
}),
cmp.Transformer("Sort", func(in []string) []string {
out := append([]string(nil), in...) // Copy input to avoid mutating it
sort.Strings(out)
return out
}),
}
// A secret is a comparable data structure that is used for testing
type Secret struct {
OrganizationID platform.ID
@ -40,10 +53,22 @@ func SecretService(
name: "PutSecret",
fn: PutSecret,
},
{
name: "PutSecrets",
fn: PutSecrets,
},
{
name: "PatchSecrets",
fn: PatchSecrets,
},
{
name: "GetSecretKeys",
fn: GetSecretKeys,
},
{
name: "DeleteSecrets",
fn: DeleteSecrets,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -179,6 +204,176 @@ func PutSecret(
}
}
// PutSecrets tests the PutSecrets method for the SecretService interface.
func PutSecrets(
init func(f SecretServiceFields, t *testing.T) (platform.SecretService, func()),
t *testing.T,
) {
type args struct {
orgID platform.ID
secrets map[string]string
}
type wants struct {
err error
keys []string
}
tests := []struct {
name string
fields SecretServiceFields
args args
wants wants
}{
{
name: "put secrets",
fields: SecretServiceFields{
Secrets: []Secret{
{
OrganizationID: platform.ID(1),
Env: map[string]string{
"api_key": "abc123xyz",
},
},
},
},
args: args{
orgID: platform.ID(1),
secrets: map[string]string{
"api_key2": "abc123xyz",
"batman": "potato",
},
},
wants: wants{
keys: []string{"api_key2", "batman"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.PutSecrets(ctx, tt.args.orgID, tt.args.secrets)
if (err != nil) != (tt.wants.err != nil) {
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
}
if err != nil && tt.wants.err != nil {
if err.Error() != tt.wants.err.Error() {
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
}
}
for k, v := range tt.args.secrets {
val, err := s.LoadSecret(ctx, tt.args.orgID, k)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if want, got := v, val; want != got {
t.Errorf("expected value to be %s, got %s", want, got)
}
}
keys, err := s.GetSecretKeys(ctx, tt.args.orgID)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if diff := cmp.Diff(keys, tt.wants.keys, secretCmpOptions...); diff != "" {
t.Errorf("keys are different -got/+want\ndiff %s", diff)
}
})
}
}
// PatchSecrets tests the PatchSecrets method for the SecretService interface.
func PatchSecrets(
init func(f SecretServiceFields, t *testing.T) (platform.SecretService, func()),
t *testing.T,
) {
type args struct {
orgID platform.ID
secrets map[string]string
}
type wants struct {
err error
keys []string
}
tests := []struct {
name string
fields SecretServiceFields
args args
wants wants
}{
{
name: "patch secrets",
fields: SecretServiceFields{
Secrets: []Secret{
{
OrganizationID: platform.ID(1),
Env: map[string]string{
"api_key": "abc123xyz",
},
},
},
},
args: args{
orgID: platform.ID(1),
secrets: map[string]string{
"api_key2": "abc123xyz",
"batman": "potato",
},
},
wants: wants{
keys: []string{"api_key", "api_key2", "batman"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.PatchSecrets(ctx, tt.args.orgID, tt.args.secrets)
if (err != nil) != (tt.wants.err != nil) {
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
}
if err != nil && tt.wants.err != nil {
if err.Error() != tt.wants.err.Error() {
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
}
}
for k, v := range tt.args.secrets {
val, err := s.LoadSecret(ctx, tt.args.orgID, k)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if want, got := v, val; want != got {
t.Errorf("expected value to be %s, got %s", want, got)
}
}
keys, err := s.GetSecretKeys(ctx, tt.args.orgID)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if diff := cmp.Diff(keys, tt.wants.keys, secretCmpOptions...); diff != "" {
t.Errorf("keys are different -got/+want\ndiff %s", diff)
}
})
}
}
// GetSecretKeys tests the GetSecretKeys method for the SecretService interface.
func GetSecretKeys(
init func(f SecretServiceFields, t *testing.T) (platform.SecretService, func()),
@ -242,7 +437,80 @@ func GetSecretKeys(
}
}
if diff := cmp.Diff(keys, tt.wants.keys); diff != "" {
if diff := cmp.Diff(keys, tt.wants.keys, secretCmpOptions...); diff != "" {
t.Errorf("keys are different -got/+want\ndiff %s", diff)
}
})
}
}
// DeleteSecrets tests the DeleteSecrets method for the SecretService interface.
func DeleteSecrets(
init func(f SecretServiceFields, t *testing.T) (platform.SecretService, func()),
t *testing.T,
) {
type args struct {
orgID platform.ID
keys []string
}
type wants struct {
keys []string
err error
}
tests := []struct {
name string
fields SecretServiceFields
args args
wants wants
}{
{
name: "delete secret keys",
fields: SecretServiceFields{
Secrets: []Secret{
{
OrganizationID: platform.ID(1),
Env: map[string]string{
"api_key": "abc123xyz",
"api_key2": "potato",
"batman": "foo",
},
},
},
},
args: args{
orgID: platform.ID(1),
keys: []string{"api_key2", "batman"},
},
wants: wants{
keys: []string{"api_key"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, done := init(tt.fields, t)
defer done()
ctx := context.Background()
err := s.DeleteSecret(ctx, tt.args.orgID, tt.args.keys...)
if (err != nil) != (tt.wants.err != nil) {
t.Fatalf("expected error '%v' got '%v'", tt.wants.err, err)
}
if err != nil && tt.wants.err != nil {
if err.Error() != tt.wants.err.Error() {
t.Fatalf("expected error messages to match '%v' got '%v'", tt.wants.err, err.Error())
}
}
keys, err := s.GetSecretKeys(ctx, tt.args.orgID)
if err != nil {
t.Fatalf("unexpected error %v", err)
}
if diff := cmp.Diff(keys, tt.wants.keys, secretCmpOptions...); diff != "" {
t.Errorf("keys are different -got/+want\ndiff %s", diff)
}
})

185
vault/secret.go Normal file
View File

@ -0,0 +1,185 @@
package vault
import (
"context"
"encoding/json"
"fmt"
"strconv"
"github.com/hashicorp/vault/api"
"github.com/influxdata/platform"
)
var _ platform.SecretService = (*SecretService)(nil)
// SecretService is service for storing user secrets
type SecretService struct {
Client *api.Client
}
// NewSecretService creates an instance of a SecretService.
// The service is configured using the standard vault environment variables.
// https://www.vaultproject.io/docs/commands/index.html#environment-variables
func NewSecretService() (*SecretService, error) {
cfg := api.DefaultConfig()
if err := cfg.ReadEnvironment(); err != nil {
return nil, err
}
c, err := api.NewClient(cfg)
if err != nil {
return nil, err
}
return &SecretService{
Client: c,
}, nil
}
// LoadSecret retrieves the secret value v found at key k for organization orgID.
func (s *SecretService) LoadSecret(ctx context.Context, orgID platform.ID, k string) (string, error) {
data, _, err := s.loadSecrets(ctx, orgID)
if err != nil {
return "", err
}
if v, ok := data[k]; ok {
return v, nil
}
return "", fmt.Errorf("secret not found")
}
// loadSecrets retrieves a map of secrets for an organization and the version of the secrets retrieved.
// The version is used to ensure that concurrent updates will not overwrite one another.
func (s *SecretService) loadSecrets(ctx context.Context, orgID platform.ID) (map[string]string, int, error) {
// TODO(desa): update url construction
sec, err := s.Client.Logical().Read(fmt.Sprintf("/secret/data/%s", orgID))
if err != nil {
return nil, -1, err
}
m := map[string]string{}
if sec == nil {
return m, 0, nil
}
data, ok := sec.Data["data"].(map[string]interface{})
if !ok {
return nil, -1, fmt.Errorf("value found in secret data is not map[string]interface{}")
}
for k, v := range data {
val, ok := v.(string)
if !ok {
continue
}
m[k] = val
}
metadata, ok := sec.Data["metadata"].(map[string]interface{})
if !ok {
return nil, -1, fmt.Errorf("value found in secret metadata is not map[string]interface{}")
}
var version int
switch v := metadata["version"].(type) {
case json.Number:
ver, err := v.Int64()
if err != nil {
return nil, -1, err
}
version = int(ver)
case string:
ver, err := strconv.Atoi(v)
if err != nil {
return nil, -1, fmt.Errorf("version provided is not a valid integer: %v", err)
}
version = ver
case int:
version = v
default:
return nil, -1, fmt.Errorf("version provided is %T not a string or int", v)
}
return m, version, nil
}
// GetSecretKeys retrieves all secret keys that are stored for the organization orgID.
func (s *SecretService) GetSecretKeys(ctx context.Context, orgID platform.ID) ([]string, error) {
data, _, err := s.loadSecrets(ctx, orgID)
if err != nil {
return nil, err
}
keys := make([]string, 0, len(data))
for k := range data {
keys = append(keys, k)
}
return keys, nil
}
// PutSecret stores the secret pair (k,v) for the organization orgID.
func (s *SecretService) PutSecret(ctx context.Context, orgID platform.ID, k string, v string) error {
data, ver, err := s.loadSecrets(ctx, orgID)
if err != nil {
return err
}
data[k] = v
return s.putSecrets(ctx, orgID, data, ver)
}
// putSecrets will set all provided data values for the organization orgID.
// If version is negative, the write will overwrite all specified values.
// If version is 0, the write will only be allowed if the keys do not exists.
// If version is non-zero, the write will only be allowed if the keys current
// version in vault matches the version specified.
func (s *SecretService) putSecrets(ctx context.Context, orgID platform.ID, data map[string]string, version int) error {
m := map[string]interface{}{"data": data}
if version >= 0 {
m["options"] = map[string]interface{}{"cas": version}
}
if _, err := s.Client.Logical().Write(fmt.Sprintf("/secret/data/%s", orgID), m); err != nil {
return err
}
return nil
}
// PutSecrets puts all provided secrets and overwrites any previous values.
func (s *SecretService) PutSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
return s.putSecrets(ctx, orgID, m, -1)
}
// PatchSecrets patches all provided secrets and updates any previous values.
func (s *SecretService) PatchSecrets(ctx context.Context, orgID platform.ID, m map[string]string) error {
data, ver, err := s.loadSecrets(ctx, orgID)
if err != nil {
return err
}
for k, v := range m {
data[k] = v
}
return s.putSecrets(ctx, orgID, data, ver)
}
// DeleteSecret removes a single secret from the secret store.
func (s *SecretService) DeleteSecret(ctx context.Context, orgID platform.ID, ks ...string) error {
data, ver, err := s.loadSecrets(ctx, orgID)
if err != nil {
return err
}
for _, k := range ks {
delete(data, k)
}
return s.putSecrets(ctx, orgID, data, ver)
}

54
vault/secret_test.go Normal file
View File

@ -0,0 +1,54 @@
// +build integration
package vault_test
import (
"context"
"fmt"
"testing"
"github.com/influxdata/platform"
platformtesting "github.com/influxdata/platform/testing"
"github.com/influxdata/platform/vault"
testcontainer "github.com/testcontainers/testcontainer-go"
)
func initSecretService(f platformtesting.SecretServiceFields, t *testing.T) (platform.SecretService, func()) {
token := "test"
ctx := context.Background()
vaultC, err := testcontainer.RunContainer(ctx, "vault", testcontainer.RequestContainer{
ExportedPort: []string{
"8200/tcp",
},
Cmd: fmt.Sprintf(`vault server -dev -dev-listen-address 0.0.0.0:8200 -dev-root-token-id=%s`, token),
})
if err != nil {
t.Fatalf("failed to initialize vault testcontiner: %v", err)
}
ip, port, err := vaultC.GetHostEndpoint(ctx, "8200/tcp")
if err != nil {
t.Fatal(err)
}
s, err := vault.NewSecretService()
if err != nil {
t.Fatal(err)
}
s.Client.SetToken(token)
s.Client.SetAddress(fmt.Sprintf("http://%v:%v", ip, port))
for _, sec := range f.Secrets {
for k, v := range sec.Env {
if err := s.PutSecret(ctx, sec.OrganizationID, k, v); err != nil {
t.Fatalf("failed to populate secrets: %v", err)
}
}
}
return s, func() {
defer vaultC.Terminate(ctx, t)
}
}
func TestSecretService(t *testing.T) {
platformtesting.SecretService(initSecretService, t)
}