From 639bce721787bb532a95cd040cd247de1a8ca398 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 29 Jun 2017 14:25:41 -0700 Subject: [PATCH 01/17] Group flags more semantically consistently --- server/server.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/server.go b/server/server.go index 22f5dc058a..a54ea0d167 100644 --- a/server/server.go +++ b/server/server.go @@ -78,14 +78,13 @@ type Server struct { GenericTokenURL string `long:"generic-token-url" description:"OAuth 2.0 provider's token endpoint URL" env:"GENERIC_TOKEN_URL"` GenericAPIURL string `long:"generic-api-url" description:"URL that returns OpenID UserInfo compatible information." env:"GENERIC_API_URL"` - StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"` - - CustomLinks map[string]string `long:"custom-link" description:"Custom link to be added to the client User menu. Multiple links can be added by using multiple of the same flag with different 'name:url' values, or as an environment variable with comma-separated 'name:url' values. E.g. via flags: '--custom-link=InfluxData:https://www.influxdata.com --custom-link=Chronograf:https://github.com/influxdata/chronograf'. E.g. via environment variable: 'export CUSTOM_LINKS=InfluxData:https://www.influxdata.com,Chronograf:https://github.com/influxdata/chronograf'" env:"CUSTOM_LINKS" env-delim:","` - Auth0Domain string `long:"auth0-domain" description:"Subdomain of auth0.com used for Auth0 OAuth2 authentication" env:"AUTH0_DOMAIN"` Auth0ClientID string `long:"auth0-client-id" description:"Auth0 Client ID for OAuth2 support" env:"AUTH0_CLIENT_ID"` Auth0ClientSecret string `long:"auth0-client-secret" description:"Auth0 Client Secret for OAuth2 support" env:"AUTH0_CLIENT_SECRET"` + StatusFeedURL string `long:"status-feed-url" description:"URL of a JSON Feed to display as a News Feed on the client Status page." default:"https://www.influxdata.com/feed/json" env:"STATUS_FEED_URL"` + CustomLinks map[string]string `long:"custom-link" description:"Custom link to be added to the client User menu. Multiple links can be added by using multiple of the same flag with different 'name:url' values, or as an environment variable with comma-separated 'name:url' values. E.g. via flags: '--custom-link=InfluxData:https://www.influxdata.com --custom-link=Chronograf:https://github.com/influxdata/chronograf'. E.g. via environment variable: 'export CUSTOM_LINKS=InfluxData:https://www.influxdata.com,Chronograf:https://github.com/influxdata/chronograf'" env:"CUSTOM_LINKS" env-delim:","` + ReportingDisabled bool `short:"r" long:"reporting-disabled" description:"Disable reporting of usage stats (os,arch,version,cluster_id,uptime) once every 24hr" env:"REPORTING_DISABLED"` LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"error" default:"info" description:"Set the logging level" env:"LOG_LEVEL"` Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted" env:"BASE_PATH"` From 0c8b5438062d7d2eb4438898de4b0d7b03de72d1 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 29 Jun 2017 15:33:22 -0700 Subject: [PATCH 02/17] Add pseudocode outline for parsing and persisting source and server Signed-off-by: Tim Raymond --- cmd/chronograf/main.go | 19 +++++++++++++++++++ server/server.go | 2 ++ 2 files changed, 21 insertions(+) diff --git a/cmd/chronograf/main.go b/cmd/chronograf/main.go index f5731616d4..6222dedeff 100644 --- a/cmd/chronograf/main.go +++ b/cmd/chronograf/main.go @@ -42,6 +42,25 @@ func main() { os.Exit(0) } + if srv.NewSource != "" { + /* + // parse influxdb key from newsource into chronograf.Source struct from chronograf.go + // parse kapacitor key from newsource into chronograf.Server struct from chronograf.go + // open connection to boltDB + // use sources.All to get all sources + // if that influxdb does not exist (how to compare?) + // use sourcesStore to add this new source + // if successful + // hold onto this new source id + // if that kapacitor does not exist (how to compare?) + // use serverStore to add new kapacitor, including new source id + // else + // throw error + // else + // do nothing + */ + } + ctx := context.Background() if err := srv.Serve(ctx); err != nil { log.Fatalln(err) diff --git a/server/server.go b/server/server.go index a54ea0d167..a9a5627ca3 100644 --- a/server/server.go +++ b/server/server.go @@ -50,6 +50,8 @@ type Server struct { KapacitorUsername string `long:"kapacitor-username" description:"Username of your Kapacitor instance" env:"KAPACITOR_USERNAME"` KapacitorPassword string `long:"kapacitor-password" description:"Password of your Kapacitor instance" env:"KAPACITOR_PASSWORD"` + NewSource map[string]string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server" env:"NEW_SOURCE"` + Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` CannedPath string `short:"c" long:"canned-path" description:"Path to directory of pre-canned application layouts (/usr/share/chronograf/canned)" env:"CANNED_PATH" default:"canned"` From b1f8ff81c3fe4591b13f4115fdbb8805ddcab52d Mon Sep 17 00:00:00 2001 From: Tim Raymond Date: Wed, 5 Jul 2017 15:00:59 -0700 Subject: [PATCH 03/17] Parse JSON for --new-source into struct Signed-off-by: Jared Scheib --- cmd/chronograf/main.go | 13 +++++++++++++ server/server.go | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/cmd/chronograf/main.go b/cmd/chronograf/main.go index 6222dedeff..326c85306b 100644 --- a/cmd/chronograf/main.go +++ b/cmd/chronograf/main.go @@ -2,9 +2,12 @@ package main import ( "context" + "encoding/json" + "fmt" "log" "os" + "github.com/influxdata/chronograf" "github.com/influxdata/chronograf/server" flags "github.com/jessevdk/go-flags" ) @@ -43,6 +46,16 @@ func main() { } if srv.NewSource != "" { + type SourceServer struct { + Source chronograf.Source `json:"influxdb"` + Kapacitor chronograf.Server `json:"kapacitor"` + } + var sourceServers []SourceServer + err := json.Unmarshal([]byte(srv.NewSource), &sourceServers) + if err != nil { + fmt.Print(err) + } + /* // parse influxdb key from newsource into chronograf.Source struct from chronograf.go // parse kapacitor key from newsource into chronograf.Server struct from chronograf.go diff --git a/server/server.go b/server/server.go index a9a5627ca3..f7e21cc8ae 100644 --- a/server/server.go +++ b/server/server.go @@ -50,7 +50,7 @@ type Server struct { KapacitorUsername string `long:"kapacitor-username" description:"Username of your Kapacitor instance" env:"KAPACITOR_USERNAME"` KapacitorPassword string `long:"kapacitor-password" description:"Password of your Kapacitor instance" env:"KAPACITOR_PASSWORD"` - NewSource map[string]string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server" env:"NEW_SOURCE"` + NewSource string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server, in JSON and surrounded by single quotes" env:"NEW_SOURCE"` Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` From 52e65be69dfbcf5dc34e1876a6fd7417d86b18a0 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Wed, 5 Jul 2017 18:12:08 -0700 Subject: [PATCH 04/17] Successfully persist new source and kapa via server flag Move this to after BoltDb connection is opened --- chronograf.go | 63 ++++++++++++++++++++++++++++++++++++++++++ cmd/chronograf/main.go | 32 --------------------- server/server.go | 12 +++++++- 3 files changed, 74 insertions(+), 33 deletions(-) diff --git a/chronograf.go b/chronograf.go index 0525482a70..24cf3ae608 100644 --- a/chronograf.go +++ b/chronograf.go @@ -625,3 +625,66 @@ type LayoutStore interface { // Update the dashboard in the store. Update(context.Context, Layout) error } + +// SourceAndKapacitor allows a --new-source to be parsed into a source and a kapacitor +type SourceAndKapacitor struct { + Source Source `json:"influxdb"` + Kapacitor Server `json:"kapacitor"` +} + +// NewSources adds sources and respective kapacitors to BoltDb idempotently by name +func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, newSources string, logger Logger) error { + // Once a bolt connection is created, try to add any new sources with respective kapacitor servers + if newSources != "" { + var srcsKaps []SourceAndKapacitor + // On JSON unmarshal error, continue server process without new source and write error to log + if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { + logger. + WithField("component", "server"). + WithField("NewSource", "invalid"). + Error(err) + } else { + srcs, err := sourcesStore.All(ctx) + if err != nil { + return err + } + kaps, err := serversStore.All(ctx) + if err != nil { + return err + } + + for _, srcKap := range srcsKaps { + isNewSource := true + for _, src := range srcs { + if src.Name == srcKap.Source.Name { + isNewSource = false + break + } + } + if isNewSource == true { + src, err := sourcesStore.Add(ctx, srcKap.Source) + if err != nil { + return err + } + + isNewKapacitor := true + for _, kap := range kaps { + if kap.Name == srcKap.Kapacitor.Name { + isNewKapacitor = false + break + } + } + if isNewKapacitor == true { + srcKap.Kapacitor.SrcID = src.ID + _, err := serversStore.Add(ctx, srcKap.Kapacitor) + if err != nil { + return err + } + } + // TODO: if Kapa is not new, should it be updated to point to this source ID? + } + } + } + } + return nil +} diff --git a/cmd/chronograf/main.go b/cmd/chronograf/main.go index 326c85306b..f5731616d4 100644 --- a/cmd/chronograf/main.go +++ b/cmd/chronograf/main.go @@ -2,12 +2,9 @@ package main import ( "context" - "encoding/json" - "fmt" "log" "os" - "github.com/influxdata/chronograf" "github.com/influxdata/chronograf/server" flags "github.com/jessevdk/go-flags" ) @@ -45,35 +42,6 @@ func main() { os.Exit(0) } - if srv.NewSource != "" { - type SourceServer struct { - Source chronograf.Source `json:"influxdb"` - Kapacitor chronograf.Server `json:"kapacitor"` - } - var sourceServers []SourceServer - err := json.Unmarshal([]byte(srv.NewSource), &sourceServers) - if err != nil { - fmt.Print(err) - } - - /* - // parse influxdb key from newsource into chronograf.Source struct from chronograf.go - // parse kapacitor key from newsource into chronograf.Server struct from chronograf.go - // open connection to boltDB - // use sources.All to get all sources - // if that influxdb does not exist (how to compare?) - // use sourcesStore to add this new source - // if successful - // hold onto this new source id - // if that kapacitor does not exist (how to compare?) - // use serverStore to add new kapacitor, including new source id - // else - // throw error - // else - // do nothing - */ - } - ctx := context.Background() if err := srv.Serve(ctx); err != nil { log.Fatalln(err) diff --git a/server/server.go b/server/server.go index f7e21cc8ae..25aafeec54 100644 --- a/server/server.go +++ b/server/server.go @@ -50,7 +50,7 @@ type Server struct { KapacitorUsername string `long:"kapacitor-username" description:"Username of your Kapacitor instance" env:"KAPACITOR_USERNAME"` KapacitorPassword string `long:"kapacitor-password" description:"Password of your Kapacitor instance" env:"KAPACITOR_PASSWORD"` - NewSource string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server, in JSON and surrounded by single quotes" env:"NEW_SOURCE"` + NewSources string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server, in JSON and surrounded by single quotes" env:"NEW_SOURCES"` Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` @@ -299,6 +299,16 @@ func (s *Server) Serve(ctx context.Context) error { return err } service := openService(ctx, s.BoltPath, layoutBuilder, sourcesBuilder, kapacitorBuilder, logger, s.useAuth()) + + // Add any new sources and kapacitors as specified via server flag + if err := chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, s.NewSources, logger); err != nil { + logger. + WithField("component", "server"). + WithField("NewSource", "invalid"). + Error(err) + return err + } + basepath = s.Basepath if basepath != "" && s.PrefixRoutes == false { logger. From 0c0d1a0e78dc3a9f151c4d05cdc77c533981d935 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 11:19:10 -0700 Subject: [PATCH 05/17] Log info if source already exists --- chronograf.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/chronograf.go b/chronograf.go index 24cf3ae608..443960f09e 100644 --- a/chronograf.go +++ b/chronograf.go @@ -658,6 +658,10 @@ func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore Ser for _, src := range srcs { if src.Name == srcKap.Source.Name { isNewSource = false + logger. + WithField("component", "server"). + WithField("NewSource", src.Name). + Info("Source already exists") break } } From abff00f88fea0470f4e10de6858abe75baef5f84 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 11:43:10 -0700 Subject: [PATCH 06/17] Add sample usage Make flag identifier plural since JSON array of objects --- server/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index 25aafeec54..b78fd26a0c 100644 --- a/server/server.go +++ b/server/server.go @@ -50,7 +50,7 @@ type Server struct { KapacitorUsername string `long:"kapacitor-username" description:"Username of your Kapacitor instance" env:"KAPACITOR_USERNAME"` KapacitorPassword string `long:"kapacitor-password" description:"Password of your Kapacitor instance" env:"KAPACITOR_PASSWORD"` - NewSources string `long:"new-source" description:"Config for adding a new InfluxDb source and Kapacitor server, in JSON and surrounded by single quotes" env:"NEW_SOURCES"` + NewSources string `long:"new-sources" description:"Config for adding a new InfluxDb source and Kapacitor server, in JSON as an array of objects, and surrounded by single quotes. E.g. --new-sources='[{\"influxdb\":{\"name\":\"Influx 1\",\"username\":\"user1\",\"password\":\"pass1\",\"url\":\"http://localhost:8086\",\"metaUrl\":\"http://metaurl.com\",\"insecureSkipVerify\":false,\"default\":true,\"telegraf\":\"telegraf\"},\"kapacitor\":{\"name\":\"Kapa 1\",\"url\":\"http://localhost:9092\",\"active\":true}}]'" env:"NEW_SOURCES"` Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` From 3c3602a724d1ce9cede299c50c1f76b8d2099999 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 11:48:14 -0700 Subject: [PATCH 07/17] Update error messages to use plural --- chronograf.go | 4 ++-- server/server.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chronograf.go b/chronograf.go index 443960f09e..bb81cc8f62 100644 --- a/chronograf.go +++ b/chronograf.go @@ -641,7 +641,7 @@ func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore Ser if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { logger. WithField("component", "server"). - WithField("NewSource", "invalid"). + WithField("NewSources", "invalid"). Error(err) } else { srcs, err := sourcesStore.All(ctx) @@ -660,7 +660,7 @@ func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore Ser isNewSource = false logger. WithField("component", "server"). - WithField("NewSource", src.Name). + WithField("NewSources", src.Name). Info("Source already exists") break } diff --git a/server/server.go b/server/server.go index b78fd26a0c..3024c08b9b 100644 --- a/server/server.go +++ b/server/server.go @@ -304,7 +304,7 @@ func (s *Server) Serve(ctx context.Context) error { if err := chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, s.NewSources, logger); err != nil { logger. WithField("component", "server"). - WithField("NewSource", "invalid"). + WithField("NewSources", "invalid"). Error(err) return err } From 340ed6f40e83e933fe45c63f5f9b68654eccc5ad Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 11:57:02 -0700 Subject: [PATCH 08/17] Move throwaway parsing type into NewSources --- chronograf.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/chronograf.go b/chronograf.go index bb81cc8f62..58bf31bd1e 100644 --- a/chronograf.go +++ b/chronograf.go @@ -626,17 +626,16 @@ type LayoutStore interface { Update(context.Context, Layout) error } -// SourceAndKapacitor allows a --new-source to be parsed into a source and a kapacitor -type SourceAndKapacitor struct { - Source Source `json:"influxdb"` - Kapacitor Server `json:"kapacitor"` -} - // NewSources adds sources and respective kapacitors to BoltDb idempotently by name func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, newSources string, logger Logger) error { // Once a bolt connection is created, try to add any new sources with respective kapacitor servers if newSources != "" { + type SourceAndKapacitor struct { + Source Source `json:"influxdb"` + Kapacitor Server `json:"kapacitor"` + } var srcsKaps []SourceAndKapacitor + // On JSON unmarshal error, continue server process without new source and write error to log if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { logger. From f49badf4f0a8bcb637691d97435e2955a5a964ca Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 12:04:34 -0700 Subject: [PATCH 09/17] Clean up conditionals --- chronograf.go | 102 +++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/chronograf.go b/chronograf.go index 58bf31bd1e..1923160968 100644 --- a/chronograf.go +++ b/chronograf.go @@ -628,66 +628,64 @@ type LayoutStore interface { // NewSources adds sources and respective kapacitors to BoltDb idempotently by name func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, newSources string, logger Logger) error { - // Once a bolt connection is created, try to add any new sources with respective kapacitor servers - if newSources != "" { - type SourceAndKapacitor struct { - Source Source `json:"influxdb"` - Kapacitor Server `json:"kapacitor"` + if newSources == "" { + return nil + } + + type SourceAndKapacitor struct { + Source Source `json:"influxdb"` + Kapacitor Server `json:"kapacitor"` + } + var srcsKaps []SourceAndKapacitor + // On JSON unmarshal error, continue server process without new source and write error to log + if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { + return err + } + + srcs, err := sourcesStore.All(ctx) + if err != nil { + return err + } + kaps, err := serversStore.All(ctx) + if err != nil { + return err + } + + for _, srcKap := range srcsKaps { + isNewSource := true + for _, src := range srcs { + if src.Name == srcKap.Source.Name { + isNewSource = false + logger. + WithField("component", "server"). + WithField("NewSources", src.Name). + Info("Source already exists") + break + } } - var srcsKaps []SourceAndKapacitor - - // On JSON unmarshal error, continue server process without new source and write error to log - if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { - logger. - WithField("component", "server"). - WithField("NewSources", "invalid"). - Error(err) - } else { - srcs, err := sourcesStore.All(ctx) - if err != nil { - return err - } - kaps, err := serversStore.All(ctx) + if isNewSource == true { + src, err := sourcesStore.Add(ctx, srcKap.Source) if err != nil { return err } - for _, srcKap := range srcsKaps { - isNewSource := true - for _, src := range srcs { - if src.Name == srcKap.Source.Name { - isNewSource = false - logger. - WithField("component", "server"). - WithField("NewSources", src.Name). - Info("Source already exists") - break - } - } - if isNewSource == true { - src, err := sourcesStore.Add(ctx, srcKap.Source) - if err != nil { - return err - } - - isNewKapacitor := true - for _, kap := range kaps { - if kap.Name == srcKap.Kapacitor.Name { - isNewKapacitor = false - break - } - } - if isNewKapacitor == true { - srcKap.Kapacitor.SrcID = src.ID - _, err := serversStore.Add(ctx, srcKap.Kapacitor) - if err != nil { - return err - } - } - // TODO: if Kapa is not new, should it be updated to point to this source ID? + isNewKapacitor := true + for _, kap := range kaps { + if kap.Name == srcKap.Kapacitor.Name { + isNewKapacitor = false + break } } + if isNewKapacitor == true { + srcKap.Kapacitor.SrcID = src.ID + _, err := serversStore.Add(ctx, srcKap.Kapacitor) + if err != nil { + return err + } + } + // TODO: if Kapa is not new, should it be updated to point to this source ID? } } + return nil } From ac0598f95cf09e68afbf1c3ac5270043807737a5 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 12:05:05 -0700 Subject: [PATCH 10/17] Allow server to run even if NewSources errors out --- server/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index 3024c08b9b..dac6059289 100644 --- a/server/server.go +++ b/server/server.go @@ -301,12 +301,12 @@ func (s *Server) Serve(ctx context.Context) error { service := openService(ctx, s.BoltPath, layoutBuilder, sourcesBuilder, kapacitorBuilder, logger, s.useAuth()) // Add any new sources and kapacitors as specified via server flag - if err := chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, s.NewSources, logger); err != nil { + if err = chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, s.NewSources, logger); err != nil { + // Continue with server run even if adding NewSources fails logger. WithField("component", "server"). WithField("NewSources", "invalid"). Error(err) - return err } basepath = s.Basepath From c4555921038db6469f1d4dc60cdbccae578ab4aa Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 12:18:33 -0700 Subject: [PATCH 11/17] Remove check on already existing Kapacitor Clean up conditionals by refactoring to use loop label. Incidentally this also fixed a bug that would not allow a Kapacitor server to be added by the same name as one that already existed, allowing the check to be removed as well. --- chronograf.go | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/chronograf.go b/chronograf.go index 1923160968..1d26219557 100644 --- a/chronograf.go +++ b/chronograf.go @@ -646,44 +646,29 @@ func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore Ser if err != nil { return err } - kaps, err := serversStore.All(ctx) - if err != nil { - return err - } +SourceLoop: for _, srcKap := range srcsKaps { - isNewSource := true for _, src := range srcs { + // If source already exists, do nothing if src.Name == srcKap.Source.Name { - isNewSource = false logger. WithField("component", "server"). WithField("NewSources", src.Name). Info("Source already exists") - break + continue SourceLoop } } - if isNewSource == true { - src, err := sourcesStore.Add(ctx, srcKap.Source) - if err != nil { - return err - } - isNewKapacitor := true - for _, kap := range kaps { - if kap.Name == srcKap.Kapacitor.Name { - isNewKapacitor = false - break - } - } - if isNewKapacitor == true { - srcKap.Kapacitor.SrcID = src.ID - _, err := serversStore.Add(ctx, srcKap.Kapacitor) - if err != nil { - return err - } - } - // TODO: if Kapa is not new, should it be updated to point to this source ID? + src, err := sourcesStore.Add(ctx, srcKap.Source) + if err != nil { + return err + } + + srcKap.Kapacitor.SrcID = src.ID + _, err = serversStore.Add(ctx, srcKap.Kapacitor) + if err != nil { + return err } } From e61ffaa6a36791718264d3207acd50a612792c12 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 13:47:39 -0700 Subject: [PATCH 12/17] Clarify comment --- chronograf.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chronograf.go b/chronograf.go index 1d26219557..54108e9b93 100644 --- a/chronograf.go +++ b/chronograf.go @@ -626,7 +626,7 @@ type LayoutStore interface { Update(context.Context, Layout) error } -// NewSources adds sources and respective kapacitors to BoltDb idempotently by name +// NewSources adds sources to BoltDb idempotently by name, as well as respective kapacitors func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, newSources string, logger Logger) error { if newSources == "" { return nil From d7e73f55adc7978df1dddbd454fcc0c86a8432e6 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 14:12:07 -0700 Subject: [PATCH 13/17] Move NewSources input prep to server Signed-off-by: Tim Raymond --- chronograf.go | 22 +++++++--------------- server/server.go | 32 ++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/chronograf.go b/chronograf.go index 54108e9b93..d31cb7b85c 100644 --- a/chronograf.go +++ b/chronograf.go @@ -626,22 +626,14 @@ type LayoutStore interface { Update(context.Context, Layout) error } +// SourceAndKapacitor is used to parse any NewSources server flag arguments +type SourceAndKapacitor struct { + Source Source `json:"influxdb"` + Kapacitor Server `json:"kapacitor"` +} + // NewSources adds sources to BoltDb idempotently by name, as well as respective kapacitors -func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, newSources string, logger Logger) error { - if newSources == "" { - return nil - } - - type SourceAndKapacitor struct { - Source Source `json:"influxdb"` - Kapacitor Server `json:"kapacitor"` - } - var srcsKaps []SourceAndKapacitor - // On JSON unmarshal error, continue server process without new source and write error to log - if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { - return err - } - +func NewSources(ctx context.Context, sourcesStore SourcesStore, serversStore ServersStore, srcsKaps []SourceAndKapacitor, logger Logger) error { srcs, err := sourcesStore.All(ctx) if err != nil { return err diff --git a/server/server.go b/server/server.go index dac6059289..245aeba9c1 100644 --- a/server/server.go +++ b/server/server.go @@ -3,6 +3,7 @@ package server import ( "context" "crypto/tls" + "encoding/json" "log" "math/rand" "net" @@ -300,14 +301,29 @@ func (s *Server) Serve(ctx context.Context) error { } service := openService(ctx, s.BoltPath, layoutBuilder, sourcesBuilder, kapacitorBuilder, logger, s.useAuth()) - // Add any new sources and kapacitors as specified via server flag - if err = chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, s.NewSources, logger); err != nil { - // Continue with server run even if adding NewSources fails - logger. - WithField("component", "server"). - WithField("NewSources", "invalid"). - Error(err) - } + go func() { + if s.NewSources == "" { + return + } + + var srcsKaps []chronograf.SourceAndKapacitor + // On JSON unmarshal error, continue server process without new source and write error to log + if err := json.Unmarshal([]byte(s.NewSources), &srcsKaps); err != nil { + logger. + WithField("component", "server"). + WithField("NewSources", "invalid"). + Error(err) + } + + // Add any new sources and kapacitors as specified via server flag + if err = chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, srcsKaps, logger); err != nil { + // Continue with server run even if adding NewSources fails + logger. + WithField("component", "server"). + WithField("NewSources", "invalid"). + Error(err) + } + }() basepath = s.Basepath if basepath != "" && s.PrefixRoutes == false { From 10c317c083dd3d94a2024d1ac1968a9877b21d43 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 14:27:14 -0700 Subject: [PATCH 14/17] Refactor process new sources into named func --- server/server.go | 52 +++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/server/server.go b/server/server.go index 245aeba9c1..8f4b2ca21f 100644 --- a/server/server.go +++ b/server/server.go @@ -301,29 +301,7 @@ func (s *Server) Serve(ctx context.Context) error { } service := openService(ctx, s.BoltPath, layoutBuilder, sourcesBuilder, kapacitorBuilder, logger, s.useAuth()) - go func() { - if s.NewSources == "" { - return - } - - var srcsKaps []chronograf.SourceAndKapacitor - // On JSON unmarshal error, continue server process without new source and write error to log - if err := json.Unmarshal([]byte(s.NewSources), &srcsKaps); err != nil { - logger. - WithField("component", "server"). - WithField("NewSources", "invalid"). - Error(err) - } - - // Add any new sources and kapacitors as specified via server flag - if err = chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, srcsKaps, logger); err != nil { - // Continue with server run even if adding NewSources fails - logger. - WithField("component", "server"). - WithField("NewSources", "invalid"). - Error(err) - } - }() + go processNewSources(ctx, service, s.NewSources, logger) basepath = s.Basepath if basepath != "" && s.PrefixRoutes == false { @@ -458,6 +436,34 @@ func openService(ctx context.Context, boltPath string, lBuilder LayoutBuilder, s } } +// processNewSources parses and persists new sources passed in via server flag. +// It's used within a goroutine so its return is negligible. +func processNewSources(ctx context.Context, service Service, newSources string, logger chronograf.Logger) error { + if newSources == "" { + return nil + } + + var srcsKaps []chronograf.SourceAndKapacitor + // On JSON unmarshal error, continue server process without new source and write error to log + if err := json.Unmarshal([]byte(newSources), &srcsKaps); err != nil { + logger. + WithField("component", "server"). + WithField("NewSources", "invalid"). + Error(err) + } + + // Add any new sources and kapacitors as specified via server flag + if err := chronograf.NewSources(ctx, service.SourcesStore, service.ServersStore, srcsKaps, logger); err != nil { + // Continue with server run even if adding NewSources fails + logger. + WithField("component", "server"). + WithField("NewSources", "invalid"). + Error(err) + } + + return nil +} + // reportUsageStats starts periodic server reporting. func reportUsageStats(bi BuildInfo, logger chronograf.Logger) { rand.Seed(time.Now().UTC().UnixNano()) From fea0a330eb9d66e36462bf5dc0dd9b38691e66f5 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Thu, 6 Jul 2017 15:04:04 -0700 Subject: [PATCH 15/17] Correct comment --- server/server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index 8f4b2ca21f..2e48d9a2d1 100644 --- a/server/server.go +++ b/server/server.go @@ -436,8 +436,7 @@ func openService(ctx context.Context, boltPath string, lBuilder LayoutBuilder, s } } -// processNewSources parses and persists new sources passed in via server flag. -// It's used within a goroutine so its return is negligible. +// processNewSources parses and persists new sources passed in via server flag func processNewSources(ctx context.Context, service Service, newSources string, logger chronograf.Logger) error { if newSources == "" { return nil From 12f1a8ce4b88b60c56c1bedc22aec8f85d9207a4 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Fri, 7 Jul 2017 12:56:12 -0700 Subject: [PATCH 16/17] Add test for creating NewSources via server flag Move TestLogger to mocks Signed-off-by: Tim Raymond --- chronograf_test.go | 88 ++++++++++++++++++++++++ server/server_test.go => mocks/logger.go | 2 +- mocks/servers.go | 38 ++++++++++ server/url_prefixer_test.go | 3 +- 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 chronograf_test.go rename server/server_test.go => mocks/logger.go (98%) create mode 100644 mocks/servers.go diff --git a/chronograf_test.go b/chronograf_test.go new file mode 100644 index 0000000000..bed0c4f40d --- /dev/null +++ b/chronograf_test.go @@ -0,0 +1,88 @@ +package chronograf_test + +import ( + "context" + "reflect" + "testing" + + "github.com/influxdata/chronograf" + "github.com/influxdata/chronograf/mocks" +) + +func Test_NewSources(t *testing.T) { + t.Parallel() + + srcsKaps := []chronograf.SourceAndKapacitor{ + { + Source: chronograf.Source{ + Default: true, + InsecureSkipVerify: false, + MetaURL: "http://metaurl.com", + Name: "Influx 1", + Password: "pass1", + Telegraf: "telegraf", + URL: "http://localhost:8086", + Username: "user1", + }, + Kapacitor: chronograf.Server{ + Active: true, + Name: "Kapa 1", + URL: "http://localhost:9092", + }, + }, + } + saboteurSrcsKaps := []chronograf.SourceAndKapacitor{ + { + Source: chronograf.Source{ + Name: "Influx 1", + }, + Kapacitor: chronograf.Server{ + Name: "Kapa Aspiring Saboteur", + }, + }, + } + + ctx := context.Background() + srcs := []chronograf.Source{} + srcsStore := mocks.SourcesStore{ + AllF: func(ctx context.Context) ([]chronograf.Source, error) { + return srcs, nil + }, + AddF: func(ctx context.Context, src chronograf.Source) (chronograf.Source, error) { + srcs = append(srcs, src) + return src, nil + }, + } + srvs := []chronograf.Server{} + srvsStore := mocks.ServersStore{ + AddF: func(ctx context.Context, srv chronograf.Server) (chronograf.Server, error) { + srvs = append(srvs, srv) + return srv, nil + }, + } + + err := chronograf.NewSources(ctx, &srcsStore, &srvsStore, srcsKaps, &mocks.TestLogger{}) + if err != nil { + t.Fatal("Expected no error when creating New Sources. Error:", err) + } + if len(srcs) != 1 { + t.Error("Expected one source in sourcesStore") + } + if len(srvs) != 1 { + t.Error("Expected one source in serversStore") + } + + err = chronograf.NewSources(ctx, &srcsStore, &srvsStore, saboteurSrcsKaps, &mocks.TestLogger{}) + if err != nil { + t.Fatal("Expected no error when creating New Sources. Error:", err) + } + if len(srcs) != 1 { + t.Error("Expected one source in sourcesStore") + } + if len(srvs) != 1 { + t.Error("Expected one source in serversStore") + } + if !reflect.DeepEqual(srcs[0], srcsKaps[0].Source) { + t.Error("Expected source in sourceStore to remain unchanged") + } +} diff --git a/server/server_test.go b/mocks/logger.go similarity index 98% rename from server/server_test.go rename to mocks/logger.go index 22330e851e..46c7bae9f6 100644 --- a/server/server_test.go +++ b/mocks/logger.go @@ -1,4 +1,4 @@ -package server_test +package mocks import ( "fmt" diff --git a/mocks/servers.go b/mocks/servers.go new file mode 100644 index 0000000000..837c0a3b1a --- /dev/null +++ b/mocks/servers.go @@ -0,0 +1,38 @@ +package mocks + +import ( + "context" + + "github.com/influxdata/chronograf" +) + +var _ chronograf.ServersStore = &ServersStore{} + +// ServersStore mock allows all functions to be set for testing +type ServersStore struct { + AllF func(context.Context) ([]chronograf.Server, error) + AddF func(context.Context, chronograf.Server) (chronograf.Server, error) + DeleteF func(context.Context, chronograf.Server) error + GetF func(ctx context.Context, ID int) (chronograf.Server, error) + UpdateF func(context.Context, chronograf.Server) error +} + +func (s *ServersStore) All(ctx context.Context) ([]chronograf.Server, error) { + return s.AllF(ctx) +} + +func (s *ServersStore) Add(ctx context.Context, srv chronograf.Server) (chronograf.Server, error) { + return s.AddF(ctx, srv) +} + +func (s *ServersStore) Delete(ctx context.Context, srv chronograf.Server) error { + return s.DeleteF(ctx, srv) +} + +func (s *ServersStore) Get(ctx context.Context, id int) (chronograf.Server, error) { + return s.GetF(ctx, id) +} + +func (s *ServersStore) Update(ctx context.Context, srv chronograf.Server) error { + return s.UpdateF(ctx, srv) +} diff --git a/server/url_prefixer_test.go b/server/url_prefixer_test.go index 619b304d2c..d1cf66678b 100644 --- a/server/url_prefixer_test.go +++ b/server/url_prefixer_test.go @@ -7,6 +7,7 @@ import ( "net/http/httptest" "testing" + "github.com/influxdata/chronograf/mocks" "github.com/influxdata/chronograf/server" ) @@ -138,7 +139,7 @@ func Test_Server_Prefixer_NoPrefixingWithoutFlusther(t *testing.T) { }) } - tl := &TestLogger{} + tl := &mocks.TestLogger{} pfx := &server.URLPrefixer{ Prefix: "/hill", Next: backend, From 4ce7e950a0740dddfa2990fba3ad20fe30eb1ab7 Mon Sep 17 00:00:00 2001 From: Jared Scheib Date: Fri, 7 Jul 2017 13:14:01 -0700 Subject: [PATCH 17/17] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63a208f4dc..1eb8e3508e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Features 1. [#1645](https://github.com/influxdata/chronograf/pull/1645): Add Auth0 as a supported OAuth2 provider 1. [#1660](https://github.com/influxdata/chronograf/pull/1660): Add ability to add custom links to User menu via server CLI or ENV vars +1. [#1695](https://github.com/influxdata/chronograf/pull/1695): Add server flag for adding new InfluxDb sources with Kapacitor servers ### UI Improvements 1. [#1644](https://github.com/influxdata/chronograf/pull/1644): Redesign Alerts History table to have sticky headers