diff --git a/component/prometheus/exporter/elasticsearch/elasticsearch.go b/component/prometheus/exporter/elasticsearch/elasticsearch.go index efe3a3b41897..9dd298643937 100644 --- a/component/prometheus/exporter/elasticsearch/elasticsearch.go +++ b/component/prometheus/exporter/elasticsearch/elasticsearch.go @@ -4,7 +4,7 @@ import ( "time" "github.com/grafana/agent/component" - commoncfg "github.com/grafana/agent/component/common/config" + commonCfg "github.com/grafana/agent/component/common/config" "github.com/grafana/agent/component/prometheus/exporter" "github.com/grafana/agent/pkg/integrations" "github.com/grafana/agent/pkg/integrations/elasticsearch_exporter" @@ -53,7 +53,7 @@ type Arguments struct { InsecureSkipVerify bool `river:"ssl_skip_verify,attr,optional"` ExportDataStreams bool `river:"data_stream,attr,optional"` ExportSLM bool `river:"slm,attr,optional"` - BasicAuth *commoncfg.BasicAuth `river:"basic_auth,block,optional"` + BasicAuth *commonCfg.BasicAuth `river:"basic_auth,block,optional"` } // SetToDefault implements river.Defaulter. @@ -80,6 +80,6 @@ func (a *Arguments) Convert() *elasticsearch_exporter.Config { InsecureSkipVerify: a.InsecureSkipVerify, ExportDataStreams: a.ExportDataStreams, ExportSLM: a.ExportSLM, - BasicAuth: a.BasicAuth, + BasicAuth: a.BasicAuth.Convert(), } } diff --git a/component/prometheus/exporter/elasticsearch/elasticsearch_test.go b/component/prometheus/exporter/elasticsearch/elasticsearch_test.go index ae90dc9d3cd8..5c71a8ac712f 100644 --- a/component/prometheus/exporter/elasticsearch/elasticsearch_test.go +++ b/component/prometheus/exporter/elasticsearch/elasticsearch_test.go @@ -4,10 +4,11 @@ import ( "testing" "time" - commoncfg "github.com/grafana/agent/component/common/config" + commonCfg "github.com/grafana/agent/component/common/config" "github.com/grafana/agent/pkg/integrations/elasticsearch_exporter" "github.com/grafana/river" "github.com/grafana/river/rivertypes" + promCfg "github.com/prometheus/common/config" "github.com/stretchr/testify/require" ) @@ -56,7 +57,7 @@ func TestRiverUnmarshal(t *testing.T) { InsecureSkipVerify: true, ExportDataStreams: true, ExportSLM: true, - BasicAuth: &commoncfg.BasicAuth{ + BasicAuth: &commonCfg.BasicAuth{ Username: "username", Password: rivertypes.Secret("pass"), }, @@ -111,9 +112,9 @@ func TestConvert(t *testing.T) { InsecureSkipVerify: true, ExportDataStreams: true, ExportSLM: true, - BasicAuth: &commoncfg.BasicAuth{ + BasicAuth: &promCfg.BasicAuth{ Username: "username", - Password: rivertypes.Secret("pass"), + Password: promCfg.Secret("pass"), }, } require.Equal(t, expected, *res) diff --git a/docs/sources/static/configuration/integrations/elasticsearch-exporter-config.md b/docs/sources/static/configuration/integrations/elasticsearch-exporter-config.md index 22f26d4f15ad..9e0f3ee0f88b 100644 --- a/docs/sources/static/configuration/integrations/elasticsearch-exporter-config.md +++ b/docs/sources/static/configuration/integrations/elasticsearch-exporter-config.md @@ -116,4 +116,12 @@ Full reference of options: # Export stats for SLM (Snapshot Lifecycle Management). [ slm: ] + + # Sets the `Authorization` header on every ES probe with the + # configured username and password. + # password and password_file are mutually exclusive. + basic_auth: + [ username: ] + [ password: ] + [ password_file: ] ``` diff --git a/pkg/integrations/elasticsearch_exporter/elasticsearch_exporter.go b/pkg/integrations/elasticsearch_exporter/elasticsearch_exporter.go index 01ef76f9f133..ab6ada42c877 100644 --- a/pkg/integrations/elasticsearch_exporter/elasticsearch_exporter.go +++ b/pkg/integrations/elasticsearch_exporter/elasticsearch_exporter.go @@ -14,11 +14,11 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" - commoncfg "github.com/grafana/agent/component/common/config" "github.com/grafana/agent/pkg/integrations" integrations_v2 "github.com/grafana/agent/pkg/integrations/v2" "github.com/grafana/agent/pkg/integrations/v2/metricsutils" "github.com/prometheus/client_golang/prometheus" + promCfg "github.com/prometheus/common/config" "github.com/prometheus-community/elasticsearch_exporter/collector" "github.com/prometheus-community/elasticsearch_exporter/pkg/clusterinfo" @@ -71,7 +71,7 @@ type Config struct { // Export stats for Snapshot Lifecycle Management ExportSLM bool `yaml:"slm,omitempty"` // BasicAuth block allows secure connection with Elasticsearch cluster via Basic-Auth - BasicAuth *commoncfg.BasicAuth `yaml:"basic_auth,omitempty"` + BasicAuth *promCfg.BasicAuth `yaml:"basic_auth,omitempty"` } // Custom http.Transport struct for Basic Auth-secured communication with ES cluster @@ -150,7 +150,15 @@ func New(logger log.Logger, c *Config) (integrations.Integration, error) { } password = strings.TrimSpace(string(buff)) } - encodedAuth := base64.StdEncoding.EncodeToString([]byte(c.BasicAuth.Username + ":" + password)) + username := string(c.BasicAuth.Username) + if len(c.BasicAuth.UsernameFile) > 0 { + buff, err := os.ReadFile(c.BasicAuth.UsernameFile) + if err != nil { + return nil, fmt.Errorf("unable to load username file %s: %w", c.BasicAuth.UsernameFile, err) + } + username = strings.TrimSpace(string(buff)) + } + encodedAuth := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) esHttpTransport.authHeader = "Basic " + encodedAuth }