mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
remote_write: allow passing along custom HTTP headers (#8416)
* remote_write: allow passing along custom HTTP headers Signed-off-by: Nandor Kracser <bonifaido@gmail.com> * add warning Signed-off-by: Nandor Kracser <bonifaido@gmail.com> * remote_write: add header valadtion Signed-off-by: Nandor Kracser <bonifaido@gmail.com> * extend tests for bad remote write headers Signed-off-by: Nandor Kracser <bonifaido@gmail.com> * remote_write: add note about the authorization header Signed-off-by: Nandor Kracser <bonifaido@gmail.com>
This commit is contained in:
parent
7db09551b0
commit
509000269a
|
@ -34,6 +34,21 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`)
|
patRulePath = regexp.MustCompile(`^[^*]*(\*[^/]*)?$`)
|
||||||
|
unchangeableHeaders = map[string]struct{}{
|
||||||
|
// NOTE: authorization is checked specially,
|
||||||
|
// see RemoteWriteConfig.UnmarshalYAML.
|
||||||
|
// "authorization": {},
|
||||||
|
"host": {},
|
||||||
|
"content-encoding": {},
|
||||||
|
"content-type": {},
|
||||||
|
"x-prometheus-remote-write-version": {},
|
||||||
|
"user-agent": {},
|
||||||
|
"connection": {},
|
||||||
|
"keep-alive": {},
|
||||||
|
"proxy-authenticate": {},
|
||||||
|
"proxy-authorization": {},
|
||||||
|
"www-authenticate": {},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Load parses the YAML input s into a Config.
|
// Load parses the YAML input s into a Config.
|
||||||
|
@ -570,6 +585,7 @@ func CheckTargetAddress(address model.LabelValue) error {
|
||||||
type RemoteWriteConfig struct {
|
type RemoteWriteConfig struct {
|
||||||
URL *config.URL `yaml:"url"`
|
URL *config.URL `yaml:"url"`
|
||||||
RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"`
|
RemoteTimeout model.Duration `yaml:"remote_timeout,omitempty"`
|
||||||
|
Headers map[string]string `yaml:"headers,omitempty"`
|
||||||
WriteRelabelConfigs []*relabel.Config `yaml:"write_relabel_configs,omitempty"`
|
WriteRelabelConfigs []*relabel.Config `yaml:"write_relabel_configs,omitempty"`
|
||||||
Name string `yaml:"name,omitempty"`
|
Name string `yaml:"name,omitempty"`
|
||||||
|
|
||||||
|
@ -600,6 +616,14 @@ func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(interface{}) error) err
|
||||||
return errors.New("empty or null relabeling rule in remote write config")
|
return errors.New("empty or null relabeling rule in remote write config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for header := range c.Headers {
|
||||||
|
if strings.ToLower(header) == "authorization" {
|
||||||
|
return errors.New("authorization header must be changed via the basic_auth, bearer_token, or bearer_token_file parameter")
|
||||||
|
}
|
||||||
|
if _, ok := unchangeableHeaders[strings.ToLower(header)]; ok {
|
||||||
|
return errors.Errorf("%s is an unchangeable header", header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// The UnmarshalYAML method of HTTPClientConfig is not being called because it's not a pointer.
|
// The UnmarshalYAML method of HTTPClientConfig is not being called because it's not a pointer.
|
||||||
// We cannot make it a pointer as the parser panics for inlined pointer structs.
|
// We cannot make it a pointer as the parser panics for inlined pointer structs.
|
||||||
|
|
|
@ -102,6 +102,7 @@ var expectedConf = &Config{
|
||||||
KeyFile: filepath.FromSlash("testdata/valid_key_file"),
|
KeyFile: filepath.FromSlash("testdata/valid_key_file"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Headers: map[string]string{"name": "value"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -937,6 +938,12 @@ var expectedErrors = []struct {
|
||||||
}, {
|
}, {
|
||||||
filename: "remote_read_url_missing.bad.yml",
|
filename: "remote_read_url_missing.bad.yml",
|
||||||
errMsg: `url for remote_read is empty`,
|
errMsg: `url for remote_read is empty`,
|
||||||
|
}, {
|
||||||
|
filename: "remote_write_header.bad.yml",
|
||||||
|
errMsg: `x-prometheus-remote-write-version is an unchangeable header`,
|
||||||
|
}, {
|
||||||
|
filename: "remote_write_authorization_header.bad.yml",
|
||||||
|
errMsg: `authorization header must be changed via the basic_auth, bearer_token, or bearer_token_file parameter`,
|
||||||
}, {
|
}, {
|
||||||
filename: "remote_write_url_missing.bad.yml",
|
filename: "remote_write_url_missing.bad.yml",
|
||||||
errMsg: `url for remote_write is empty`,
|
errMsg: `url for remote_write is empty`,
|
||||||
|
|
2
config/testdata/conf.good.yml
vendored
2
config/testdata/conf.good.yml
vendored
|
@ -24,6 +24,8 @@ remote_write:
|
||||||
tls_config:
|
tls_config:
|
||||||
cert_file: valid_cert_file
|
cert_file: valid_cert_file
|
||||||
key_file: valid_key_file
|
key_file: valid_key_file
|
||||||
|
headers:
|
||||||
|
name: value
|
||||||
|
|
||||||
remote_read:
|
remote_read:
|
||||||
- url: http://remote1/read
|
- url: http://remote1/read
|
||||||
|
|
5
config/testdata/remote_write_authorization_header.bad.yml
vendored
Normal file
5
config/testdata/remote_write_authorization_header.bad.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
remote_write:
|
||||||
|
- url: localhost:9090
|
||||||
|
name: queue1
|
||||||
|
headers:
|
||||||
|
"authorization": "Basic YWxhZGRpbjpvcGVuc2VzYW1l"
|
5
config/testdata/remote_write_header.bad.yml
vendored
Normal file
5
config/testdata/remote_write_header.bad.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
remote_write:
|
||||||
|
- url: localhost:9090
|
||||||
|
name: queue1
|
||||||
|
headers:
|
||||||
|
"x-prometheus-remote-write-version": "somehack"
|
|
@ -1719,6 +1719,11 @@ url: <string>
|
||||||
# Timeout for requests to the remote write endpoint.
|
# Timeout for requests to the remote write endpoint.
|
||||||
[ remote_timeout: <duration> | default = 30s ]
|
[ remote_timeout: <duration> | default = 30s ]
|
||||||
|
|
||||||
|
# Custom HTTP headers to be sent along with each remote write request.
|
||||||
|
# Be aware that headers that are set by Prometheus itself can't be overwritten.
|
||||||
|
headers:
|
||||||
|
[ <string>: <string> ... ]
|
||||||
|
|
||||||
# List of remote write relabel configurations.
|
# List of remote write relabel configurations.
|
||||||
write_relabel_configs:
|
write_relabel_configs:
|
||||||
[ - <relabel_config> ... ]
|
[ - <relabel_config> ... ]
|
||||||
|
|
|
@ -83,6 +83,7 @@ type Client struct {
|
||||||
url *config_util.URL
|
url *config_util.URL
|
||||||
Client *http.Client
|
Client *http.Client
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
headers map[string]string
|
||||||
|
|
||||||
readQueries prometheus.Gauge
|
readQueries prometheus.Gauge
|
||||||
readQueriesTotal *prometheus.CounterVec
|
readQueriesTotal *prometheus.CounterVec
|
||||||
|
@ -94,6 +95,7 @@ type ClientConfig struct {
|
||||||
URL *config_util.URL
|
URL *config_util.URL
|
||||||
Timeout model.Duration
|
Timeout model.Duration
|
||||||
HTTPClientConfig config_util.HTTPClientConfig
|
HTTPClientConfig config_util.HTTPClientConfig
|
||||||
|
Headers map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadClient uses the SAMPLES method of remote read to read series samples from remote server.
|
// ReadClient uses the SAMPLES method of remote read to read series samples from remote server.
|
||||||
|
@ -142,6 +144,7 @@ func NewWriteClient(name string, conf *ClientConfig) (WriteClient, error) {
|
||||||
url: conf.URL,
|
url: conf.URL,
|
||||||
Client: httpClient,
|
Client: httpClient,
|
||||||
timeout: time.Duration(conf.Timeout),
|
timeout: time.Duration(conf.Timeout),
|
||||||
|
headers: conf.Headers,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +161,9 @@ func (c *Client) Store(ctx context.Context, req []byte) error {
|
||||||
// recoverable.
|
// recoverable.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for k, v := range c.headers {
|
||||||
|
httpReq.Header.Set(k, v)
|
||||||
|
}
|
||||||
httpReq.Header.Add("Content-Encoding", "snappy")
|
httpReq.Header.Add("Content-Encoding", "snappy")
|
||||||
httpReq.Header.Set("Content-Type", "application/x-protobuf")
|
httpReq.Header.Set("Content-Type", "application/x-protobuf")
|
||||||
httpReq.Header.Set("User-Agent", UserAgent)
|
httpReq.Header.Set("User-Agent", UserAgent)
|
||||||
|
|
|
@ -134,6 +134,7 @@ func (rws *WriteStorage) ApplyConfig(conf *config.Config) error {
|
||||||
URL: rwConf.URL,
|
URL: rwConf.URL,
|
||||||
Timeout: rwConf.RemoteTimeout,
|
Timeout: rwConf.RemoteTimeout,
|
||||||
HTTPClientConfig: rwConf.HTTPClientConfig,
|
HTTPClientConfig: rwConf.HTTPClientConfig,
|
||||||
|
Headers: rwConf.Headers,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in a new issue