From 4f1e8f5afb9c4c58c4b84d3cb11113efdb74b97a Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Mon, 2 Nov 2020 20:41:33 +0100 Subject: [PATCH 1/2] do not panic when envs are set incorrectly --- cmd/postgres_exporter/postgres_exporter.go | 83 ++++++++++++---------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/cmd/postgres_exporter/postgres_exporter.go b/cmd/postgres_exporter/postgres_exporter.go index 37795aacf..95b91b5b4 100644 --- a/cmd/postgres_exporter/postgres_exporter.go +++ b/cmd/postgres_exporter/postgres_exporter.go @@ -1561,50 +1561,51 @@ func (e *Exporter) scrapeDSN(ch chan<- prometheus.Metric, dsn string) error { // DATA_SOURCE_NAME always wins so we do not break older versions // reading secrets from files wins over secrets in environment variables // DATA_SOURCE_NAME > DATA_SOURCE_{USER|PASS}_FILE > DATA_SOURCE_{USER|PASS} -func getDataSources() []string { +func getDataSources() ([]string, error) { var dsn = os.Getenv("DATA_SOURCE_NAME") - if len(dsn) == 0 { - var user string - var pass string - var uri string + if len(dsn) != 0 { + return strings.Split(dsn, ","), nil + } - if len(os.Getenv("DATA_SOURCE_USER_FILE")) != 0 { - fileContents, err := ioutil.ReadFile(os.Getenv("DATA_SOURCE_USER_FILE")) - if err != nil { - panic(err) - } - user = strings.TrimSpace(string(fileContents)) - } else { - user = os.Getenv("DATA_SOURCE_USER") - } + var user, pass, uri string - if len(os.Getenv("DATA_SOURCE_PASS_FILE")) != 0 { - fileContents, err := ioutil.ReadFile(os.Getenv("DATA_SOURCE_PASS_FILE")) - if err != nil { - panic(err) - } - pass = strings.TrimSpace(string(fileContents)) - } else { - pass = os.Getenv("DATA_SOURCE_PASS") + dataSourceUserFile := os.Getenv("DATA_SOURCE_USER_FILE") + if len(dataSourceUserFile) != 0 { + fileContents, err := ioutil.ReadFile(dataSourceUserFile) + if err != nil { + return nil, fmt.Errorf("failed loading data source user file %s: %s", dataSourceUserFile, err.Error()) } + user = strings.TrimSpace(string(fileContents)) + } else { + user = os.Getenv("DATA_SOURCE_USER") + } - ui := url.UserPassword(user, pass).String() + dataSourcePassFile := os.Getenv("DATA_SOURCE_PASS_FILE") + if len(dataSourcePassFile) != 0 { + fileContents, err := ioutil.ReadFile(dataSourcePassFile) + if err != nil { + return nil, fmt.Errorf("failed loading data source pass file %s: %s", dataSourcePassFile, err.Error()) + } + pass = strings.TrimSpace(string(fileContents)) + } else { + pass = os.Getenv("DATA_SOURCE_PASS") + } - if len(os.Getenv("DATA_SOURCE_URI_FILE")) != 0 { - fileContents, err := ioutil.ReadFile(os.Getenv("DATA_SOURCE_URI_FILE")) - if err != nil { - panic(err) - } - uri = strings.TrimSpace(string(fileContents)) - } else { - uri = os.Getenv("DATA_SOURCE_URI") + ui := url.UserPassword(user, pass).String() + dataSrouceURIFile := os.Getenv("DATA_SOURCE_URI_FILE") + if len(dataSrouceURIFile) != 0 { + fileContents, err := ioutil.ReadFile(dataSrouceURIFile) + if err != nil { + return nil, fmt.Errorf("failed loading data source URI file %s: %s", dataSrouceURIFile, err.Error()) } + uri = strings.TrimSpace(string(fileContents)) + } else { + uri = os.Getenv("DATA_SOURCE_URI") + } - dsn = "postgresql://" + ui + "@" + uri + dsn = "postgresql://" + ui + "@" + uri - return []string{dsn} - } - return strings.Split(dsn, ",") + return []string{dsn}, nil } func contains(a []string, x string) bool { @@ -1637,19 +1638,25 @@ func main() { return } - dsn := getDataSources() + dsn, err := getDataSources() + if err != nil { + log.Fatalf("failed reading data sources: %s", err.Error()) + } + if len(dsn) == 0 { log.Fatal("couldn't find environment variables describing the datasource to use") } - exporter := NewExporter(dsn, + opts := []ExporterOpt{ DisableDefaultMetrics(*disableDefaultMetrics), DisableSettingsMetrics(*disableSettingsMetrics), AutoDiscoverDatabases(*autoDiscoverDatabases), WithUserQueriesPath(*queriesPath), WithConstantLabels(*constantLabelsList), ExcludeDatabases(*excludeDatabases), - ) + } + + exporter := NewExporter(dsn, opts...) defer func() { exporter.servers.Close() }() From b2557c42a82add00291a1e950608cfa1869c77d6 Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Mon, 2 Nov 2020 21:15:43 +0100 Subject: [PATCH 2/2] do not panic when envs are set incorrectly - fix tests --- .../postgres_exporter_test.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/cmd/postgres_exporter/postgres_exporter_test.go b/cmd/postgres_exporter/postgres_exporter_test.go index 39932ce23..8222bf9de 100644 --- a/cmd/postgres_exporter/postgres_exporter_test.go +++ b/cmd/postgres_exporter/postgres_exporter_test.go @@ -111,7 +111,11 @@ func (s *FunctionalSuite) TestEnvironmentSettingWithSecretsFiles(c *C) { var expected = "postgresql://custom_username$&+,%2F%3A;=%3F%40:custom_password$&+,%2F%3A;=%3F%40@localhost:5432/?sslmode=disable" - dsn := getDataSources() + dsn, err := getDataSources() + if err != nil { + c.Errorf("Unexpected error reading datasources") + } + if len(dsn) == 0 { c.Errorf("Expected one data source, zero found") } @@ -127,7 +131,11 @@ func (s *FunctionalSuite) TestEnvironmentSettingWithDns(c *C) { c.Assert(err, IsNil) defer UnsetEnvironment(c, "DATA_SOURCE_NAME") - dsn := getDataSources() + dsn, err := getDataSources() + if err != nil { + c.Errorf("Unexpected error reading datasources") + } + if len(dsn) == 0 { c.Errorf("Expected one data source, zero found") } @@ -151,7 +159,11 @@ func (s *FunctionalSuite) TestEnvironmentSettingWithDnsAndSecrets(c *C) { c.Assert(err, IsNil) defer UnsetEnvironment(c, "DATA_SOURCE_PASS") - dsn := getDataSources() + dsn, err := getDataSources() + if err != nil { + c.Errorf("Unexpected error reading datasources") + } + if len(dsn) == 0 { c.Errorf("Expected one data source, zero found") }