2020-06-28 11:26:22 +00:00
package remoteread
import (
"flag"
"fmt"
"net/http"
2024-05-30 15:54:42 +00:00
"time"
2020-06-28 11:26:22 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
2022-08-11 07:56:40 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
2024-02-08 14:52:00 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/httputils"
2024-07-15 21:00:14 +00:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/netutil"
2020-06-28 11:26:22 +00:00
)
var (
2022-08-08 07:45:21 +00:00
addr = flag . String ( "remoteRead.url" , "" , "Optional URL to datasource compatible with Prometheus HTTP API. It can be single node VictoriaMetrics or vmselect." +
"Remote read is used to restore alerts state." +
"This configuration makes sense only if `vmalert` was configured with `remoteWrite.url` before and has been successfully persisted its state. " +
2024-08-16 09:32:04 +00:00
"Supports address in the form of IP address with a port (e.g., http://127.0.0.1:8428) or DNS SRV record. " +
2024-05-22 08:52:51 +00:00
"See also '-remoteRead.disablePathAppend', '-remoteRead.showURL'." )
2022-03-10 11:09:12 +00:00
2022-08-11 07:56:40 +00:00
showRemoteReadURL = flag . Bool ( "remoteRead.showURL" , false , "Whether to show -remoteRead.url in the exported metrics. " +
"It is hidden by default, since it can contain sensitive info such as auth key" )
2022-07-21 11:57:53 +00:00
headers = flag . String ( "remoteRead.headers" , "" , "Optional HTTP headers to send with each request to the corresponding -remoteRead.url. " +
"For example, -remoteRead.headers='My-Auth:foobar' would send 'My-Auth: foobar' HTTP header with every request to the corresponding -remoteRead.url. " +
"Multiple headers must be delimited by '^^': -remoteRead.headers='header1:value1^^header2:value2'" )
2020-06-28 11:26:22 +00:00
basicAuthUsername = flag . String ( "remoteRead.basicAuth.username" , "" , "Optional basic auth username for -remoteRead.url" )
basicAuthPassword = flag . String ( "remoteRead.basicAuth.password" , "" , "Optional basic auth password for -remoteRead.url" )
2021-09-14 11:32:06 +00:00
basicAuthPasswordFile = flag . String ( "remoteRead.basicAuth.passwordFile" , "" , "Optional path to basic auth password to use for -remoteRead.url" )
2022-03-10 11:09:12 +00:00
bearerToken = flag . String ( "remoteRead.bearerToken" , "" , "Optional bearer auth token to use for -remoteRead.url." )
bearerTokenFile = flag . String ( "remoteRead.bearerTokenFile" , "" , "Optional path to bearer token file to use for -remoteRead.url." )
2021-09-14 11:32:06 +00:00
2024-05-30 15:54:42 +00:00
idleConnectionTimeout = flag . Duration ( "remoteRead.idleConnTimeout" , 50 * time . Second , ` Defines a duration for idle (keep-alive connections) to exist. Consider settings this value less to the value of "-http.idleConnTimeout". It must prevent possible "write: broken pipe" and "read: connection reset by peer" errors. ` )
2020-06-28 11:26:22 +00:00
tlsInsecureSkipVerify = flag . Bool ( "remoteRead.tlsInsecureSkipVerify" , false , "Whether to skip tls verification when connecting to -remoteRead.url" )
tlsCertFile = flag . String ( "remoteRead.tlsCertFile" , "" , "Optional path to client-side TLS certificate file to use when connecting to -remoteRead.url" )
tlsKeyFile = flag . String ( "remoteRead.tlsKeyFile" , "" , "Optional path to client-side TLS certificate key to use when connecting to -remoteRead.url" )
tlsCAFile = flag . String ( "remoteRead.tlsCAFile" , "" , "Optional path to TLS CA file to use for verifying connections to -remoteRead.url. " +
2023-05-10 07:50:41 +00:00
"By default, system CA is used" )
2020-06-28 11:26:22 +00:00
tlsServerName = flag . String ( "remoteRead.tlsServerName" , "" , "Optional TLS server name to use for connections to -remoteRead.url. " +
2023-05-10 07:50:41 +00:00
"By default, the server name from -remoteRead.url is used" )
2022-03-10 11:09:12 +00:00
oauth2ClientID = flag . String ( "remoteRead.oauth2.clientID" , "" , "Optional OAuth2 clientID to use for -remoteRead.url." )
oauth2ClientSecret = flag . String ( "remoteRead.oauth2.clientSecret" , "" , "Optional OAuth2 clientSecret to use for -remoteRead.url." )
oauth2ClientSecretFile = flag . String ( "remoteRead.oauth2.clientSecretFile" , "" , "Optional OAuth2 clientSecretFile to use for -remoteRead.url." )
2023-12-20 19:35:16 +00:00
oauth2EndpointParams = flag . String ( "remoteRead.oauth2.endpointParams" , "" , "Optional OAuth2 endpoint parameters to use for -remoteRead.url . " +
` The endpoint parameters must be set in JSON format: { "param1":"value1",...,"paramN":"valueN"} ` )
oauth2TokenURL = flag . String ( "remoteRead.oauth2.tokenUrl" , "" , "Optional OAuth2 tokenURL to use for -remoteRead.url. " )
oauth2Scopes = flag . String ( "remoteRead.oauth2.scopes" , "" , "Optional OAuth2 scopes to use for -remoteRead.url. Scopes must be delimited by ';'." )
2020-06-28 11:26:22 +00:00
)
2022-08-11 07:56:40 +00:00
// InitSecretFlags must be called after flag.Parse and before any logging
func InitSecretFlags ( ) {
if ! * showRemoteReadURL {
flagutil . RegisterSecretFlag ( "remoteRead.url" )
}
}
2020-06-28 11:26:22 +00:00
// Init creates a Querier from provided flag values.
// Returns nil if addr flag wasn't set.
2021-04-28 20:41:15 +00:00
func Init ( ) ( datasource . QuerierBuilder , error ) {
2020-06-28 11:26:22 +00:00
if * addr == "" {
return nil , nil
}
2024-02-08 14:52:00 +00:00
tr , err := httputils . Transport ( * addr , * tlsCertFile , * tlsKeyFile , * tlsCAFile , * tlsServerName , * tlsInsecureSkipVerify )
2020-06-28 11:26:22 +00:00
if err != nil {
2024-08-16 09:32:04 +00:00
return nil , fmt . Errorf ( "failed to create transport for -remoteRead.url=%q: %w" , * addr , err )
2020-06-28 11:26:22 +00:00
}
2024-05-30 15:54:42 +00:00
tr . IdleConnTimeout = * idleConnectionTimeout
2024-07-15 21:00:14 +00:00
tr . DialContext = netutil . NewStatDialFunc ( "vmalert_remoteread" )
2022-03-10 11:09:12 +00:00
2023-12-20 19:35:16 +00:00
endpointParams , err := flagutil . ParseJSONMap ( * oauth2EndpointParams )
if err != nil {
return nil , fmt . Errorf ( "cannot parse JSON for -remoteRead.oauth2.endpointParams=%s: %w" , * oauth2EndpointParams , err )
}
2022-03-10 11:09:12 +00:00
authCfg , err := utils . AuthConfig (
utils . WithBasicAuth ( * basicAuthUsername , * basicAuthPassword , * basicAuthPasswordFile ) ,
utils . WithBearer ( * bearerToken , * bearerTokenFile ) ,
2023-12-20 19:35:16 +00:00
utils . WithOAuth ( * oauth2ClientID , * oauth2ClientSecret , * oauth2ClientSecretFile , * oauth2TokenURL , * oauth2Scopes , endpointParams ) ,
2022-07-21 11:57:53 +00:00
utils . WithHeaders ( * headers ) )
2021-09-14 11:32:06 +00:00
if err != nil {
return nil , fmt . Errorf ( "failed to configure auth: %w" , err )
}
2020-06-28 11:26:22 +00:00
c := & http . Client { Transport : tr }
2024-10-29 15:30:39 +00:00
return datasource . NewPrometheusClient ( * addr , authCfg , false , c ) , nil
2020-06-28 11:26:22 +00:00
}