diff --git a/pkg/api/admin.go b/pkg/api/admin.go index 52d271ce69b..54a86724f0c 100644 --- a/pkg/api/admin.go +++ b/pkg/api/admin.go @@ -12,7 +12,7 @@ import ( func AdminGetSettings(c *m.ReqContext) { settings := make(map[string]interface{}) - for _, section := range setting.Cfg.Sections() { + for _, section := range setting.Raw.Sections() { jsonSec := make(map[string]interface{}) settings[section.Name()] = jsonSec diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 8d1d0dc0a60..fa27eabbf24 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -35,9 +35,10 @@ type HTTPServer struct { context context.Context streamManager *live.StreamManager cache *gocache.Cache - RouteRegister RouteRegister `inject:""` + httpSrv *http.Server - httpSrv *http.Server + RouteRegister RouteRegister `inject:""` + Bus bus.Bus `inject:""` } func (hs *HTTPServer) Init() { diff --git a/pkg/cmd/grafana-cli/commands/commands.go b/pkg/cmd/grafana-cli/commands/commands.go index d8f01bbdcab..43484749670 100644 --- a/pkg/cmd/grafana-cli/commands/commands.go +++ b/pkg/cmd/grafana-cli/commands/commands.go @@ -15,7 +15,8 @@ func runDbCommand(command func(commandLine CommandLine) error) func(context *cli return func(context *cli.Context) { cmd := &contextCommandLine{context} - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ Config: cmd.String("config"), HomePath: cmd.String("homepath"), Args: flag.Args(), diff --git a/pkg/cmd/grafana-server/server.go b/pkg/cmd/grafana-server/server.go index 86cbe51dd22..911cf092b47 100644 --- a/pkg/cmd/grafana-server/server.go +++ b/pkg/cmd/grafana-server/server.go @@ -49,6 +49,7 @@ func NewGrafanaServer() *GrafanaServerImpl { shutdownFn: shutdownFn, childRoutines: childRoutines, log: log.New("server"), + cfg: setting.NewCfg(), } } @@ -57,28 +58,29 @@ type GrafanaServerImpl struct { shutdownFn context.CancelFunc childRoutines *errgroup.Group log log.Logger + cfg *setting.Cfg RouteRegister api.RouteRegister `inject:""` HttpServer *api.HTTPServer `inject:""` } func (g *GrafanaServerImpl) Start() error { - g.initLogging() + g.loadConfiguration() g.writePIDFile() // initSql sqlstore.NewEngine() // TODO: this should return an error sqlstore.EnsureAdminUser() - metrics.Init(setting.Cfg) + metrics.Init(g.cfg.Raw) login.Init() social.NewOAuthService() - if err := provisioning.Init(g.context, setting.HomePath, setting.Cfg); err != nil { + if err := provisioning.Init(g.context, setting.HomePath, g.cfg.Raw); err != nil { return fmt.Errorf("Failed to provision Grafana from config. error: %v", err) } - tracingCloser, err := tracing.Init(setting.Cfg) + tracingCloser, err := tracing.Init(g.cfg.Raw) if err != nil { return fmt.Errorf("Tracing settings is not valid. error: %v", err) } @@ -86,6 +88,7 @@ func (g *GrafanaServerImpl) Start() error { serviceGraph := inject.Graph{} serviceGraph.Provide(&inject.Object{Value: bus.GetBus()}) + serviceGraph.Provide(&inject.Object{Value: g.cfg}) serviceGraph.Provide(&inject.Object{Value: dashboards.NewProvisioningService()}) serviceGraph.Provide(&inject.Object{Value: api.NewRouteRegister(middleware.RequestMetrics, middleware.RequestTracing)}) serviceGraph.Provide(&inject.Object{Value: api.HTTPServer{}}) @@ -138,8 +141,8 @@ func (g *GrafanaServerImpl) Start() error { return g.startHttpServer() } -func (g *GrafanaServerImpl) initLogging() { - err := setting.NewConfigContext(&setting.CommandLineArgs{ +func (g *GrafanaServerImpl) loadConfiguration() { + err := g.cfg.Load(&setting.CommandLineArgs{ Config: *configFile, HomePath: *homePath, Args: flag.Args(), @@ -151,7 +154,7 @@ func (g *GrafanaServerImpl) initLogging() { } g.log.Info("Starting "+setting.ApplicationName, "version", version, "commit", commit, "compiled", time.Unix(setting.BuildStamp, 0)) - setting.LogConfigurationInfo() + g.cfg.LogConfigSources() } func (g *GrafanaServerImpl) startHttpServer() error { diff --git a/pkg/components/imguploader/azureblobuploader_test.go b/pkg/components/imguploader/azureblobuploader_test.go index ca978f70e3d..c0c7889a155 100644 --- a/pkg/components/imguploader/azureblobuploader_test.go +++ b/pkg/components/imguploader/azureblobuploader_test.go @@ -10,7 +10,8 @@ import ( func TestUploadToAzureBlob(t *testing.T) { SkipConvey("[Integration test] for external_image_store.azure_blob", t, func() { - err := setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + err := cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) So(err, ShouldBeNil) diff --git a/pkg/components/imguploader/gcsuploader_test.go b/pkg/components/imguploader/gcsuploader_test.go index bdc21084dbf..58cb21c184c 100644 --- a/pkg/components/imguploader/gcsuploader_test.go +++ b/pkg/components/imguploader/gcsuploader_test.go @@ -10,7 +10,8 @@ import ( func TestUploadToGCS(t *testing.T) { SkipConvey("[Integration test] for external_image_store.gcs", t, func() { - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) diff --git a/pkg/components/imguploader/imguploader.go b/pkg/components/imguploader/imguploader.go index 52a31f9f606..93f69cadd46 100644 --- a/pkg/components/imguploader/imguploader.go +++ b/pkg/components/imguploader/imguploader.go @@ -3,9 +3,10 @@ package imguploader import ( "context" "fmt" - "github.com/grafana/grafana/pkg/log" "regexp" + "github.com/grafana/grafana/pkg/log" + "github.com/grafana/grafana/pkg/setting" ) @@ -24,7 +25,7 @@ func NewImageUploader() (ImageUploader, error) { switch setting.ImageUploadProvider { case "s3": - s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec, err := setting.Raw.GetSection("external_image_storage.s3") if err != nil { return nil, err } @@ -51,7 +52,7 @@ func NewImageUploader() (ImageUploader, error) { return NewS3Uploader(region, bucket, path, "public-read", accessKey, secretKey), nil case "webdav": - webdavSec, err := setting.Cfg.GetSection("external_image_storage.webdav") + webdavSec, err := setting.Raw.GetSection("external_image_storage.webdav") if err != nil { return nil, err } @@ -67,7 +68,7 @@ func NewImageUploader() (ImageUploader, error) { return NewWebdavImageUploader(url, username, password, public_url) case "gcs": - gcssec, err := setting.Cfg.GetSection("external_image_storage.gcs") + gcssec, err := setting.Raw.GetSection("external_image_storage.gcs") if err != nil { return nil, err } @@ -78,7 +79,7 @@ func NewImageUploader() (ImageUploader, error) { return NewGCSUploader(keyFile, bucketName, path), nil case "azure_blob": - azureBlobSec, err := setting.Cfg.GetSection("external_image_storage.azure_blob") + azureBlobSec, err := setting.Raw.GetSection("external_image_storage.azure_blob") if err != nil { return nil, err } diff --git a/pkg/components/imguploader/imguploader_test.go b/pkg/components/imguploader/imguploader_test.go index b272a45e7a5..570e36a47e3 100644 --- a/pkg/components/imguploader/imguploader_test.go +++ b/pkg/components/imguploader/imguploader_test.go @@ -11,14 +11,15 @@ import ( func TestImageUploaderFactory(t *testing.T) { Convey("Can create image uploader for ", t, func() { Convey("S3ImageUploader config", func() { - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) setting.ImageUploadProvider = "s3" Convey("with bucket url https://foo.bar.baz.s3-us-east-2.amazonaws.com", func() { - s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec, err := setting.Raw.GetSection("external_image_storage.s3") So(err, ShouldBeNil) s3sec.NewKey("bucket_url", "https://foo.bar.baz.s3-us-east-2.amazonaws.com") s3sec.NewKey("access_key", "access_key") @@ -37,7 +38,7 @@ func TestImageUploaderFactory(t *testing.T) { }) Convey("with bucket url https://s3.amazonaws.com/mybucket", func() { - s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec, err := setting.Raw.GetSection("external_image_storage.s3") So(err, ShouldBeNil) s3sec.NewKey("bucket_url", "https://s3.amazonaws.com/my.bucket.com") s3sec.NewKey("access_key", "access_key") @@ -56,7 +57,7 @@ func TestImageUploaderFactory(t *testing.T) { }) Convey("with bucket url https://s3-us-west-2.amazonaws.com/mybucket", func() { - s3sec, err := setting.Cfg.GetSection("external_image_storage.s3") + s3sec, err := setting.Raw.GetSection("external_image_storage.s3") So(err, ShouldBeNil) s3sec.NewKey("bucket_url", "https://s3-us-west-2.amazonaws.com/my.bucket.com") s3sec.NewKey("access_key", "access_key") @@ -77,13 +78,14 @@ func TestImageUploaderFactory(t *testing.T) { Convey("Webdav uploader", func() { var err error - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) setting.ImageUploadProvider = "webdav" - webdavSec, err := setting.Cfg.GetSection("external_image_storage.webdav") + webdavSec, err := cfg.Raw.GetSection("external_image_storage.webdav") So(err, ShouldBeNil) webdavSec.NewKey("url", "webdavUrl") webdavSec.NewKey("username", "username") @@ -103,13 +105,14 @@ func TestImageUploaderFactory(t *testing.T) { Convey("GCS uploader", func() { var err error - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) setting.ImageUploadProvider = "gcs" - gcpSec, err := setting.Cfg.GetSection("external_image_storage.gcs") + gcpSec, err := cfg.Raw.GetSection("external_image_storage.gcs") So(err, ShouldBeNil) gcpSec.NewKey("key_file", "/etc/secrets/project-79a52befa3f6.json") gcpSec.NewKey("bucket", "project-grafana-east") @@ -124,13 +127,14 @@ func TestImageUploaderFactory(t *testing.T) { }) Convey("AzureBlobUploader config", func() { - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) setting.ImageUploadProvider = "azure_blob" Convey("with container name", func() { - azureBlobSec, err := setting.Cfg.GetSection("external_image_storage.azure_blob") + azureBlobSec, err := cfg.Raw.GetSection("external_image_storage.azure_blob") So(err, ShouldBeNil) azureBlobSec.NewKey("account_name", "account_name") azureBlobSec.NewKey("account_key", "account_key") @@ -150,7 +154,8 @@ func TestImageUploaderFactory(t *testing.T) { Convey("Local uploader", func() { var err error - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) diff --git a/pkg/components/imguploader/s3uploader_test.go b/pkg/components/imguploader/s3uploader_test.go index b02d4676b5e..0e43740ef9b 100644 --- a/pkg/components/imguploader/s3uploader_test.go +++ b/pkg/components/imguploader/s3uploader_test.go @@ -10,7 +10,8 @@ import ( func TestUploadToS3(t *testing.T) { SkipConvey("[Integration test] for external_image_store.s3", t, func() { - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) diff --git a/pkg/metrics/settings.go b/pkg/metrics/settings.go index 5e51f85768a..c21e7279b7e 100644 --- a/pkg/metrics/settings.go +++ b/pkg/metrics/settings.go @@ -46,7 +46,7 @@ func ReadSettings(file *ini.File) *MetricSettings { } func parseGraphiteSettings(settings *MetricSettings, file *ini.File) (*graphitebridge.Config, error) { - graphiteSection, err := setting.Cfg.GetSection("metrics.graphite") + graphiteSection, err := setting.Raw.GetSection("metrics.graphite") if err != nil { return nil, nil } diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go index d8460a1875c..6f31b49f99d 100644 --- a/pkg/plugins/dashboard_importer_test.go +++ b/pkg/plugins/dashboard_importer_test.go @@ -87,8 +87,8 @@ func TestDashboardImport(t *testing.T) { func pluginScenario(desc string, t *testing.T, fn func()) { Convey("Given a plugin", t, func() { - setting.Cfg = ini.Empty() - sec, _ := setting.Cfg.NewSection("plugin.test-app") + setting.Raw = ini.Empty() + sec, _ := setting.Raw.NewSection("plugin.test-app") sec.NewKey("path", "../../tests/test-app") pm := &PluginManager{} diff --git a/pkg/plugins/dashboards_test.go b/pkg/plugins/dashboards_test.go index 241e41d7bb2..c422a1431c0 100644 --- a/pkg/plugins/dashboards_test.go +++ b/pkg/plugins/dashboards_test.go @@ -14,8 +14,8 @@ import ( func TestPluginDashboards(t *testing.T) { Convey("When asking plugin dashboard info", t, func() { - setting.Cfg = ini.Empty() - sec, _ := setting.Cfg.NewSection("plugin.test-app") + setting.Raw = ini.Empty() + sec, _ := setting.Raw.NewSection("plugin.test-app") sec.NewKey("path", "../../tests/test-app") pm := &PluginManager{} diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index aa4131ae06d..5096bf5cebc 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -132,7 +132,7 @@ func (pm *PluginManager) Run(ctx context.Context) error { } func checkPluginPaths() error { - for _, section := range setting.Cfg.Sections() { + for _, section := range setting.Raw.Sections() { if strings.HasPrefix(section.Name(), "plugin.") { path := section.Key("path").String() if path != "" { diff --git a/pkg/plugins/plugins_test.go b/pkg/plugins/plugins_test.go index 7566d054b7f..fa68ae4389d 100644 --- a/pkg/plugins/plugins_test.go +++ b/pkg/plugins/plugins_test.go @@ -13,7 +13,7 @@ func TestPluginScans(t *testing.T) { Convey("When scanning for plugins", t, func() { setting.StaticRootPath, _ = filepath.Abs("../../public/") - setting.Cfg = ini.Empty() + setting.Raw = ini.Empty() pm := &PluginManager{} err := pm.Init() @@ -28,8 +28,8 @@ func TestPluginScans(t *testing.T) { }) Convey("When reading app plugin definition", t, func() { - setting.Cfg = ini.Empty() - sec, _ := setting.Cfg.NewSection("plugin.nginx-app") + setting.Raw = ini.Empty() + sec, _ := setting.Raw.NewSection("plugin.nginx-app") sec.NewKey("path", "../../tests/test-app") pm := &PluginManager{} diff --git a/pkg/services/cleanup/cleanup.go b/pkg/services/cleanup/cleanup.go index ef474fd2eb2..69bc7695dea 100644 --- a/pkg/services/cleanup/cleanup.go +++ b/pkg/services/cleanup/cleanup.go @@ -16,42 +16,43 @@ import ( type CleanUpService struct { log log.Logger + Cfg *setting.Cfg `inject:""` } func init() { registry.RegisterService(&CleanUpService{}) } -func (service *CleanUpService) Init() error { - service.log = log.New("cleanup") +func (srv *CleanUpService) Init() error { + srv.log = log.New("cleanup") return nil } -func (service *CleanUpService) Run(ctx context.Context) error { - service.cleanUpTmpFiles() +func (srv *CleanUpService) Run(ctx context.Context) error { + srv.cleanUpTmpFiles() ticker := time.NewTicker(time.Minute * 10) for { select { case <-ticker.C: - service.cleanUpTmpFiles() - service.deleteExpiredSnapshots() - service.deleteExpiredDashboardVersions() - service.deleteOldLoginAttempts() + srv.cleanUpTmpFiles() + srv.deleteExpiredSnapshots() + srv.deleteExpiredDashboardVersions() + srv.deleteOldLoginAttempts() case <-ctx.Done(): return ctx.Err() } } } -func (service *CleanUpService) cleanUpTmpFiles() { - if _, err := os.Stat(setting.ImagesDir); os.IsNotExist(err) { +func (srv *CleanUpService) cleanUpTmpFiles() { + if _, err := os.Stat(srv.Cfg.ImagesDir); os.IsNotExist(err) { return } - files, err := ioutil.ReadDir(setting.ImagesDir) + files, err := ioutil.ReadDir(srv.Cfg.ImagesDir) if err != nil { - service.log.Error("Problem reading image dir", "error", err) + srv.log.Error("Problem reading image dir", "error", err) return } @@ -63,36 +64,36 @@ func (service *CleanUpService) cleanUpTmpFiles() { } for _, file := range toDelete { - fullPath := path.Join(setting.ImagesDir, file.Name()) + fullPath := path.Join(srv.Cfg.ImagesDir, file.Name()) err := os.Remove(fullPath) if err != nil { - service.log.Error("Failed to delete temp file", "file", file.Name(), "error", err) + srv.log.Error("Failed to delete temp file", "file", file.Name(), "error", err) } } - service.log.Debug("Found old rendered image to delete", "deleted", len(toDelete), "keept", len(files)) + srv.log.Debug("Found old rendered image to delete", "deleted", len(toDelete), "keept", len(files)) } -func (service *CleanUpService) deleteExpiredSnapshots() { +func (srv *CleanUpService) deleteExpiredSnapshots() { cmd := m.DeleteExpiredSnapshotsCommand{} if err := bus.Dispatch(&cmd); err != nil { - service.log.Error("Failed to delete expired snapshots", "error", err.Error()) + srv.log.Error("Failed to delete expired snapshots", "error", err.Error()) } else { - service.log.Debug("Deleted expired snapshots", "rows affected", cmd.DeletedRows) + srv.log.Debug("Deleted expired snapshots", "rows affected", cmd.DeletedRows) } } -func (service *CleanUpService) deleteExpiredDashboardVersions() { +func (srv *CleanUpService) deleteExpiredDashboardVersions() { cmd := m.DeleteExpiredVersionsCommand{} if err := bus.Dispatch(&cmd); err != nil { - service.log.Error("Failed to delete expired dashboard versions", "error", err.Error()) + srv.log.Error("Failed to delete expired dashboard versions", "error", err.Error()) } else { - service.log.Debug("Deleted old/expired dashboard versions", "rows affected", cmd.DeletedRows) + srv.log.Debug("Deleted old/expired dashboard versions", "rows affected", cmd.DeletedRows) } } -func (service *CleanUpService) deleteOldLoginAttempts() { - if setting.DisableBruteForceLoginProtection { +func (srv *CleanUpService) deleteOldLoginAttempts() { + if srv.Cfg.DisableBruteForceLoginProtection { return } @@ -100,8 +101,8 @@ func (service *CleanUpService) deleteOldLoginAttempts() { OlderThan: time.Now().Add(time.Minute * -10), } if err := bus.Dispatch(&cmd); err != nil { - service.log.Error("Problem deleting expired login attempts", "error", err.Error()) + srv.log.Error("Problem deleting expired login attempts", "error", err.Error()) } else { - service.log.Debug("Deleted expired login attempts", "rows affected", cmd.DeletedRows) + srv.log.Debug("Deleted expired login attempts", "rows affected", cmd.DeletedRows) } } diff --git a/pkg/services/notifications/mailer.go b/pkg/services/notifications/mailer.go index 37169661d73..4730ef7f0f1 100644 --- a/pkg/services/notifications/mailer.go +++ b/pkg/services/notifications/mailer.go @@ -17,8 +17,8 @@ import ( gomail "gopkg.in/mail.v2" ) -func send(msg *Message) (int, error) { - dialer, err := createDialer() +func (ns *NotificationService) send(msg *Message) (int, error) { + dialer, err := ns.createDialer() if err != nil { return 0, err } @@ -42,8 +42,8 @@ func send(msg *Message) (int, error) { return len(msg.To), nil } -func createDialer() (*gomail.Dialer, error) { - host, port, err := net.SplitHostPort(setting.Smtp.Host) +func (ns *NotificationService) createDialer() (*gomail.Dialer, error) { + host, port, err := net.SplitHostPort(ns.Cfg.Smtp.Host) if err != nil { return nil, err @@ -54,30 +54,31 @@ func createDialer() (*gomail.Dialer, error) { } tlsconfig := &tls.Config{ - InsecureSkipVerify: setting.Smtp.SkipVerify, + InsecureSkipVerify: ns.Cfg.Smtp.SkipVerify, ServerName: host, } - if setting.Smtp.CertFile != "" { - cert, err := tls.LoadX509KeyPair(setting.Smtp.CertFile, setting.Smtp.KeyFile) + if ns.Cfg.Smtp.CertFile != "" { + cert, err := tls.LoadX509KeyPair(ns.Cfg.Smtp.CertFile, ns.Cfg.Smtp.KeyFile) if err != nil { return nil, fmt.Errorf("Could not load cert or key file. error: %v", err) } tlsconfig.Certificates = []tls.Certificate{cert} } - d := gomail.NewDialer(host, iPort, setting.Smtp.User, setting.Smtp.Password) + d := gomail.NewDialer(host, iPort, ns.Cfg.Smtp.User, ns.Cfg.Smtp.Password) d.TLSConfig = tlsconfig - if setting.Smtp.EhloIdentity != "" { - d.LocalName = setting.Smtp.EhloIdentity + + if ns.Cfg.Smtp.EhloIdentity != "" { + d.LocalName = ns.Cfg.Smtp.EhloIdentity } else { d.LocalName = setting.InstanceName } return d, nil } -func buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) { - if !setting.Smtp.Enabled { +func (ns *NotificationService) buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) { + if !ns.Cfg.Smtp.Enabled { return nil, m.ErrSmtpNotEnabled } @@ -121,7 +122,7 @@ func buildEmailMessage(cmd *m.SendEmailCommand) (*Message, error) { return &Message{ To: cmd.To, - From: fmt.Sprintf("%s <%s>", setting.Smtp.FromName, setting.Smtp.FromAddress), + From: fmt.Sprintf("%s <%s>", ns.Cfg.Smtp.FromName, ns.Cfg.Smtp.FromAddress), Subject: subject, Body: buffer.String(), EmbededFiles: cmd.EmbededFiles, diff --git a/pkg/services/notifications/notifications.go b/pkg/services/notifications/notifications.go index ad776057ad7..ee54e7269f7 100644 --- a/pkg/services/notifications/notifications.go +++ b/pkg/services/notifications/notifications.go @@ -28,7 +28,9 @@ func init() { } type NotificationService struct { - Bus bus.Bus `inject:""` + Bus bus.Bus `inject:""` + Cfg *setting.Cfg `inject:""` + mailQueue chan *Message webhookQueue chan *Webhook log log.Logger @@ -54,13 +56,13 @@ func (ns *NotificationService) Init() error { "Subject": subjectTemplateFunc, }) - templatePattern := filepath.Join(setting.StaticRootPath, setting.Smtp.TemplatesPattern) + templatePattern := filepath.Join(setting.StaticRootPath, ns.Cfg.Smtp.TemplatesPattern) _, err := mailTemplates.ParseGlob(templatePattern) if err != nil { return err } - if !util.IsEmail(setting.Smtp.FromAddress) { + if !util.IsEmail(ns.Cfg.Smtp.FromAddress) { return errors.New("Invalid email address for SMTP from_address config") } @@ -81,7 +83,7 @@ func (ns *NotificationService) Run(ctx context.Context) error { ns.log.Error("Failed to send webrequest ", "error", err) } case msg := <-ns.mailQueue: - num, err := send(msg) + num, err := ns.send(msg) tos := strings.Join(msg.To, "; ") info := "" if err != nil { @@ -117,7 +119,7 @@ func subjectTemplateFunc(obj map[string]interface{}, value string) string { } func (ns *NotificationService) sendEmailCommandHandlerSync(ctx context.Context, cmd *m.SendEmailCommandSync) error { - message, err := buildEmailMessage(&m.SendEmailCommand{ + message, err := ns.buildEmailMessage(&m.SendEmailCommand{ Data: cmd.Data, Info: cmd.Info, Template: cmd.Template, @@ -130,12 +132,12 @@ func (ns *NotificationService) sendEmailCommandHandlerSync(ctx context.Context, return err } - _, err = send(message) + _, err = ns.send(message) return err } func (ns *NotificationService) sendEmailCommandHandler(cmd *m.SendEmailCommand) error { - message, err := buildEmailMessage(cmd) + message, err := ns.buildEmailMessage(cmd) if err != nil { return err @@ -205,7 +207,7 @@ func (ns *NotificationService) signUpStartedHandler(evt *events.SignUpStarted) e } func (ns *NotificationService) signUpCompletedHandler(evt *events.SignUpCompleted) error { - if evt.Email == "" || !setting.Smtp.SendWelcomeEmailOnSignUp { + if evt.Email == "" || !ns.Cfg.Smtp.SendWelcomeEmailOnSignUp { return nil } diff --git a/pkg/services/notifications/notifications_test.go b/pkg/services/notifications/notifications_test.go index a86bd3b19ed..504c10c22ec 100644 --- a/pkg/services/notifications/notifications_test.go +++ b/pkg/services/notifications/notifications_test.go @@ -19,13 +19,14 @@ func TestNotifications(t *testing.T) { Convey("Given the notifications service", t, func() { setting.StaticRootPath = "../../../public/" - setting.Smtp.Enabled = true - setting.Smtp.TemplatesPattern = "emails/*.html" - setting.Smtp.FromAddress = "from@address.com" - setting.Smtp.FromName = "Grafana Admin" ns := &NotificationService{} ns.Bus = bus.New() + ns.Cfg = setting.NewCfg() + ns.Cfg.Smtp.Enabled = true + ns.Cfg.Smtp.TemplatesPattern = "emails/*.html" + ns.Cfg.Smtp.FromAddress = "from@address.com" + ns.Cfg.Smtp.FromName = "Grafana Admin" err := ns.Init() So(err, ShouldBeNil) diff --git a/pkg/services/notifications/send_email_integration_test.go b/pkg/services/notifications/send_email_integration_test.go index a9f37018a3a..201f86036d3 100644 --- a/pkg/services/notifications/send_email_integration_test.go +++ b/pkg/services/notifications/send_email_integration_test.go @@ -13,14 +13,15 @@ import ( func TestEmailIntegrationTest(t *testing.T) { SkipConvey("Given the notifications service", t, func() { setting.StaticRootPath = "../../../public/" - setting.Smtp.Enabled = true - setting.Smtp.TemplatesPattern = "emails/*.html" - setting.Smtp.FromAddress = "from@address.com" - setting.Smtp.FromName = "Grafana Admin" setting.BuildVersion = "4.0.0" ns := &NotificationService{} ns.Bus = bus.New() + ns.Cfg = setting.NewCfg() + ns.Cfg.Smtp.Enabled = true + ns.Cfg.Smtp.TemplatesPattern = "emails/*.html" + ns.Cfg.Smtp.FromAddress = "from@address.com" + ns.Cfg.Smtp.FromName = "Grafana Admin" err := ns.Init() So(err, ShouldBeNil) diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index e4be3208c86..b804d8b1621 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -168,7 +168,7 @@ func getEngine() (*xorm.Engine, error) { engine.SetMaxOpenConns(DbCfg.MaxOpenConn) engine.SetMaxIdleConns(DbCfg.MaxIdleConn) engine.SetConnMaxLifetime(time.Second * time.Duration(DbCfg.ConnMaxLifetime)) - debugSql := setting.Cfg.Section("database").Key("log_queries").MustBool(false) + debugSql := setting.Raw.Section("database").Key("log_queries").MustBool(false) if !debugSql { engine.SetLogger(&xorm.DiscardLogger{}) } else { @@ -181,7 +181,7 @@ func getEngine() (*xorm.Engine, error) { } func LoadConfig() { - sec := setting.Cfg.Section("database") + sec := setting.Raw.Section("database") cfgURL := sec.Key("url").String() if len(cfgURL) != 0 { diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 922eea607d1..40d7522f775 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -137,7 +137,7 @@ var ( SessionConnMaxLifetime int64 // Global setting objects. - Cfg *ini.File + Raw *ini.File ConfRootPath string IsWindows bool @@ -160,9 +160,6 @@ var ( LdapConfigFile string LdapAllowSignup = true - // SMTP email settings - Smtp SmtpSettings - // QUOTA Quota QuotaSettings @@ -187,6 +184,16 @@ var ( ImageUploadProvider string ) +type Cfg struct { + Raw *ini.File + + // SMTP email settings + Smtp SmtpSettings + + ImagesDir string + DisableBruteForceLoginProtection bool +} + type CommandLineArgs struct { Config string HomePath string @@ -228,9 +235,9 @@ func shouldRedactURLKey(s string) bool { return strings.Contains(uppercased, "DATABASE_URL") } -func applyEnvVariableOverrides() error { +func applyEnvVariableOverrides(file *ini.File) error { appliedEnvOverrides = make([]string, 0) - for _, section := range Cfg.Sections() { + for _, section := range file.Sections() { for _, key := range section.Keys() { sectionName := strings.ToUpper(strings.Replace(section.Name(), ".", "_", -1)) keyName := strings.ToUpper(strings.Replace(key.Name(), ".", "_", -1)) @@ -264,9 +271,9 @@ func applyEnvVariableOverrides() error { return nil } -func applyCommandLineDefaultProperties(props map[string]string) { +func applyCommandLineDefaultProperties(props map[string]string, file *ini.File) { appliedCommandLineProperties = make([]string, 0) - for _, section := range Cfg.Sections() { + for _, section := range file.Sections() { for _, key := range section.Keys() { keyString := fmt.Sprintf("default.%s.%s", section.Name(), key.Name()) value, exists := props[keyString] @@ -281,8 +288,8 @@ func applyCommandLineDefaultProperties(props map[string]string) { } } -func applyCommandLineProperties(props map[string]string) { - for _, section := range Cfg.Sections() { +func applyCommandLineProperties(props map[string]string, file *ini.File) { + for _, section := range file.Sections() { sectionName := section.Name() + "." if section.Name() == ini.DEFAULT_SECTION { sectionName = "" @@ -341,15 +348,15 @@ func evalEnvVarExpression(value string) string { }) } -func evalConfigValues() { - for _, section := range Cfg.Sections() { +func evalConfigValues(file *ini.File) { + for _, section := range file.Sections() { for _, key := range section.Keys() { key.SetValue(evalEnvVarExpression(key.Value())) } } } -func loadSpecifedConfigFile(configFile string) error { +func loadSpecifedConfigFile(configFile string, masterFile *ini.File) error { if configFile == "" { configFile = filepath.Join(HomePath, CustomInitPath) // return without error if custom file does not exist @@ -371,9 +378,9 @@ func loadSpecifedConfigFile(configFile string) error { continue } - defaultSec, err := Cfg.GetSection(section.Name()) + defaultSec, err := masterFile.GetSection(section.Name()) if err != nil { - defaultSec, _ = Cfg.NewSection(section.Name()) + defaultSec, _ = masterFile.NewSection(section.Name()) } defaultKey, err := defaultSec.GetKey(key.Name()) if err != nil { @@ -387,7 +394,7 @@ func loadSpecifedConfigFile(configFile string) error { return nil } -func loadConfiguration(args *CommandLineArgs) error { +func loadConfiguration(args *CommandLineArgs) (*ini.File, error) { var err error // load config defaults @@ -401,44 +408,44 @@ func loadConfiguration(args *CommandLineArgs) error { } // load defaults - Cfg, err = ini.Load(defaultConfigFile) + parsedFile, err := ini.Load(defaultConfigFile) if err != nil { fmt.Println(fmt.Sprintf("Failed to parse defaults.ini, %v", err)) os.Exit(1) - return err + return nil, err } - Cfg.BlockMode = false + parsedFile.BlockMode = false // command line props commandLineProps := getCommandLineProperties(args.Args) // load default overrides - applyCommandLineDefaultProperties(commandLineProps) + applyCommandLineDefaultProperties(commandLineProps, parsedFile) // load specified config file - err = loadSpecifedConfigFile(args.Config) + err = loadSpecifedConfigFile(args.Config, parsedFile) if err != nil { - initLogging() + initLogging(parsedFile) log.Fatal(3, err.Error()) } // apply environment overrides - err = applyEnvVariableOverrides() + err = applyEnvVariableOverrides(parsedFile) if err != nil { - return err + return nil, err } // apply command line overrides - applyCommandLineProperties(commandLineProps) + applyCommandLineProperties(commandLineProps, parsedFile) // evaluate config values containing environment variables - evalConfigValues() + evalConfigValues(parsedFile) // update data path and logging config - DataPath = makeAbsolute(Cfg.Section("paths").Key("data").String(), HomePath) - initLogging() + DataPath = makeAbsolute(parsedFile.Section("paths").Key("data").String(), HomePath) + initLogging(parsedFile) - return err + return parsedFile, err } func pathExists(path string) bool { @@ -484,23 +491,33 @@ func validateStaticRootPath() error { return nil } -func NewConfigContext(args *CommandLineArgs) error { +func NewCfg() *Cfg { + return &Cfg{} +} + +func (cfg *Cfg) Load(args *CommandLineArgs) error { setHomePath(args) - err := loadConfiguration(args) + + iniFile, err := loadConfiguration(args) if err != nil { return err } + cfg.Raw = iniFile + + // Temporary keep global, to make refactor in steps + Raw = cfg.Raw + ApplicationName = "Grafana" if Enterprise { ApplicationName += " Enterprise" } - Env = Cfg.Section("").Key("app_mode").MustString("development") - InstanceName = Cfg.Section("").Key("instance_name").MustString("unknown_instance_name") - PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath) - ProvisioningPath = makeAbsolute(Cfg.Section("paths").Key("provisioning").String(), HomePath) - server := Cfg.Section("server") + Env = iniFile.Section("").Key("app_mode").MustString("development") + InstanceName = iniFile.Section("").Key("instance_name").MustString("unknown_instance_name") + PluginsPath = makeAbsolute(iniFile.Section("paths").Key("plugins").String(), HomePath) + ProvisioningPath = makeAbsolute(iniFile.Section("paths").Key("provisioning").String(), HomePath) + server := iniFile.Section("server") AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server) Protocol = HTTP @@ -528,27 +545,28 @@ func NewConfigContext(args *CommandLineArgs) error { } // read data proxy settings - dataproxy := Cfg.Section("dataproxy") + dataproxy := iniFile.Section("dataproxy") DataProxyLogging = dataproxy.Key("logging").MustBool(false) // read security settings - security := Cfg.Section("security") + security := iniFile.Section("security") SecretKey = security.Key("secret_key").String() LogInRememberDays = security.Key("login_remember_days").MustInt() CookieUserName = security.Key("cookie_username").String() CookieRememberName = security.Key("cookie_remember_name").String() DisableGravatar = security.Key("disable_gravatar").MustBool(true) - DisableBruteForceLoginProtection = security.Key("disable_brute_force_login_protection").MustBool(false) + cfg.DisableBruteForceLoginProtection = security.Key("disable_brute_force_login_protection").MustBool(false) + DisableBruteForceLoginProtection = cfg.DisableBruteForceLoginProtection // read snapshots settings - snapshots := Cfg.Section("snapshots") + snapshots := iniFile.Section("snapshots") ExternalSnapshotUrl = snapshots.Key("external_snapshot_url").String() ExternalSnapshotName = snapshots.Key("external_snapshot_name").String() ExternalEnabled = snapshots.Key("external_enabled").MustBool(true) SnapShotRemoveExpired = snapshots.Key("snapshot_remove_expired").MustBool(true) // read dashboard settings - dashboards := Cfg.Section("dashboards") + dashboards := iniFile.Section("dashboards") DashboardVersionsToKeep = dashboards.Key("versions_to_keep").MustInt(20) // read data source proxy white list @@ -561,7 +579,7 @@ func NewConfigContext(args *CommandLineArgs) error { AdminUser = security.Key("admin_user").String() AdminPassword = security.Key("admin_password").String() - users := Cfg.Section("users") + users := iniFile.Section("users") AllowUserSignUp = users.Key("allow_sign_up").MustBool(true) AllowUserOrgCreate = users.Key("allow_org_create").MustBool(true) AutoAssignOrg = users.Key("auto_assign_org").MustBool(true) @@ -575,17 +593,17 @@ func NewConfigContext(args *CommandLineArgs) error { ViewersCanEdit = users.Key("viewers_can_edit").MustBool(false) // auth - auth := Cfg.Section("auth") + auth := iniFile.Section("auth") DisableLoginForm = auth.Key("disable_login_form").MustBool(false) DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false) // anonymous access - AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false) - AnonymousOrgName = Cfg.Section("auth.anonymous").Key("org_name").String() - AnonymousOrgRole = Cfg.Section("auth.anonymous").Key("org_role").String() + AnonymousEnabled = iniFile.Section("auth.anonymous").Key("enabled").MustBool(false) + AnonymousOrgName = iniFile.Section("auth.anonymous").Key("org_name").String() + AnonymousOrgRole = iniFile.Section("auth.anonymous").Key("org_role").String() // auth proxy - authProxy := Cfg.Section("auth.proxy") + authProxy := iniFile.Section("auth.proxy") AuthProxyEnabled = authProxy.Key("enabled").MustBool(false) AuthProxyHeaderName = authProxy.Key("header_name").String() AuthProxyHeaderProperty = authProxy.Key("header_property").String() @@ -594,63 +612,64 @@ func NewConfigContext(args *CommandLineArgs) error { AuthProxyWhitelist = authProxy.Key("whitelist").String() // basic auth - authBasic := Cfg.Section("auth.basic") + authBasic := iniFile.Section("auth.basic") BasicAuthEnabled = authBasic.Key("enabled").MustBool(true) // global plugin settings - PluginAppsSkipVerifyTLS = Cfg.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false) + PluginAppsSkipVerifyTLS = iniFile.Section("plugins").Key("app_tls_skip_verify_insecure").MustBool(false) // PhantomJS rendering - ImagesDir = filepath.Join(DataPath, "png") + cfg.ImagesDir = filepath.Join(DataPath, "png") + ImagesDir = cfg.ImagesDir PhantomDir = filepath.Join(HomePath, "tools/phantomjs") - analytics := Cfg.Section("analytics") + analytics := iniFile.Section("analytics") ReportingEnabled = analytics.Key("reporting_enabled").MustBool(true) CheckForUpdates = analytics.Key("check_for_updates").MustBool(true) GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String() GoogleTagManagerId = analytics.Key("google_tag_manager_id").String() - ldapSec := Cfg.Section("auth.ldap") + ldapSec := iniFile.Section("auth.ldap") LdapEnabled = ldapSec.Key("enabled").MustBool(false) LdapConfigFile = ldapSec.Key("config_file").String() LdapAllowSignup = ldapSec.Key("allow_sign_up").MustBool(true) - alerting := Cfg.Section("alerting") + alerting := iniFile.Section("alerting") AlertingEnabled = alerting.Key("enabled").MustBool(true) ExecuteAlerts = alerting.Key("execute_alerts").MustBool(true) - explore := Cfg.Section("explore") + explore := iniFile.Section("explore") ExploreEnabled = explore.Key("enabled").MustBool(false) - readSessionConfig() - readSmtpSettings() - readQuotaSettings() + cfg.readSessionConfig() + cfg.readSmtpSettings() + cfg.readQuotaSettings() - if VerifyEmailEnabled && !Smtp.Enabled { + if VerifyEmailEnabled && !cfg.Smtp.Enabled { log.Warn("require_email_validation is enabled but smtp is disabled") } // check old key name - GrafanaComUrl = Cfg.Section("grafana_net").Key("url").MustString("") + GrafanaComUrl = iniFile.Section("grafana_net").Key("url").MustString("") if GrafanaComUrl == "" { - GrafanaComUrl = Cfg.Section("grafana_com").Key("url").MustString("https://grafana.com") + GrafanaComUrl = iniFile.Section("grafana_com").Key("url").MustString("https://grafana.com") } - imageUploadingSection := Cfg.Section("external_image_storage") + imageUploadingSection := iniFile.Section("external_image_storage") ImageUploadProvider = imageUploadingSection.Key("provider").MustString("") return nil } -func readSessionConfig() { - sec := Cfg.Section("session") +func (cfg *Cfg) readSessionConfig() { + sec := cfg.Raw.Section("session") SessionOptions = session.Options{} SessionOptions.Provider = sec.Key("provider").In("memory", []string{"memory", "file", "redis", "mysql", "postgres", "memcache"}) SessionOptions.ProviderConfig = strings.Trim(sec.Key("provider_config").String(), "\" ") SessionOptions.CookieName = sec.Key("cookie_name").MustString("grafana_sess") SessionOptions.CookiePath = AppSubUrl SessionOptions.Secure = sec.Key("cookie_secure").MustBool() - SessionOptions.Gclifetime = Cfg.Section("session").Key("gc_interval_time").MustInt64(86400) - SessionOptions.Maxlifetime = Cfg.Section("session").Key("session_life_time").MustInt64(86400) + SessionOptions.Gclifetime = cfg.Raw.Section("session").Key("gc_interval_time").MustInt64(86400) + SessionOptions.Maxlifetime = cfg.Raw.Section("session").Key("session_life_time").MustInt64(86400) SessionOptions.IDLength = 16 if SessionOptions.Provider == "file" { @@ -662,21 +681,21 @@ func readSessionConfig() { SessionOptions.CookiePath = "/" } - SessionConnMaxLifetime = Cfg.Section("session").Key("conn_max_lifetime").MustInt64(14400) + SessionConnMaxLifetime = cfg.Raw.Section("session").Key("conn_max_lifetime").MustInt64(14400) } -func initLogging() { +func initLogging(file *ini.File) { // split on comma - LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",") + LogModes = strings.Split(file.Section("log").Key("mode").MustString("console"), ",") // also try space if len(LogModes) == 1 { - LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), " ") + LogModes = strings.Split(file.Section("log").Key("mode").MustString("console"), " ") } - LogsPath = makeAbsolute(Cfg.Section("paths").Key("logs").String(), HomePath) - log.ReadLoggingConfig(LogModes, LogsPath, Cfg) + LogsPath = makeAbsolute(file.Section("paths").Key("logs").String(), HomePath) + log.ReadLoggingConfig(LogModes, LogsPath, file) } -func LogConfigurationInfo() { +func (cfg *Cfg) LogConfigSources() { var text bytes.Buffer for _, file := range configFiles { diff --git a/pkg/setting/setting_quota.go b/pkg/setting/setting_quota.go index 49769d9930f..c3a509219db 100644 --- a/pkg/setting/setting_quota.go +++ b/pkg/setting/setting_quota.go @@ -63,9 +63,9 @@ type QuotaSettings struct { Global *GlobalQuota } -func readQuotaSettings() { +func (cfg *Cfg) readQuotaSettings() { // set global defaults. - quota := Cfg.Section("quota") + quota := cfg.Raw.Section("quota") Quota.Enabled = quota.Key("enabled").MustBool(false) // per ORG Limits diff --git a/pkg/setting/setting_smtp.go b/pkg/setting/setting_smtp.go index 9d8b8a529a5..5df774dc691 100644 --- a/pkg/setting/setting_smtp.go +++ b/pkg/setting/setting_smtp.go @@ -16,20 +16,20 @@ type SmtpSettings struct { TemplatesPattern string } -func readSmtpSettings() { - sec := Cfg.Section("smtp") - Smtp.Enabled = sec.Key("enabled").MustBool(false) - Smtp.Host = sec.Key("host").String() - Smtp.User = sec.Key("user").String() - Smtp.Password = sec.Key("password").String() - Smtp.CertFile = sec.Key("cert_file").String() - Smtp.KeyFile = sec.Key("key_file").String() - Smtp.FromAddress = sec.Key("from_address").String() - Smtp.FromName = sec.Key("from_name").String() - Smtp.EhloIdentity = sec.Key("ehlo_identity").String() - Smtp.SkipVerify = sec.Key("skip_verify").MustBool(false) +func (cfg *Cfg) readSmtpSettings() { + sec := cfg.Raw.Section("smtp") + cfg.Smtp.Enabled = sec.Key("enabled").MustBool(false) + cfg.Smtp.Host = sec.Key("host").String() + cfg.Smtp.User = sec.Key("user").String() + cfg.Smtp.Password = sec.Key("password").String() + cfg.Smtp.CertFile = sec.Key("cert_file").String() + cfg.Smtp.KeyFile = sec.Key("key_file").String() + cfg.Smtp.FromAddress = sec.Key("from_address").String() + cfg.Smtp.FromName = sec.Key("from_name").String() + cfg.Smtp.EhloIdentity = sec.Key("ehlo_identity").String() + cfg.Smtp.SkipVerify = sec.Key("skip_verify").MustBool(false) - emails := Cfg.Section("emails") - Smtp.SendWelcomeEmailOnSignUp = emails.Key("welcome_email_on_sign_up").MustBool(false) - Smtp.TemplatesPattern = emails.Key("templates_pattern").MustString("emails/*.html") + emails := cfg.Raw.Section("emails") + cfg.Smtp.SendWelcomeEmailOnSignUp = emails.Key("welcome_email_on_sign_up").MustBool(false) + cfg.Smtp.TemplatesPattern = emails.Key("templates_pattern").MustString("emails/*.html") } diff --git a/pkg/setting/setting_test.go b/pkg/setting/setting_test.go index 2da728b7298..9de22c86811 100644 --- a/pkg/setting/setting_test.go +++ b/pkg/setting/setting_test.go @@ -15,7 +15,8 @@ func TestLoadingSettings(t *testing.T) { skipStaticRootValidation = true Convey("Given the default ini files", func() { - err := NewConfigContext(&CommandLineArgs{HomePath: "../../"}) + cfg := NewCfg() + err := cfg.Load(&CommandLineArgs{HomePath: "../../"}) So(err, ShouldBeNil) So(AdminUser, ShouldEqual, "admin") @@ -23,7 +24,9 @@ func TestLoadingSettings(t *testing.T) { Convey("Should be able to override via environment variables", func() { os.Setenv("GF_SECURITY_ADMIN_USER", "superduper") - NewConfigContext(&CommandLineArgs{HomePath: "../../"}) + + cfg := NewCfg() + cfg.Load(&CommandLineArgs{HomePath: "../../"}) So(AdminUser, ShouldEqual, "superduper") So(DataPath, ShouldEqual, filepath.Join(HomePath, "data")) @@ -32,21 +35,27 @@ func TestLoadingSettings(t *testing.T) { Convey("Should replace password when defined in environment", func() { os.Setenv("GF_SECURITY_ADMIN_PASSWORD", "supersecret") - NewConfigContext(&CommandLineArgs{HomePath: "../../"}) + + cfg := NewCfg() + cfg.Load(&CommandLineArgs{HomePath: "../../"}) So(appliedEnvOverrides, ShouldContain, "GF_SECURITY_ADMIN_PASSWORD=*********") }) Convey("Should return an error when url is invalid", func() { os.Setenv("GF_DATABASE_URL", "postgres.%31://grafana:secret@postgres:5432/grafana") - err := NewConfigContext(&CommandLineArgs{HomePath: "../../"}) + + cfg := NewCfg() + err := cfg.Load(&CommandLineArgs{HomePath: "../../"}) So(err, ShouldNotBeNil) }) Convey("Should replace password in URL when url environment is defined", func() { os.Setenv("GF_DATABASE_URL", "mysql://user:secret@localhost:3306/database") - NewConfigContext(&CommandLineArgs{HomePath: "../../"}) + + cfg := NewCfg() + cfg.Load(&CommandLineArgs{HomePath: "../../"}) So(appliedEnvOverrides, ShouldContain, "GF_DATABASE_URL=mysql://user:-redacted-@localhost:3306/database") }) @@ -61,14 +70,16 @@ func TestLoadingSettings(t *testing.T) { Convey("Should be able to override via command line", func() { if runtime.GOOS == "windows" { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Args: []string{`cfg:paths.data=c:\tmp\data`, `cfg:paths.logs=c:\tmp\logs`}, }) So(DataPath, ShouldEqual, `c:\tmp\data`) So(LogsPath, ShouldEqual, `c:\tmp\logs`) } else { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Args: []string{"cfg:paths.data=/tmp/data", "cfg:paths.logs=/tmp/logs"}, }) @@ -79,7 +90,8 @@ func TestLoadingSettings(t *testing.T) { }) Convey("Should be able to override defaults via command line", func() { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Args: []string{ "cfg:default.server.domain=test2", @@ -92,7 +104,8 @@ func TestLoadingSettings(t *testing.T) { Convey("Defaults can be overridden in specified config file", func() { if runtime.GOOS == "windows" { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Config: filepath.Join(HomePath, "tests/config-files/override_windows.ini"), Args: []string{`cfg:default.paths.data=c:\tmp\data`}, @@ -100,7 +113,8 @@ func TestLoadingSettings(t *testing.T) { So(DataPath, ShouldEqual, `c:\tmp\override`) } else { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Config: filepath.Join(HomePath, "tests/config-files/override.ini"), Args: []string{"cfg:default.paths.data=/tmp/data"}, @@ -112,7 +126,8 @@ func TestLoadingSettings(t *testing.T) { Convey("Command line overrides specified config file", func() { if runtime.GOOS == "windows" { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Config: filepath.Join(HomePath, "tests/config-files/override_windows.ini"), Args: []string{`cfg:paths.data=c:\tmp\data`}, @@ -120,7 +135,8 @@ func TestLoadingSettings(t *testing.T) { So(DataPath, ShouldEqual, `c:\tmp\data`) } else { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Config: filepath.Join(HomePath, "tests/config-files/override.ini"), Args: []string{"cfg:paths.data=/tmp/data"}, @@ -133,7 +149,8 @@ func TestLoadingSettings(t *testing.T) { Convey("Can use environment variables in config values", func() { if runtime.GOOS == "windows" { os.Setenv("GF_DATA_PATH", `c:\tmp\env_override`) - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Args: []string{"cfg:paths.data=${GF_DATA_PATH}"}, }) @@ -141,7 +158,8 @@ func TestLoadingSettings(t *testing.T) { So(DataPath, ShouldEqual, `c:\tmp\env_override`) } else { os.Setenv("GF_DATA_PATH", "/tmp/env_override") - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", Args: []string{"cfg:paths.data=${GF_DATA_PATH}"}, }) @@ -151,7 +169,8 @@ func TestLoadingSettings(t *testing.T) { }) Convey("instance_name default to hostname even if hostname env is empty", func() { - NewConfigContext(&CommandLineArgs{ + cfg := NewCfg() + cfg.Load(&CommandLineArgs{ HomePath: "../../", }) diff --git a/pkg/social/social.go b/pkg/social/social.go index 8f0618b7f74..adbe5a912d9 100644 --- a/pkg/social/social.go +++ b/pkg/social/social.go @@ -58,7 +58,7 @@ func NewOAuthService() { allOauthes := []string{"github", "google", "generic_oauth", "grafananet", "grafana_com"} for _, name := range allOauthes { - sec := setting.Cfg.Section("auth." + name) + sec := setting.Raw.Section("auth." + name) info := &setting.OAuthInfo{ ClientId: sec.Key("client_id").String(), ClientSecret: sec.Key("client_secret").String(), diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index 921996d155d..79b01f70c9b 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -32,7 +32,7 @@ func Init(file *ini.File) (io.Closer, error) { func parseSettings(file *ini.File) *TracingSettings { settings := &TracingSettings{} - var section, err = setting.Cfg.GetSection("tracing.jaeger") + var section, err = setting.Raw.GetSection("tracing.jaeger") if err != nil { return settings } diff --git a/pkg/tsdb/influxdb/response_parser_test.go b/pkg/tsdb/influxdb/response_parser_test.go index a517cf4d71f..d8ec6e145c7 100644 --- a/pkg/tsdb/influxdb/response_parser_test.go +++ b/pkg/tsdb/influxdb/response_parser_test.go @@ -13,7 +13,8 @@ func TestInfluxdbResponseParser(t *testing.T) { Convey("Response parser", func() { parser := &ResponseParser{} - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../../", }) diff --git a/pkg/tsdb/interval_test.go b/pkg/tsdb/interval_test.go index 1e36e5428fe..941b08dd554 100644 --- a/pkg/tsdb/interval_test.go +++ b/pkg/tsdb/interval_test.go @@ -10,7 +10,8 @@ import ( func TestInterval(t *testing.T) { Convey("Default interval ", t, func() { - setting.NewConfigContext(&setting.CommandLineArgs{ + cfg := setting.NewCfg() + cfg.Load(&setting.CommandLineArgs{ HomePath: "../../", })