mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-10 15:14:09 +00:00
vmagent:support follow_redirects on SD level (#4286)
* vmagent:support follow_redirects on SD level
* fix follow_redirects on sd level
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4282
(cherry picked from commit b3d0ff463a
)
This commit is contained in:
parent
e3ce736ce2
commit
73a8f763a0
15 changed files with 56 additions and 23 deletions
|
@ -123,6 +123,9 @@ type HTTPClientConfig struct {
|
||||||
|
|
||||||
// Headers contains optional HTTP headers, which must be sent in the request to the server
|
// Headers contains optional HTTP headers, which must be sent in the request to the server
|
||||||
Headers []string `yaml:"headers,omitempty"`
|
Headers []string `yaml:"headers,omitempty"`
|
||||||
|
|
||||||
|
// FollowRedirects specifies whether the client should follow HTTP 3xx redirects.
|
||||||
|
FollowRedirects *bool `yaml:"follow_redirects,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProxyClientConfig represents proxy client config.
|
// ProxyClientConfig represents proxy client config.
|
||||||
|
|
|
@ -245,7 +245,6 @@ type ScrapeConfig struct {
|
||||||
MetricsPath string `yaml:"metrics_path,omitempty"`
|
MetricsPath string `yaml:"metrics_path,omitempty"`
|
||||||
HonorLabels bool `yaml:"honor_labels,omitempty"`
|
HonorLabels bool `yaml:"honor_labels,omitempty"`
|
||||||
HonorTimestamps *bool `yaml:"honor_timestamps,omitempty"`
|
HonorTimestamps *bool `yaml:"honor_timestamps,omitempty"`
|
||||||
FollowRedirects *bool `yaml:"follow_redirects,omitempty"`
|
|
||||||
Scheme string `yaml:"scheme,omitempty"`
|
Scheme string `yaml:"scheme,omitempty"`
|
||||||
Params map[string][]string `yaml:"params,omitempty"`
|
Params map[string][]string `yaml:"params,omitempty"`
|
||||||
HTTPClientConfig promauth.HTTPClientConfig `yaml:",inline"`
|
HTTPClientConfig promauth.HTTPClientConfig `yaml:",inline"`
|
||||||
|
@ -990,8 +989,8 @@ func getScrapeWorkConfig(sc *ScrapeConfig, baseDir string, globalCfg *GlobalConf
|
||||||
honorTimestamps = *sc.HonorTimestamps
|
honorTimestamps = *sc.HonorTimestamps
|
||||||
}
|
}
|
||||||
denyRedirects := false
|
denyRedirects := false
|
||||||
if sc.FollowRedirects != nil {
|
if sc.HTTPClientConfig.FollowRedirects != nil {
|
||||||
denyRedirects = !*sc.FollowRedirects
|
denyRedirects = !*sc.HTTPClientConfig.FollowRedirects
|
||||||
}
|
}
|
||||||
metricsPath := sc.MetricsPath
|
metricsPath := sc.MetricsPath
|
||||||
if metricsPath == "" {
|
if metricsPath == "" {
|
||||||
|
|
|
@ -110,7 +110,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c, err := discoveryutils.NewClient(env.ResourceManagerEndpoint, ac, sdc.ProxyURL, proxyAC)
|
c, err := discoveryutils.NewClient(env.ResourceManagerEndpoint, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create client for %q: %w", env.ResourceManagerEndpoint, err)
|
return nil, fmt.Errorf("cannot create client for %q: %w", env.ResourceManagerEndpoint, err)
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ func getRefreshTokenFunc(sdc *SDConfig, ac, proxyAC *promauth.Config, env *cloud
|
||||||
return nil, fmt.Errorf("unsupported `authentication_method: %q` only `OAuth` and `ManagedIdentity` are supported", authenticationMethod)
|
return nil, fmt.Errorf("unsupported `authentication_method: %q` only `OAuth` and `ManagedIdentity` are supported", authenticationMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
authClient, err := discoveryutils.NewClient(tokenEndpoint, ac, sdc.ProxyURL, proxyAC)
|
authClient, err := discoveryutils.NewClient(tokenEndpoint, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot build auth client: %w", err)
|
return nil, fmt.Errorf("cannot build auth client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ func TestGetVirtualMachinesSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
defer testServer.Close()
|
defer testServer.Close()
|
||||||
c, err := discoveryutils.NewClient(testServer.URL, nil, nil, nil)
|
c, err := discoveryutils.NewClient(testServer.URL, nil, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error at client create: %s", err)
|
t.Fatalf("unexpected error at client create: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ func getAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return v.(*apiConfig), nil
|
return v.(*apiConfig), nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const dropletsAPIPath = "/v2/droplets"
|
const dropletsAPIPath = "/v2/droplets"
|
||||||
|
|
|
@ -50,7 +50,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(sdc.Host, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(sdc.Host, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(sdc.Host, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(sdc.Host, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", sdc.Host, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,6 @@ func getAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return v.(*apiConfig), nil
|
return v.(*apiConfig), nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAPIResponse(cfg *apiConfig, path string) ([]byte, error) {
|
func getAPIResponse(cfg *apiConfig, path string) ([]byte, error) {
|
||||||
|
|
|
@ -44,7 +44,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
return nil, fmt.Errorf("cannot parse proxy auth config: %w", err)
|
||||||
}
|
}
|
||||||
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC)
|
client, err := discoveryutils.NewClient(apiServer, ac, sdc.ProxyURL, proxyAC, sdc.HTTPClientConfig.FollowRedirects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot create HTTP client for %q: %w", apiServer, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ type HTTPClient struct {
|
||||||
var defaultDialer = &net.Dialer{}
|
var defaultDialer = &net.Dialer{}
|
||||||
|
|
||||||
// NewClient returns new Client for the given args.
|
// NewClient returns new Client for the given args.
|
||||||
func NewClient(apiServer string, ac *promauth.Config, proxyURL *proxy.URL, proxyAC *promauth.Config) (*Client, error) {
|
func NewClient(apiServer string, ac *promauth.Config, proxyURL *proxy.URL, proxyAC *promauth.Config, followRedirects *bool) (*Client, error) {
|
||||||
u, err := url.Parse(apiServer)
|
u, err := url.Parse(apiServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse apiServer=%q: %w", apiServer, err)
|
return nil, fmt.Errorf("cannot parse apiServer=%q: %w", apiServer, err)
|
||||||
|
@ -139,6 +139,14 @@ func NewClient(apiServer string, ac *promauth.Config, proxyURL *proxy.URL, proxy
|
||||||
ac.SetHeaders(req, true)
|
ac.SetHeaders(req, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if followRedirects != nil && !*followRedirects {
|
||||||
|
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||||
|
return http.ErrUseLastResponse
|
||||||
|
}
|
||||||
|
blockingClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||||
|
return http.ErrUseLastResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
setHTTPProxyHeaders := func(req *http.Request) {}
|
setHTTPProxyHeaders := func(req *http.Request) {}
|
||||||
if proxyAC != nil {
|
if proxyAC != nil {
|
||||||
setHTTPProxyHeaders = func(req *http.Request) {
|
setHTTPProxyHeaders = func(req *http.Request) {
|
||||||
|
@ -186,7 +194,8 @@ func (c *Client) GetAPIResponse(path string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) getAPIResponseWithConcurrencyLimit(ctx context.Context, client *HTTPClient, path string,
|
func (c *Client) getAPIResponseWithConcurrencyLimit(ctx context.Context, client *HTTPClient, path string,
|
||||||
modifyRequest RequestCallback, inspectResponse ResponseCallback) ([]byte, error) {
|
modifyRequest RequestCallback, inspectResponse ResponseCallback,
|
||||||
|
) ([]byte, error) {
|
||||||
// Limit the number of concurrent API requests.
|
// Limit the number of concurrent API requests.
|
||||||
concurrencyLimitChOnce.Do(concurrencyLimitChInit)
|
concurrencyLimitChOnce.Do(concurrencyLimitChInit)
|
||||||
t := timerpool.Get(*maxWaitTime)
|
t := timerpool.Get(*maxWaitTime)
|
||||||
|
|
26
lib/promscrape/testdata/prometheus.yml
vendored
26
lib/promscrape/testdata/prometheus.yml
vendored
|
@ -1,5 +1,29 @@
|
||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: foo
|
- job_name: foo
|
||||||
|
scrape_interval: 54s
|
||||||
|
scrape_timeout: 12s
|
||||||
|
metrics_path: /foo/bar
|
||||||
|
scheme: https
|
||||||
|
honor_labels: true
|
||||||
|
honor_timestamps: false
|
||||||
|
follow_redirects: false
|
||||||
|
static_configs:
|
||||||
|
- targets: ["foo.bar", "aaa"]
|
||||||
|
labels:
|
||||||
|
x: y
|
||||||
|
__scrape_timeout__: "5s"
|
||||||
|
- job_name: file-job
|
||||||
file_sd_configs:
|
file_sd_configs:
|
||||||
- files: ["file_sd_*.yml"]
|
- files: ["file_sd_*.yml"]
|
||||||
- files: ["file_sd.json"]
|
- files: ["file_sd.json"]
|
||||||
|
- job_name: service-kubernetes
|
||||||
|
kubernetes_sd_configs:
|
||||||
|
- role: endpoints
|
||||||
|
api_server: "https://localhost:1234"
|
||||||
|
follow_redirects: true
|
||||||
|
tls_config:
|
||||||
|
cert_file: valid_cert_file
|
||||||
|
key_file: valid_key_file
|
||||||
|
basic_auth:
|
||||||
|
username: "myusername"
|
||||||
|
password: "mysecret"
|
||||||
|
|
Loading…
Reference in a new issue