mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/promauth: follow-up after 5b8176c68e
This commit is contained in:
parent
5b8176c68e
commit
78dddfb98f
7 changed files with 194 additions and 136 deletions
|
@ -669,12 +669,18 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
|
||||||
-remoteWrite.basicAuth.password array
|
-remoteWrite.basicAuth.password array
|
||||||
Optional basic auth password to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional basic auth password to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.basicAuth.passwordFile array
|
||||||
|
Optional path to basic auth password to use for -remoteWrite.url. The file is re-read every second. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.basicAuth.username array
|
-remoteWrite.basicAuth.username array
|
||||||
Optional basic auth username to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional basic auth username to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.bearerToken array
|
-remoteWrite.bearerToken array
|
||||||
Optional bearer auth token to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional bearer auth token to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.bearerTokenFile array
|
||||||
|
Optional path to bearer token file to use for -remoteWrite.url. The token is re-read from the file every second. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.flushInterval duration
|
-remoteWrite.flushInterval duration
|
||||||
Interval for flushing the data to remote storage. This option takes effect only when less than 10K data points per second are pushed to -remoteWrite.url (default 1s)
|
Interval for flushing the data to remote storage. This option takes effect only when less than 10K data points per second are pushed to -remoteWrite.url (default 1s)
|
||||||
-remoteWrite.label array
|
-remoteWrite.label array
|
||||||
|
@ -690,6 +696,21 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
|
||||||
Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
|
Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
|
||||||
-remoteWrite.maxHourlySeries int
|
-remoteWrite.maxHourlySeries int
|
||||||
The maximum number of unique series vmagent can send to remote storage systems during the last hour. Excess series are logged and dropped. This can be useful for limiting series cardinality. See also -remoteWrite.maxDailySeries
|
The maximum number of unique series vmagent can send to remote storage systems during the last hour. Excess series are logged and dropped. This can be useful for limiting series cardinality. See also -remoteWrite.maxDailySeries
|
||||||
|
-remoteWrite.oauth2.clientID array
|
||||||
|
Optional OAuth2 clientID to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.clientSecret array
|
||||||
|
Optional OAuth2 clientSecret to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.clientSecretFile array
|
||||||
|
Optional OAuth2 clientSecretFile to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.scopes array
|
||||||
|
Optional OAuth2 scopes to use for -remoteWrite.url. Scopes must be delimited by ';'. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.tokenUrl array
|
||||||
|
Optional OAuth2 tokenURL to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.proxyURL array
|
-remoteWrite.proxyURL array
|
||||||
Optional proxy URL for writing data to -remoteWrite.url. Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234
|
Optional proxy URL for writing data to -remoteWrite.url. Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
|
|
@ -2,8 +2,6 @@ package remotewrite
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -42,25 +40,30 @@ var (
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
basicAuthPassword = flagutil.NewArray("remoteWrite.basicAuth.password", "Optional basic auth password to use for -remoteWrite.url. "+
|
basicAuthPassword = flagutil.NewArray("remoteWrite.basicAuth.password", "Optional basic auth password to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
|
basicAuthPasswordFile = flagutil.NewArray("remoteWrite.basicAuth.passwordFile", "Optional path to basic auth password to use for -remoteWrite.url. "+
|
||||||
|
"The file is re-read every second. "+
|
||||||
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
bearerToken = flagutil.NewArray("remoteWrite.bearerToken", "Optional bearer auth token to use for -remoteWrite.url. "+
|
bearerToken = flagutil.NewArray("remoteWrite.bearerToken", "Optional bearer auth token to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
|
bearerTokenFile = flagutil.NewArray("remoteWrite.bearerTokenFile", "Optional path to bearer token file to use for -remoteWrite.url. "+
|
||||||
|
"The token is re-read from the file every second. "+
|
||||||
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
|
|
||||||
clientID = flagutil.NewArray("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for -remoteWrite.url."+
|
oauth2ClientID = flagutil.NewArray("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
clientSecret = flagutil.NewArray("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -remoteWrite.url."+
|
oauth2ClientSecret = flagutil.NewArray("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
clientSecretFile = flagutil.NewArray("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -remoteWrite.url."+
|
oauth2ClientSecretFile = flagutil.NewArray("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
tokenURL = flagutil.NewArray("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 token url to use for -remoteWrite.url."+
|
oauth2TokenURL = flagutil.NewArray("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for -remoteWrite.url. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
oAuth2Scopes = flagutil.NewArray("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for -remoteWrite.url."+
|
oauth2Scopes = flagutil.NewArray("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for -remoteWrite.url. Scopes must be delimited by ';'. "+
|
||||||
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
"If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url")
|
||||||
)
|
)
|
||||||
|
|
||||||
type client struct {
|
type client struct {
|
||||||
sanitizedURL string
|
sanitizedURL string
|
||||||
remoteWriteURL string
|
remoteWriteURL string
|
||||||
authHeader string
|
|
||||||
fq *persistentqueue.FastQueue
|
fq *persistentqueue.FastQueue
|
||||||
hc *http.Client
|
hc *http.Client
|
||||||
|
|
||||||
|
@ -81,11 +84,11 @@ type client struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClient(argIdx int, remoteWriteURL, sanitizedURL string, fq *persistentqueue.FastQueue, concurrency int) *client {
|
func newClient(argIdx int, remoteWriteURL, sanitizedURL string, fq *persistentqueue.FastQueue, concurrency int) *client {
|
||||||
tlsCfg, err := getTLSConfig(argIdx)
|
authCfg, err := getAuthConfig(argIdx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Panicf("FATAL: cannot initialize TLS config: %s", err)
|
logger.Panicf("FATAL: cannot initialize auth config: %s", err)
|
||||||
}
|
}
|
||||||
|
tlsCfg := authCfg.NewTLSConfig()
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
Dial: statDial,
|
Dial: statDial,
|
||||||
TLSClientConfig: tlsCfg,
|
TLSClientConfig: tlsCfg,
|
||||||
|
@ -106,33 +109,9 @@ func newClient(argIdx int, remoteWriteURL, sanitizedURL string, fq *persistentqu
|
||||||
}
|
}
|
||||||
tr.Proxy = http.ProxyURL(urlProxy)
|
tr.Proxy = http.ProxyURL(urlProxy)
|
||||||
}
|
}
|
||||||
authHeader := ""
|
|
||||||
username := basicAuthUsername.GetOptionalArg(argIdx)
|
|
||||||
password := basicAuthPassword.GetOptionalArg(argIdx)
|
|
||||||
if len(username) > 0 || len(password) > 0 {
|
|
||||||
// See https://en.wikipedia.org/wiki/Basic_access_authentication
|
|
||||||
token := username + ":" + password
|
|
||||||
token64 := base64.StdEncoding.EncodeToString([]byte(token))
|
|
||||||
authHeader = "Basic " + token64
|
|
||||||
}
|
|
||||||
token := bearerToken.GetOptionalArg(argIdx)
|
|
||||||
if len(token) > 0 {
|
|
||||||
if authHeader != "" {
|
|
||||||
logger.Fatalf("`-remoteWrite.bearerToken`=%q cannot be set when `-remoteWrite.basicAuth.*` flags are set", token)
|
|
||||||
}
|
|
||||||
authHeader = "Bearer " + token
|
|
||||||
}
|
|
||||||
authCfg, err := getAuthConfig(argIdx)
|
|
||||||
if err != nil {
|
|
||||||
logger.Fatalf("FATAL: cannot create OAuth2 config for remoteWrite idx: %d, err: %s", argIdx, err)
|
|
||||||
}
|
|
||||||
if authCfg != nil && authHeader != "" {
|
|
||||||
logger.Fatalf("`-remoteWrite.bearerToken`=%q or `-remoteWrite.basicAuth.* cannot be set when `-remoteWrite.oauth2.*` flags are set", token)
|
|
||||||
}
|
|
||||||
c := &client{
|
c := &client{
|
||||||
sanitizedURL: sanitizedURL,
|
sanitizedURL: sanitizedURL,
|
||||||
remoteWriteURL: remoteWriteURL,
|
remoteWriteURL: remoteWriteURL,
|
||||||
authHeader: authHeader,
|
|
||||||
authCfg: authCfg,
|
authCfg: authCfg,
|
||||||
fq: fq,
|
fq: fq,
|
||||||
hc: &http.Client{
|
hc: &http.Client{
|
||||||
|
@ -171,38 +150,44 @@ func (c *client) MustStop() {
|
||||||
logger.Infof("stopped client for -remoteWrite.url=%q", c.sanitizedURL)
|
logger.Infof("stopped client for -remoteWrite.url=%q", c.sanitizedURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTLSConfig(argIdx int) (*tls.Config, error) {
|
func getAuthConfig(argIdx int) (*promauth.Config, error) {
|
||||||
c := &promauth.TLSConfig{
|
username := basicAuthUsername.GetOptionalArg(argIdx)
|
||||||
|
password := basicAuthPassword.GetOptionalArg(argIdx)
|
||||||
|
passwordFile := basicAuthPasswordFile.GetOptionalArg(argIdx)
|
||||||
|
var basicAuthCfg *promauth.BasicAuthConfig
|
||||||
|
if username != "" || password != "" || passwordFile != "" {
|
||||||
|
basicAuthCfg = &promauth.BasicAuthConfig{
|
||||||
|
Username: username,
|
||||||
|
Password: password,
|
||||||
|
PasswordFile: passwordFile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
token := bearerToken.GetOptionalArg(argIdx)
|
||||||
|
tokenFile := bearerTokenFile.GetOptionalArg(argIdx)
|
||||||
|
|
||||||
|
var oauth2Cfg *promauth.OAuth2Config
|
||||||
|
clientSecret := oauth2ClientSecret.GetOptionalArg(argIdx)
|
||||||
|
clientSecretFile := oauth2ClientSecretFile.GetOptionalArg(argIdx)
|
||||||
|
if clientSecretFile != "" || clientSecret != "" {
|
||||||
|
oauth2Cfg = &promauth.OAuth2Config{
|
||||||
|
ClientID: oauth2ClientID.GetOptionalArg(argIdx),
|
||||||
|
ClientSecret: clientSecret,
|
||||||
|
ClientSecretFile: clientSecretFile,
|
||||||
|
TokenURL: oauth2TokenURL.GetOptionalArg(argIdx),
|
||||||
|
Scopes: strings.Split(oauth2Scopes.GetOptionalArg(argIdx), ";"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsCfg := &promauth.TLSConfig{
|
||||||
CAFile: tlsCAFile.GetOptionalArg(argIdx),
|
CAFile: tlsCAFile.GetOptionalArg(argIdx),
|
||||||
CertFile: tlsCertFile.GetOptionalArg(argIdx),
|
CertFile: tlsCertFile.GetOptionalArg(argIdx),
|
||||||
KeyFile: tlsKeyFile.GetOptionalArg(argIdx),
|
KeyFile: tlsKeyFile.GetOptionalArg(argIdx),
|
||||||
ServerName: tlsServerName.GetOptionalArg(argIdx),
|
ServerName: tlsServerName.GetOptionalArg(argIdx),
|
||||||
InsecureSkipVerify: tlsInsecureSkipVerify.GetOptionalArg(argIdx),
|
InsecureSkipVerify: tlsInsecureSkipVerify.GetOptionalArg(argIdx),
|
||||||
}
|
}
|
||||||
if c.CAFile == "" && c.CertFile == "" && c.KeyFile == "" && c.ServerName == "" && !c.InsecureSkipVerify {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
cfg, err := promauth.NewConfig(".", nil, nil, "", "", nil, c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot populate TLS config: %w", err)
|
|
||||||
}
|
|
||||||
tlsCfg := cfg.NewTLSConfig()
|
|
||||||
return tlsCfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAuthConfig(argIdx int) (*promauth.Config, error) {
|
authCfg, err := promauth.NewConfig(".", nil, basicAuthCfg, token, tokenFile, oauth2Cfg, tlsCfg)
|
||||||
|
|
||||||
oAuth2Cfg := &promauth.OAuth2Config{
|
|
||||||
ClientID: clientID.GetOptionalArg(argIdx),
|
|
||||||
ClientSecret: clientSecret.GetOptionalArg(argIdx),
|
|
||||||
ClientSecretFile: clientSecretFile.GetOptionalArg(argIdx),
|
|
||||||
TokenURL: tokenURL.GetOptionalArg(argIdx),
|
|
||||||
Scopes: strings.Split(oAuth2Scopes.GetOptionalArg(argIdx), ";"),
|
|
||||||
}
|
|
||||||
if oAuth2Cfg.ClientSecretFile == "" && oAuth2Cfg.ClientSecret == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
authCfg, err := promauth.NewConfig("", nil, nil, "", "", oAuth2Cfg, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot populate OAuth2 config for remoteWrite idx: %d, err: %w", argIdx, err)
|
return nil, fmt.Errorf("cannot populate OAuth2 config for remoteWrite idx: %d, err: %w", argIdx, err)
|
||||||
}
|
}
|
||||||
|
@ -267,13 +252,8 @@ again:
|
||||||
h.Set("Content-Type", "application/x-protobuf")
|
h.Set("Content-Type", "application/x-protobuf")
|
||||||
h.Set("Content-Encoding", "snappy")
|
h.Set("Content-Encoding", "snappy")
|
||||||
h.Set("X-Prometheus-Remote-Write-Version", "0.1.0")
|
h.Set("X-Prometheus-Remote-Write-Version", "0.1.0")
|
||||||
if c.authHeader != "" {
|
if ah := c.authCfg.GetAuthHeader(); ah != "" {
|
||||||
req.Header.Set("Authorization", c.authHeader)
|
req.Header.Set("Authorization", ah)
|
||||||
}
|
|
||||||
// add oauth2 header on best effort.
|
|
||||||
// remote storage may return error with incorrect authorization.
|
|
||||||
if c.authCfg != nil {
|
|
||||||
req.Header.Set("Authorization", c.authCfg.GetAuthHeader())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
|
@ -20,6 +20,8 @@ sort: 15
|
||||||
* FEATURE: automatically detect memory and cpu limits for VictoriaMetrics components running under [cgroup v2](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html) environments such as [HashiCorp Nomad](https://www.nomadproject.io/). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1269).
|
* FEATURE: automatically detect memory and cpu limits for VictoriaMetrics components running under [cgroup v2](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html) environments such as [HashiCorp Nomad](https://www.nomadproject.io/). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1269).
|
||||||
* FEATURE: vmauth: allow `-auth.config` reloading via `/-/reload` http endpoint. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1194).
|
* FEATURE: vmauth: allow `-auth.config` reloading via `/-/reload` http endpoint. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1194).
|
||||||
* FEATURE: add `timezone_offset(tz)` function. It returns offset in seconds for the given timezone `tz` relative to UTC. This can be useful when combining with datetime-related functions. For example, `day_of_week(time()+timezone_offset("America/Los_Angeles"))` would return weekdays for `America/Los_Angeles` time zone. Special `Local` time zone can be used for returning an offset for the time zone set on the host where VictoriaMetrics runs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1306) and [MetricsQL docs](https://docs.victoriametrics.com/MetricsQL.html) for more details.
|
* FEATURE: add `timezone_offset(tz)` function. It returns offset in seconds for the given timezone `tz` relative to UTC. This can be useful when combining with datetime-related functions. For example, `day_of_week(time()+timezone_offset("America/Los_Angeles"))` would return weekdays for `America/Los_Angeles` time zone. Special `Local` time zone can be used for returning an offset for the time zone set on the host where VictoriaMetrics runs. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1306) and [MetricsQL docs](https://docs.victoriametrics.com/MetricsQL.html) for more details.
|
||||||
|
* FEATURE: vmagent: add support for OAuth2 authorization for scrape targets and service discovery in the same way as Prometheus does. See [these docs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#oauth2).
|
||||||
|
* FEATURE: vmagent: add support for OAuth2 authorization when writing data to `-remoteWrite.url`. See `-remoteWrite.oauth2.*` config params in `/path/to/vmagent -help` output.
|
||||||
|
|
||||||
* BUGFIX: vmagent: do not retry scraping targets, which don't support HTTP. This should reduce CPU load and network usage at `vmagent` and at scrape target. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1289).
|
* BUGFIX: vmagent: do not retry scraping targets, which don't support HTTP. This should reduce CPU load and network usage at `vmagent` and at scrape target. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1289).
|
||||||
* BUGFIX: vmagent: fix possible race when refreshing `role: endpoints` and `role: endpointslices` scrape targets in `kubernetes_sd_config`. Prevoiusly `pod` objects could be updated after the related `endpoints` object update. This could lead to missing scrape targets. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240).
|
* BUGFIX: vmagent: fix possible race when refreshing `role: endpoints` and `role: endpointslices` scrape targets in `kubernetes_sd_config`. Prevoiusly `pod` objects could be updated after the related `endpoints` object update. This could lead to missing scrape targets. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240).
|
||||||
|
|
|
@ -673,12 +673,18 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
|
||||||
-remoteWrite.basicAuth.password array
|
-remoteWrite.basicAuth.password array
|
||||||
Optional basic auth password to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional basic auth password to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.basicAuth.passwordFile array
|
||||||
|
Optional path to basic auth password to use for -remoteWrite.url. The file is re-read every second. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.basicAuth.username array
|
-remoteWrite.basicAuth.username array
|
||||||
Optional basic auth username to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional basic auth username to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.bearerToken array
|
-remoteWrite.bearerToken array
|
||||||
Optional bearer auth token to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
Optional bearer auth token to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.bearerTokenFile array
|
||||||
|
Optional path to bearer token file to use for -remoteWrite.url. The token is re-read from the file every second. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.flushInterval duration
|
-remoteWrite.flushInterval duration
|
||||||
Interval for flushing the data to remote storage. This option takes effect only when less than 10K data points per second are pushed to -remoteWrite.url (default 1s)
|
Interval for flushing the data to remote storage. This option takes effect only when less than 10K data points per second are pushed to -remoteWrite.url (default 1s)
|
||||||
-remoteWrite.label array
|
-remoteWrite.label array
|
||||||
|
@ -694,6 +700,21 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
|
||||||
Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
|
Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
|
||||||
-remoteWrite.maxHourlySeries int
|
-remoteWrite.maxHourlySeries int
|
||||||
The maximum number of unique series vmagent can send to remote storage systems during the last hour. Excess series are logged and dropped. This can be useful for limiting series cardinality. See also -remoteWrite.maxDailySeries
|
The maximum number of unique series vmagent can send to remote storage systems during the last hour. Excess series are logged and dropped. This can be useful for limiting series cardinality. See also -remoteWrite.maxDailySeries
|
||||||
|
-remoteWrite.oauth2.clientID array
|
||||||
|
Optional OAuth2 clientID to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.clientSecret array
|
||||||
|
Optional OAuth2 clientSecret to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.clientSecretFile array
|
||||||
|
Optional OAuth2 clientSecretFile to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.scopes array
|
||||||
|
Optional OAuth2 scopes to use for -remoteWrite.url. Scopes must be delimited by ';'. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
-remoteWrite.oauth2.tokenUrl array
|
||||||
|
Optional OAuth2 tokenURL to use for -remoteWrite.url. If multiple args are set, then they are applied independently for the corresponding -remoteWrite.url
|
||||||
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
-remoteWrite.proxyURL array
|
-remoteWrite.proxyURL array
|
||||||
Optional proxy URL for writing data to -remoteWrite.url. Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234
|
Optional proxy URL for writing data to -remoteWrite.url. Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234
|
||||||
Supports an array of values separated by comma or specified via multiple flags.
|
Supports an array of values separated by comma or specified via multiple flags.
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -533,7 +533,7 @@ github.com/influxdata/flux v0.113.0/go.mod h1:3TJtvbm/Kwuo5/PEo5P6HUzwVg4bXWkb2w
|
||||||
github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69/go.mod h1:pwymjR6SrP3gD3pRj9RJwdl1j5s3doEEV8gS4X9qSzA=
|
github.com/influxdata/httprouter v1.3.1-0.20191122104820-ee83e2772f69/go.mod h1:pwymjR6SrP3gD3pRj9RJwdl1j5s3doEEV8gS4X9qSzA=
|
||||||
github.com/influxdata/influxdb v1.8.0/go.mod h1:SIzcnsjaHRFpmlxpJ4S3NT64qtEKYweNTUMb/vh0OMQ=
|
github.com/influxdata/influxdb v1.8.0/go.mod h1:SIzcnsjaHRFpmlxpJ4S3NT64qtEKYweNTUMb/vh0OMQ=
|
||||||
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
|
github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI=
|
||||||
github.com/influxdata/influxdb v1.9.0 h1:KefL3i2JdNgsZwKRlHkkV+sYs4ejJ+aGF6glBUoKKio=
|
github.com/influxdata/influxdb v1.9.0 h1:9z/aRmTpWT1rIm4EN+qTJTZqgEdLGZ4xRMgvA276UEA=
|
||||||
github.com/influxdata/influxdb v1.9.0/go.mod h1:UEe3MeD9AaP5rlPIes102IhYua3FhIWZuOXNHxDjSrI=
|
github.com/influxdata/influxdb v1.9.0/go.mod h1:UEe3MeD9AaP5rlPIes102IhYua3FhIWZuOXNHxDjSrI=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/influxdata/influxql v1.1.0/go.mod h1:KpVI7okXjK6PRi3Z5B+mtKZli+R1DnZgb3N+tzevNgo=
|
github.com/influxdata/influxql v1.1.0/go.mod h1:KpVI7okXjK6PRi3Z5B+mtKZli+R1DnZgb3N+tzevNgo=
|
||||||
|
@ -1031,8 +1031,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
|
||||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
|
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
|
||||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
|
||||||
|
@ -64,65 +65,93 @@ type ProxyClientConfig struct {
|
||||||
|
|
||||||
// OAuth2Config represent OAuth2 configuration
|
// OAuth2Config represent OAuth2 configuration
|
||||||
type OAuth2Config struct {
|
type OAuth2Config struct {
|
||||||
ClientID string `yaml:"client_id"`
|
ClientID string `yaml:"client_id"`
|
||||||
ClientSecretFile string `yaml:"client_secret_file"`
|
ClientSecret string `yaml:"client_secret"`
|
||||||
Scopes []string `yaml:"scopes"`
|
ClientSecretFile string `yaml:"client_secret_file"`
|
||||||
TokenURL string `yaml:"token_url"`
|
Scopes []string `yaml:"scopes"`
|
||||||
// mu guards tokenSource and client Secret
|
TokenURL string `yaml:"token_url"`
|
||||||
mu sync.Mutex
|
EndpointParams map[string]string `yaml:"endpoint_params"`
|
||||||
ClientSecret string `yaml:"client_secret"`
|
|
||||||
tokenSource oauth2.TokenSource
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OAuth2Config) refreshTokenSourceLocked() {
|
// String returns string representation of o.
|
||||||
cfg := clientcredentials.Config{
|
func (o *OAuth2Config) String() string {
|
||||||
ClientID: o.ClientID,
|
return fmt.Sprintf("clientID=%q, clientSecret=%q, clientSecretFile=%q, Scopes=%q, tokenURL=%q, endpointParams=%q",
|
||||||
ClientSecret: o.ClientSecret,
|
o.ClientID, o.ClientSecret, o.ClientSecretFile, o.Scopes, o.TokenURL, o.EndpointParams)
|
||||||
TokenURL: o.TokenURL,
|
|
||||||
Scopes: o.Scopes,
|
|
||||||
}
|
|
||||||
o.tokenSource = cfg.TokenSource(context.Background())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate checks given configs.
|
|
||||||
func (o *OAuth2Config) validate() error {
|
func (o *OAuth2Config) validate() error {
|
||||||
if o.TokenURL == "" {
|
if o.ClientID == "" {
|
||||||
return fmt.Errorf("token url cannot be empty")
|
return fmt.Errorf("client_id cannot be empty")
|
||||||
}
|
}
|
||||||
if o.ClientSecret == "" && o.ClientSecretFile == "" {
|
if o.ClientSecret == "" && o.ClientSecretFile == "" {
|
||||||
return fmt.Errorf("ClientSecret or ClientSecretFile must be set")
|
return fmt.Errorf("ClientSecret or ClientSecretFile must be set")
|
||||||
}
|
}
|
||||||
if o.ClientSecret != "" && o.ClientSecretFile != "" {
|
if o.ClientSecret != "" && o.ClientSecretFile != "" {
|
||||||
return fmt.Errorf("only one option can be set ClientSecret or ClientSecretFile, provided both")
|
return fmt.Errorf("ClientSecret and ClientSecretFile cannot be set simultaneously")
|
||||||
|
}
|
||||||
|
if o.TokenURL == "" {
|
||||||
|
return fmt.Errorf("token_url cannot be empty")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OAuth2Config) getAuthHeader() (string, error) {
|
type oauth2ConfigInternal struct {
|
||||||
var needUpdate bool
|
mu sync.Mutex
|
||||||
if o.ClientSecretFile != "" {
|
cfg *clientcredentials.Config
|
||||||
newSecret, err := readPasswordFromFile(o.ClientSecretFile)
|
clientSecretFile string
|
||||||
if err != nil {
|
tokenSource oauth2.TokenSource
|
||||||
return "", fmt.Errorf("cannot read OAuth2 config file with path: %s, err: %w", o.ClientSecretFile, err)
|
}
|
||||||
}
|
|
||||||
o.mu.Lock()
|
|
||||||
if o.ClientSecret != newSecret {
|
|
||||||
o.ClientSecret = newSecret
|
|
||||||
needUpdate = true
|
|
||||||
}
|
|
||||||
o.mu.Unlock()
|
|
||||||
}
|
|
||||||
o.mu.Lock()
|
|
||||||
defer o.mu.Unlock()
|
|
||||||
if needUpdate {
|
|
||||||
o.refreshTokenSourceLocked()
|
|
||||||
}
|
|
||||||
t, err := o.tokenSource.Token()
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("cannot fetch token for OAuth2 client: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return t.Type() + " " + t.AccessToken, nil
|
func newOAuth2ConfigInternal(baseDir string, o *OAuth2Config) (*oauth2ConfigInternal, error) {
|
||||||
|
if err := o.validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
oi := &oauth2ConfigInternal{
|
||||||
|
cfg: &clientcredentials.Config{
|
||||||
|
ClientID: o.ClientID,
|
||||||
|
ClientSecret: o.ClientSecret,
|
||||||
|
TokenURL: o.TokenURL,
|
||||||
|
Scopes: o.Scopes,
|
||||||
|
EndpointParams: urlValuesFromMap(o.EndpointParams),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if o.ClientSecretFile != "" {
|
||||||
|
oi.clientSecretFile = getFilepath(baseDir, o.ClientSecretFile)
|
||||||
|
secret, err := readPasswordFromFile(oi.clientSecretFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot read OAuth2 secret from %q: %w", oi.clientSecretFile, err)
|
||||||
|
}
|
||||||
|
oi.cfg.ClientSecret = secret
|
||||||
|
}
|
||||||
|
oi.tokenSource = oi.cfg.TokenSource(context.Background())
|
||||||
|
return oi, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func urlValuesFromMap(m map[string]string) url.Values {
|
||||||
|
result := make(url.Values, len(m))
|
||||||
|
for k, v := range m {
|
||||||
|
result[k] = []string{v}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (oi *oauth2ConfigInternal) getTokenSource() (oauth2.TokenSource, error) {
|
||||||
|
oi.mu.Lock()
|
||||||
|
defer oi.mu.Unlock()
|
||||||
|
|
||||||
|
if oi.clientSecretFile == "" {
|
||||||
|
return oi.tokenSource, nil
|
||||||
|
}
|
||||||
|
newSecret, err := readPasswordFromFile(oi.clientSecretFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot read OAuth2 secret from %q: %w", oi.clientSecretFile, err)
|
||||||
|
}
|
||||||
|
if newSecret == oi.cfg.ClientSecret {
|
||||||
|
return oi.tokenSource, nil
|
||||||
|
}
|
||||||
|
oi.cfg.ClientSecret = newSecret
|
||||||
|
oi.tokenSource = oi.cfg.TokenSource(context.Background())
|
||||||
|
return oi.tokenSource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is auth config.
|
// Config is auth config.
|
||||||
|
@ -207,7 +236,7 @@ func (pcc *ProxyClientConfig) NewConfig(baseDir string) (*Config, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfig creates auth config from the given args.
|
// NewConfig creates auth config from the given args.
|
||||||
func NewConfig(baseDir string, az *Authorization, basicAuth *BasicAuthConfig, bearerToken, bearerTokenFile string, oauth *OAuth2Config, tlsConfig *TLSConfig) (*Config, error) {
|
func NewConfig(baseDir string, az *Authorization, basicAuth *BasicAuthConfig, bearerToken, bearerTokenFile string, o *OAuth2Config, tlsConfig *TLSConfig) (*Config, error) {
|
||||||
var getAuthHeader func() string
|
var getAuthHeader func() string
|
||||||
authDigest := ""
|
authDigest := ""
|
||||||
if az != nil {
|
if az != nil {
|
||||||
|
@ -297,29 +326,28 @@ func NewConfig(baseDir string, az *Authorization, basicAuth *BasicAuthConfig, be
|
||||||
}
|
}
|
||||||
authDigest = fmt.Sprintf("bearer(token=%q)", bearerToken)
|
authDigest = fmt.Sprintf("bearer(token=%q)", bearerToken)
|
||||||
}
|
}
|
||||||
if oauth != nil {
|
if o != nil {
|
||||||
if getAuthHeader != nil {
|
if getAuthHeader != nil {
|
||||||
return nil, fmt.Errorf("cannot simultaneously use `authorization`, `basic_auth, `bearer_token` and `ouath2`")
|
return nil, fmt.Errorf("cannot simultaneously use `authorization`, `basic_auth, `bearer_token` and `ouath2`")
|
||||||
}
|
}
|
||||||
if err := oauth.validate(); err != nil {
|
oi, err := newOAuth2ConfigInternal(baseDir, o)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if oauth.ClientSecretFile != "" {
|
|
||||||
secret, err := readPasswordFromFile(oauth.ClientSecretFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
oauth.ClientSecret = secret
|
|
||||||
}
|
|
||||||
oauth.refreshTokenSourceLocked()
|
|
||||||
getAuthHeader = func() string {
|
getAuthHeader = func() string {
|
||||||
h, err := oauth.getAuthHeader()
|
ts, err := oi.getTokenSource()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot get OAuth2 header: %s", err)
|
logger.Errorf("cannot get OAuth2 tokenSource: %s", err)
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return h
|
t, err := ts.Token()
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot get OAuth2 token: %s", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return t.Type() + " " + t.AccessToken
|
||||||
}
|
}
|
||||||
|
authDigest = fmt.Sprintf("oauth2(%s)", o.String())
|
||||||
}
|
}
|
||||||
var tlsRootCA *x509.CertPool
|
var tlsRootCA *x509.CertPool
|
||||||
var tlsCertificate *tls.Certificate
|
var tlsCertificate *tls.Certificate
|
||||||
|
|
|
@ -17,9 +17,10 @@ func TestNewConfig(t *testing.T) {
|
||||||
tlsConfig *TLSConfig
|
tlsConfig *TLSConfig
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
wantErr bool
|
wantErr bool
|
||||||
|
expectHeader string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "OAuth2 config",
|
name: "OAuth2 config",
|
||||||
|
@ -30,6 +31,7 @@ func TestNewConfig(t *testing.T) {
|
||||||
TokenURL: "http://localhost:8511",
|
TokenURL: "http://localhost:8511",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Bearer some-token",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OAuth2 config with file",
|
name: "OAuth2 config with file",
|
||||||
|
@ -40,8 +42,8 @@ func TestNewConfig(t *testing.T) {
|
||||||
TokenURL: "http://localhost:8511",
|
TokenURL: "http://localhost:8511",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Bearer some-token",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "OAuth2 want err",
|
name: "OAuth2 want err",
|
||||||
args: args{
|
args: args{
|
||||||
|
@ -62,6 +64,7 @@ func TestNewConfig(t *testing.T) {
|
||||||
Password: "password",
|
Password: "password",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Basic dXNlcjpwYXNzd29yZA==",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "basic Auth config with file",
|
name: "basic Auth config with file",
|
||||||
|
@ -71,21 +74,24 @@ func TestNewConfig(t *testing.T) {
|
||||||
PasswordFile: "testdata/test_secretfile.txt",
|
PasswordFile: "testdata/test_secretfile.txt",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Basic dXNlcjpzZWNyZXQtY29udGVudA==",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "want Authorization",
|
name: "want Authorization",
|
||||||
args: args{
|
args: args{
|
||||||
az: &Authorization{
|
az: &Authorization{
|
||||||
Type: "Bearer ",
|
Type: "Bearer",
|
||||||
Credentials: "Value",
|
Credentials: "Value",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Bearer Value",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "token file",
|
name: "token file",
|
||||||
args: args{
|
args: args{
|
||||||
bearerTokenFile: "testdata/test_secretfile.txt",
|
bearerTokenFile: "testdata/test_secretfile.txt",
|
||||||
},
|
},
|
||||||
|
expectHeader: "Bearer secret-content",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "token with tls",
|
name: "token with tls",
|
||||||
|
@ -95,6 +101,7 @@ func TestNewConfig(t *testing.T) {
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
expectHeader: "Bearer some-token",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -103,7 +110,7 @@ func TestNewConfig(t *testing.T) {
|
||||||
r := http.NewServeMux()
|
r := http.NewServeMux()
|
||||||
r.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
|
r.HandleFunc("/", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write([]byte(`{"access_token":"some-token","token_type": "Bearer "}`))
|
w.Write([]byte(`{"access_token":"some-token","token_type": "Bearer"}`))
|
||||||
|
|
||||||
})
|
})
|
||||||
mock := httptest.NewServer(r)
|
mock := httptest.NewServer(r)
|
||||||
|
@ -115,8 +122,9 @@ func TestNewConfig(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if got != nil {
|
if got != nil {
|
||||||
if ah := got.GetAuthHeader(); ah == "" {
|
ah := got.GetAuthHeader()
|
||||||
t.Fatalf("unexpected empty auth header")
|
if ah != tt.expectHeader {
|
||||||
|
t.Fatalf("unexpected auth header; got %q; want %q", ah, tt.expectHeader)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue