2020-06-28 13:26:22 +02:00
package datasource
import (
"flag"
"fmt"
"net/http"
2021-12-02 13:45:08 +01:00
"net/url"
2021-05-10 10:11:45 +02:00
"strings"
2022-09-23 10:22:53 +02:00
"time"
2020-06-28 13:26:22 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
2022-08-11 09:56:40 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
2023-10-10 12:41:19 +02:00
"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
2020-06-28 13:26:22 +02:00
)
var (
2022-08-08 09:45:21 +02:00
addr = flag . String ( "datasource.url" , "" , "Datasource compatible with Prometheus HTTP API. It can be single node VictoriaMetrics or vmselect URL. Required parameter. " +
2022-11-30 05:36:38 +01:00
"E.g. http://127.0.0.1:8428 . See also -remoteRead.disablePathAppend and -datasource.showURL" )
2022-08-11 09:56:40 +02:00
appendTypePrefix = flag . Bool ( "datasource.appendTypePrefix" , false , "Whether to add type prefix to -datasource.url based on the query type. Set to true if sending different query types to the vmselect URL." )
2023-10-10 11:40:27 +02:00
showDatasourceURL = flag . Bool ( "datasource.showURL" , false , "Whether to avoid stripping sensitive information such as auth headers or passwords from URLs in log messages or UI and exported metrics. " +
2022-08-11 09:56:40 +02:00
"It is hidden by default, since it can contain sensitive info such as auth key" )
2022-03-10 12:09:12 +01:00
2022-07-21 15:59:55 +02:00
headers = flag . String ( "datasource.headers" , "" , "Optional HTTP extraHeaders to send with each request to the corresponding -datasource.url. " +
2022-07-21 13:57:53 +02:00
"For example, -datasource.headers='My-Auth:foobar' would send 'My-Auth: foobar' HTTP header with every request to the corresponding -datasource.url. " +
"Multiple headers must be delimited by '^^': -datasource.headers='header1:value1^^header2:value2'" )
2021-09-14 13:32:06 +02:00
basicAuthUsername = flag . String ( "datasource.basicAuth.username" , "" , "Optional basic auth username for -datasource.url" )
basicAuthPassword = flag . String ( "datasource.basicAuth.password" , "" , "Optional basic auth password for -datasource.url" )
basicAuthPasswordFile = flag . String ( "datasource.basicAuth.passwordFile" , "" , "Optional path to basic auth password to use for -datasource.url" )
2022-03-10 12:09:12 +01:00
bearerToken = flag . String ( "datasource.bearerToken" , "" , "Optional bearer auth token to use for -datasource.url." )
bearerTokenFile = flag . String ( "datasource.bearerTokenFile" , "" , "Optional path to bearer token file to use for -datasource.url." )
2020-06-28 13:26:22 +02:00
tlsInsecureSkipVerify = flag . Bool ( "datasource.tlsInsecureSkipVerify" , false , "Whether to skip tls verification when connecting to -datasource.url" )
tlsCertFile = flag . String ( "datasource.tlsCertFile" , "" , "Optional path to client-side TLS certificate file to use when connecting to -datasource.url" )
tlsKeyFile = flag . String ( "datasource.tlsKeyFile" , "" , "Optional path to client-side TLS certificate key to use when connecting to -datasource.url" )
2021-04-12 11:28:04 +02:00
tlsCAFile = flag . String ( "datasource.tlsCAFile" , "" , ` Optional path to TLS CA file to use for verifying connections to -datasource.url. By default, system CA is used ` )
tlsServerName = flag . String ( "datasource.tlsServerName" , "" , ` Optional TLS server name to use for connections to -datasource.url. By default, the server name from -datasource.url is used ` )
2020-09-21 14:53:49 +02:00
2022-03-10 12:09:12 +01:00
oauth2ClientID = flag . String ( "datasource.oauth2.clientID" , "" , "Optional OAuth2 clientID to use for -datasource.url. " )
oauth2ClientSecret = flag . String ( "datasource.oauth2.clientSecret" , "" , "Optional OAuth2 clientSecret to use for -datasource.url." )
oauth2ClientSecretFile = flag . String ( "datasource.oauth2.clientSecretFile" , "" , "Optional OAuth2 clientSecretFile to use for -datasource.url. " )
oauth2TokenURL = flag . String ( "datasource.oauth2.tokenUrl" , "" , "Optional OAuth2 tokenURL to use for -datasource.url." )
oauth2Scopes = flag . String ( "datasource.oauth2.scopes" , "" , "Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'" )
2021-04-12 11:28:04 +02:00
lookBack = flag . Duration ( "datasource.lookback" , 0 , ` Lookback defines how far into the past to look when evaluating queries. For example, if the datasource.lookback=5m then param "time" with value now()-5m will be added to every query. ` )
2022-09-26 07:46:21 +02:00
queryStep = flag . Duration ( "datasource.queryStep" , 5 * time . Minute , "How far a value can fallback to when evaluating queries. " +
"For example, if -datasource.queryStep=15s then param \"step\" with value \"15s\" will be added to every query. " +
"If set to 0, rule's evaluation interval will be used instead." )
2023-10-13 13:07:16 +02:00
queryTimeAlignment = flag . Bool ( "datasource.queryTimeAlignment" , true , ` Deprecated: please use "eval_alignment" in rule group instead. ` +
` Whether to align "time" parameter with evaluation interval. ` +
"Alignment supposed to produce deterministic results despite number of vmalert replicas or time they were started. " +
"See more details at https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1257" )
2021-04-12 11:28:04 +02:00
maxIdleConnections = flag . Int ( "datasource.maxIdleConnections" , 100 , ` Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. ` )
2022-04-04 11:59:04 +02:00
disableKeepAlive = flag . Bool ( "datasource.disableKeepAlive" , false , ` Whether to disable long-lived connections to the datasource. ` +
` If true, disables HTTP keep-alives and will only use the connection to the server for a single HTTP request. ` )
roundDigits = flag . Int ( "datasource.roundDigits" , 0 , ` Adds "round_digits" GET param to datasource requests. ` +
2021-05-10 10:18:26 +02:00
` In VM "round_digits" limits the number of digits after the decimal point in response values. ` )
2020-06-28 13:26:22 +02:00
)
2022-08-11 09:56:40 +02:00
// InitSecretFlags must be called after flag.Parse and before any logging
func InitSecretFlags ( ) {
if ! * showDatasourceURL {
flagutil . RegisterSecretFlag ( "datasource.url" )
}
}
2023-10-10 11:40:27 +02:00
// ShowDatasourceURL whether to show -datasource.url with sensitive information
func ShowDatasourceURL ( ) bool {
return * showDatasourceURL
}
2021-08-31 13:57:47 +02:00
// Param represents an HTTP GET param
type Param struct {
Key , Value string
}
2020-06-28 13:26:22 +02:00
// Init creates a Querier from provided flag values.
2021-12-02 13:45:08 +01:00
// Provided extraParams will be added as GET params for
2021-08-31 13:57:47 +02:00
// each request.
2021-12-02 13:45:08 +01:00
func Init ( extraParams url . Values ) ( QuerierBuilder , error ) {
2020-06-28 13:26:22 +02:00
if * addr == "" {
return nil , fmt . Errorf ( "datasource.url is empty" )
}
2023-10-10 12:41:19 +02:00
if ! * queryTimeAlignment {
logger . Warnf ( "flag `datasource.queryTimeAlignment` is deprecated and will be removed in next releases, please use `eval_alignment` in rule group instead" )
}
2021-05-10 10:11:45 +02:00
2020-06-28 13:26:22 +02:00
tr , err := utils . Transport ( * addr , * tlsCertFile , * tlsKeyFile , * tlsCAFile , * tlsServerName , * tlsInsecureSkipVerify )
if err != nil {
2020-06-30 21:58:18 +02:00
return nil , fmt . Errorf ( "failed to create transport: %w" , err )
2020-06-28 13:26:22 +02:00
}
2022-04-04 11:59:04 +02:00
tr . DisableKeepAlives = * disableKeepAlive
2021-05-14 17:10:19 +02:00
tr . MaxIdleConnsPerHost = * maxIdleConnections
2021-10-13 16:29:28 +02:00
if tr . MaxIdleConns != 0 && tr . MaxIdleConns < tr . MaxIdleConnsPerHost {
tr . MaxIdleConns = tr . MaxIdleConnsPerHost
}
2021-05-10 10:11:45 +02:00
2021-12-02 13:45:08 +01:00
if extraParams == nil {
extraParams = url . Values { }
}
2021-05-10 10:11:45 +02:00
if * roundDigits > 0 {
2021-12-02 13:45:08 +01:00
extraParams . Set ( "round_digits" , fmt . Sprintf ( "%d" , * roundDigits ) )
2021-05-10 10:11:45 +02:00
}
2022-03-10 12:09:12 +01:00
authCfg , err := utils . AuthConfig (
utils . WithBasicAuth ( * basicAuthUsername , * basicAuthPassword , * basicAuthPasswordFile ) ,
utils . WithBearer ( * bearerToken , * bearerTokenFile ) ,
2022-07-21 13:57:53 +02:00
utils . WithOAuth ( * oauth2ClientID , * oauth2ClientSecret , * oauth2ClientSecretFile , * oauth2TokenURL , * oauth2Scopes ) ,
utils . WithHeaders ( * headers ) )
2021-09-14 13:32:06 +02:00
if err != nil {
return nil , fmt . Errorf ( "failed to configure auth: %w" , err )
}
2023-10-17 11:58:19 +02:00
_ , err = authCfg . GetAuthHeader ( )
if err != nil {
return nil , fmt . Errorf ( "failed to set request auth header to datasource %q: %s" , * addr , err )
}
2021-09-14 13:32:06 +02:00
2021-05-10 10:11:45 +02:00
return & VMStorage {
c : & http . Client { Transport : tr } ,
2021-09-14 13:32:06 +02:00
authCfg : authCfg ,
2021-05-10 10:11:45 +02:00
datasourceURL : strings . TrimSuffix ( * addr , "/" ) ,
appendTypePrefix : * appendTypePrefix ,
lookBack : * lookBack ,
queryStep : * queryStep ,
2022-07-22 10:44:55 +02:00
dataSourceType : datasourcePrometheus ,
2021-08-31 13:57:47 +02:00
extraParams : extraParams ,
2021-05-10 10:11:45 +02:00
} , nil
2020-06-28 13:26:22 +02:00
}