lib/flagutil: rename Array to ArrayString

This makes the ArrayString more consistent with other Array* types.

While at it, add ArrayBytes type, which will be used for https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3071
This commit is contained in:
Aliaksandr Valialkin 2022-10-01 18:26:05 +03:00
parent 366f04001b
commit c1fa9828b3
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
10 changed files with 217 additions and 120 deletions

View file

@ -24,46 +24,46 @@ var (
"By default the rate limit is disabled. It can be useful for limiting load on remote storage when big amounts of buffered data "+ "By default the rate limit is disabled. It can be useful for limiting load on remote storage when big amounts of buffered data "+
"is sent after temporary unavailability of the remote storage") "is sent after temporary unavailability of the remote storage")
sendTimeout = flagutil.NewArrayDuration("remoteWrite.sendTimeout", "Timeout for sending a single block of data to the corresponding -remoteWrite.url") sendTimeout = flagutil.NewArrayDuration("remoteWrite.sendTimeout", "Timeout for sending a single block of data to the corresponding -remoteWrite.url")
proxyURL = flagutil.NewArray("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+ proxyURL = flagutil.NewArrayString("remoteWrite.proxyURL", "Optional proxy URL for writing data to the corresponding -remoteWrite.url. "+
"Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234") "Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234")
tlsInsecureSkipVerify = flagutil.NewArrayBool("remoteWrite.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to the corresponding -remoteWrite.url") tlsInsecureSkipVerify = flagutil.NewArrayBool("remoteWrite.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to the corresponding -remoteWrite.url")
tlsCertFile = flagutil.NewArray("remoteWrite.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting "+ tlsCertFile = flagutil.NewArrayString("remoteWrite.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting "+
"to the corresponding -remoteWrite.url") "to the corresponding -remoteWrite.url")
tlsKeyFile = flagutil.NewArray("remoteWrite.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to the corresponding -remoteWrite.url") tlsKeyFile = flagutil.NewArrayString("remoteWrite.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to the corresponding -remoteWrite.url")
tlsCAFile = flagutil.NewArray("remoteWrite.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to the corresponding -remoteWrite.url. "+ tlsCAFile = flagutil.NewArrayString("remoteWrite.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to the corresponding -remoteWrite.url. "+
"By default system CA is used") "By default system CA is used")
tlsServerName = flagutil.NewArray("remoteWrite.tlsServerName", "Optional TLS server name to use for connections to the corresponding -remoteWrite.url. "+ tlsServerName = flagutil.NewArrayString("remoteWrite.tlsServerName", "Optional TLS server name to use for connections to the corresponding -remoteWrite.url. "+
"By default the server name from -remoteWrite.url is used") "By default the server name from -remoteWrite.url is used")
headers = flagutil.NewArray("remoteWrite.headers", "Optional HTTP headers to send with each request to the corresponding -remoteWrite.url. "+ headers = flagutil.NewArrayString("remoteWrite.headers", "Optional HTTP headers to send with each request to the corresponding -remoteWrite.url. "+
"For example, -remoteWrite.headers='My-Auth:foobar' would send 'My-Auth: foobar' HTTP header with every request to the corresponding -remoteWrite.url. "+ "For example, -remoteWrite.headers='My-Auth:foobar' would send 'My-Auth: foobar' HTTP header with every request to the corresponding -remoteWrite.url. "+
"Multiple headers must be delimited by '^^': -remoteWrite.headers='header1:value1^^header2:value2'") "Multiple headers must be delimited by '^^': -remoteWrite.headers='header1:value1^^header2:value2'")
basicAuthUsername = flagutil.NewArray("remoteWrite.basicAuth.username", "Optional basic auth username to use for the corresponding -remoteWrite.url") basicAuthUsername = flagutil.NewArrayString("remoteWrite.basicAuth.username", "Optional basic auth username to use for the corresponding -remoteWrite.url")
basicAuthPassword = flagutil.NewArray("remoteWrite.basicAuth.password", "Optional basic auth password to use for the corresponding -remoteWrite.url") basicAuthPassword = flagutil.NewArrayString("remoteWrite.basicAuth.password", "Optional basic auth password to use for the corresponding -remoteWrite.url")
basicAuthPasswordFile = flagutil.NewArray("remoteWrite.basicAuth.passwordFile", "Optional path to basic auth password to use for the corresponding -remoteWrite.url. "+ basicAuthPasswordFile = flagutil.NewArrayString("remoteWrite.basicAuth.passwordFile", "Optional path to basic auth password to use for the corresponding -remoteWrite.url. "+
"The file is re-read every second") "The file is re-read every second")
bearerToken = flagutil.NewArray("remoteWrite.bearerToken", "Optional bearer auth token to use for the corresponding -remoteWrite.url") bearerToken = flagutil.NewArrayString("remoteWrite.bearerToken", "Optional bearer auth token to use for the corresponding -remoteWrite.url")
bearerTokenFile = flagutil.NewArray("remoteWrite.bearerTokenFile", "Optional path to bearer token file to use for the corresponding -remoteWrite.url. "+ bearerTokenFile = flagutil.NewArrayString("remoteWrite.bearerTokenFile", "Optional path to bearer token file to use for the corresponding -remoteWrite.url. "+
"The token is re-read from the file every second") "The token is re-read from the file every second")
oauth2ClientID = flagutil.NewArray("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for the corresponding -remoteWrite.url") oauth2ClientID = flagutil.NewArrayString("remoteWrite.oauth2.clientID", "Optional OAuth2 clientID to use for the corresponding -remoteWrite.url")
oauth2ClientSecret = flagutil.NewArray("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for the corresponding -remoteWrite.url") oauth2ClientSecret = flagutil.NewArrayString("remoteWrite.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for the corresponding -remoteWrite.url")
oauth2ClientSecretFile = flagutil.NewArray("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for the corresponding -remoteWrite.url") oauth2ClientSecretFile = flagutil.NewArrayString("remoteWrite.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for the corresponding -remoteWrite.url")
oauth2TokenURL = flagutil.NewArray("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for the corresponding -remoteWrite.url") oauth2TokenURL = flagutil.NewArrayString("remoteWrite.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for the corresponding -remoteWrite.url")
oauth2Scopes = flagutil.NewArray("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for the corresponding -remoteWrite.url. Scopes must be delimited by ';'") oauth2Scopes = flagutil.NewArrayString("remoteWrite.oauth2.scopes", "Optional OAuth2 scopes to use for the corresponding -remoteWrite.url. Scopes must be delimited by ';'")
awsUseSigv4 = flagutil.NewArrayBool("remoteWrite.aws.useSigv4", "Enables SigV4 request signing for the corresponding -remoteWrite.url. "+ awsUseSigv4 = flagutil.NewArrayBool("remoteWrite.aws.useSigv4", "Enables SigV4 request signing for the corresponding -remoteWrite.url. "+
"It is expected that other -remoteWrite.aws.* command-line flags are set if sigv4 request signing is enabled") "It is expected that other -remoteWrite.aws.* command-line flags are set if sigv4 request signing is enabled")
awsEC2Endpoint = flagutil.NewArray("remoteWrite.aws.ec2Endpoint", "Optional AWS EC2 API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsEC2Endpoint = flagutil.NewArrayString("remoteWrite.aws.ec2Endpoint", "Optional AWS EC2 API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsSTSEndpoint = flagutil.NewArray("remoteWrite.aws.stsEndpoint", "Optional AWS STS API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsSTSEndpoint = flagutil.NewArrayString("remoteWrite.aws.stsEndpoint", "Optional AWS STS API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRegion = flagutil.NewArray("remoteWrite.aws.region", "Optional AWS region to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsRegion = flagutil.NewArrayString("remoteWrite.aws.region", "Optional AWS region to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsRoleARN = flagutil.NewArray("remoteWrite.aws.roleARN", "Optional AWS roleARN to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsRoleARN = flagutil.NewArrayString("remoteWrite.aws.roleARN", "Optional AWS roleARN to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsAccessKey = flagutil.NewArray("remoteWrite.aws.accessKey", "Optional AWS AccessKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsAccessKey = flagutil.NewArrayString("remoteWrite.aws.accessKey", "Optional AWS AccessKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
awsService = flagutil.NewArray("remoteWrite.aws.service", "Optional AWS Service to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set. "+ awsService = flagutil.NewArrayString("remoteWrite.aws.service", "Optional AWS Service to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set. "+
"Defaults to \"aps\"") "Defaults to \"aps\"")
awsSecretKey = flagutil.NewArray("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set") awsSecretKey = flagutil.NewArrayString("remoteWrite.aws.secretKey", "Optional AWS SecretKey to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set")
) )
type client struct { type client struct {

View file

@ -13,14 +13,14 @@ import (
) )
var ( var (
unparsedLabelsGlobal = flagutil.NewArray("remoteWrite.label", "Optional label in the form 'name=value' to add to all the metrics before sending them to -remoteWrite.url. "+ unparsedLabelsGlobal = flagutil.NewArrayString("remoteWrite.label", "Optional label in the form 'name=value' to add to all the metrics before sending them to -remoteWrite.url. "+
"Pass multiple -remoteWrite.label flags in order to add multiple labels to metrics before sending them to remote storage") "Pass multiple -remoteWrite.label flags in order to add multiple labels to metrics before sending them to remote storage")
relabelConfigPathGlobal = flag.String("remoteWrite.relabelConfig", "", "Optional path to file with relabel_config entries. "+ relabelConfigPathGlobal = flag.String("remoteWrite.relabelConfig", "", "Optional path to file with relabel_config entries. "+
"The path can point either to local file or to http url. These entries are applied to all the metrics "+ "The path can point either to local file or to http url. These entries are applied to all the metrics "+
"before sending them to -remoteWrite.url. See https://docs.victoriametrics.com/vmagent.html#relabeling for details") "before sending them to -remoteWrite.url. See https://docs.victoriametrics.com/vmagent.html#relabeling for details")
relabelDebugGlobal = flag.Bool("remoteWrite.relabelDebug", false, "Whether to log metrics before and after relabeling with -remoteWrite.relabelConfig. "+ relabelDebugGlobal = flag.Bool("remoteWrite.relabelDebug", false, "Whether to log metrics before and after relabeling with -remoteWrite.relabelConfig. "+
"If the -remoteWrite.relabelDebug is enabled, then the metrics aren't sent to remote storage. This is useful for debugging the relabeling configs") "If the -remoteWrite.relabelDebug is enabled, then the metrics aren't sent to remote storage. This is useful for debugging the relabeling configs")
relabelConfigPaths = flagutil.NewArray("remoteWrite.urlRelabelConfig", "Optional path to relabel config for the corresponding -remoteWrite.url. "+ relabelConfigPaths = flagutil.NewArrayString("remoteWrite.urlRelabelConfig", "Optional path to relabel config for the corresponding -remoteWrite.url. "+
"The path can point either to local file or to http url") "The path can point either to local file or to http url")
relabelDebug = flagutil.NewArrayBool("remoteWrite.urlRelabelDebug", "Whether to log metrics before and after relabeling with -remoteWrite.urlRelabelConfig. "+ relabelDebug = flagutil.NewArrayBool("remoteWrite.urlRelabelDebug", "Whether to log metrics before and after relabeling with -remoteWrite.urlRelabelConfig. "+
"If the -remoteWrite.urlRelabelDebug is enabled, then the metrics aren't sent to the corresponding -remoteWrite.url. "+ "If the -remoteWrite.urlRelabelDebug is enabled, then the metrics aren't sent to the corresponding -remoteWrite.url. "+

View file

@ -26,10 +26,10 @@ import (
) )
var ( var (
remoteWriteURLs = flagutil.NewArray("remoteWrite.url", "Remote storage URL to write data to. It must support Prometheus remote_write API. "+ remoteWriteURLs = flagutil.NewArrayString("remoteWrite.url", "Remote storage URL to write data to. It must support Prometheus remote_write API. "+
"It is recommended using VictoriaMetrics as remote storage. Example url: http://<victoriametrics-host>:8428/api/v1/write . "+ "It is recommended using VictoriaMetrics as remote storage. Example url: http://<victoriametrics-host>:8428/api/v1/write . "+
"Pass multiple -remoteWrite.url flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.multitenantURL") "Pass multiple -remoteWrite.url flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.multitenantURL")
remoteWriteMultitenantURLs = flagutil.NewArray("remoteWrite.multitenantURL", "Base path for multitenant remote storage URL to write data to. "+ remoteWriteMultitenantURLs = flagutil.NewArrayString("remoteWrite.multitenantURL", "Base path for multitenant remote storage URL to write data to. "+
"See https://docs.victoriametrics.com/vmagent.html#multitenancy for details. Example url: http://<vminsert>:8480 . "+ "See https://docs.victoriametrics.com/vmagent.html#multitenancy for details. Example url: http://<vminsert>:8480 . "+
"Pass multiple -remoteWrite.multitenantURL flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.url") "Pass multiple -remoteWrite.multitenantURL flags in order to replicate data to multiple remote storage systems. See also -remoteWrite.url")
tmpDataPath = flag.String("remoteWrite.tmpDataPath", "vmagent-remotewrite-data", "Path to directory where temporary data for remote write component is stored. "+ tmpDataPath = flag.String("remoteWrite.tmpDataPath", "vmagent-remotewrite-data", "Path to directory where temporary data for remote write component is stored. "+

View file

@ -28,7 +28,7 @@ import (
) )
var ( var (
rulePath = flagutil.NewArray("rule", `Path to the file with alert rules. rulePath = flagutil.NewArrayString("rule", `Path to the file with alert rules.
Supports patterns. Flag can be specified multiple times. Supports patterns. Flag can be specified multiple times.
Examples: Examples:
-rule="/path/to/file". Path to a single file with alerting rules -rule="/path/to/file". Path to a single file with alerting rules
@ -36,7 +36,7 @@ Examples:
absolute path to all .yaml files in root. absolute path to all .yaml files in root.
Rule files may contain %{ENV_VAR} placeholders, which are substituted by the corresponding env vars.`) Rule files may contain %{ENV_VAR} placeholders, which are substituted by the corresponding env vars.`)
ruleTemplatesPath = flagutil.NewArray("rule.templates", `Path or glob pattern to location with go template definitions ruleTemplatesPath = flagutil.NewArrayString("rule.templates", `Path or glob pattern to location with go template definitions
for rules annotations templating. Flag can be specified multiple times. for rules annotations templating. Flag can be specified multiple times.
Examples: Examples:
-rule.templates="/path/to/file". Path to a single file with go templates -rule.templates="/path/to/file". Path to a single file with go templates
@ -62,7 +62,7 @@ absolute path to all .tpl files in root.`)
externalAlertSource = flag.String("external.alert.source", "", `External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. externalAlertSource = flag.String("external.alert.source", "", `External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service.
Supports templating. For example, link to Grafana: 'explore?orgId=1&left=[\"now-1h\",\"now\",\"VictoriaMetrics\",{\"expr\": \"{{$expr|quotesEscape|crlfEscape|queryEscape}}\"},{\"mode\":\"Metrics\"},{\"ui\":[true,true,true,\"none\"]}]'. Supports templating. For example, link to Grafana: 'explore?orgId=1&left=[\"now-1h\",\"now\",\"VictoriaMetrics\",{\"expr\": \"{{$expr|quotesEscape|crlfEscape|queryEscape}}\"},{\"mode\":\"Metrics\"},{\"ui\":[true,true,true,\"none\"]}]'.
If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.`) If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.`)
externalLabels = flagutil.NewArray("external.label", "Optional label in the form 'Name=value' to add to all generated recording rules and alerts. "+ externalLabels = flagutil.NewArrayString("external.label", "Optional label in the form 'Name=value' to add to all generated recording rules and alerts. "+
"Pass multiple -label flags in order to add multiple label sets.") "Pass multiple -label flags in order to add multiple label sets.")
remoteReadLookBack = flag.Duration("remoteRead.lookback", time.Hour, "Lookback defines how far to look into past for alerts timeseries."+ remoteReadLookBack = flag.Duration("remoteRead.lookback", time.Hour, "Lookback defines how far to look into past for alerts timeseries."+

View file

@ -17,32 +17,32 @@ var (
configPath = flag.String("notifier.config", "", "Path to configuration file for notifiers") configPath = flag.String("notifier.config", "", "Path to configuration file for notifiers")
suppressDuplicateTargetErrors = flag.Bool("notifier.suppressDuplicateTargetErrors", false, "Whether to suppress 'duplicate target' errors during discovery") suppressDuplicateTargetErrors = flag.Bool("notifier.suppressDuplicateTargetErrors", false, "Whether to suppress 'duplicate target' errors during discovery")
addrs = flagutil.NewArray("notifier.url", "Prometheus alertmanager URL, e.g. http://127.0.0.1:9093") addrs = flagutil.NewArrayString("notifier.url", "Prometheus alertmanager URL, e.g. http://127.0.0.1:9093")
basicAuthUsername = flagutil.NewArray("notifier.basicAuth.username", "Optional basic auth username for -notifier.url") basicAuthUsername = flagutil.NewArrayString("notifier.basicAuth.username", "Optional basic auth username for -notifier.url")
basicAuthPassword = flagutil.NewArray("notifier.basicAuth.password", "Optional basic auth password for -notifier.url") basicAuthPassword = flagutil.NewArrayString("notifier.basicAuth.password", "Optional basic auth password for -notifier.url")
basicAuthPasswordFile = flagutil.NewArray("notifier.basicAuth.passwordFile", "Optional path to basic auth password file for -notifier.url") basicAuthPasswordFile = flagutil.NewArrayString("notifier.basicAuth.passwordFile", "Optional path to basic auth password file for -notifier.url")
bearerToken = flagutil.NewArray("notifier.bearerToken", "Optional bearer token for -notifier.url") bearerToken = flagutil.NewArrayString("notifier.bearerToken", "Optional bearer token for -notifier.url")
bearerTokenFile = flagutil.NewArray("notifier.bearerTokenFile", "Optional path to bearer token file for -notifier.url") bearerTokenFile = flagutil.NewArrayString("notifier.bearerTokenFile", "Optional path to bearer token file for -notifier.url")
tlsInsecureSkipVerify = flagutil.NewArrayBool("notifier.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to -notifier.url") tlsInsecureSkipVerify = flagutil.NewArrayBool("notifier.tlsInsecureSkipVerify", "Whether to skip tls verification when connecting to -notifier.url")
tlsCertFile = flagutil.NewArray("notifier.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting to -notifier.url") tlsCertFile = flagutil.NewArrayString("notifier.tlsCertFile", "Optional path to client-side TLS certificate file to use when connecting to -notifier.url")
tlsKeyFile = flagutil.NewArray("notifier.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to -notifier.url") tlsKeyFile = flagutil.NewArrayString("notifier.tlsKeyFile", "Optional path to client-side TLS certificate key to use when connecting to -notifier.url")
tlsCAFile = flagutil.NewArray("notifier.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to -notifier.url. "+ tlsCAFile = flagutil.NewArrayString("notifier.tlsCAFile", "Optional path to TLS CA file to use for verifying connections to -notifier.url. "+
"By default system CA is used") "By default system CA is used")
tlsServerName = flagutil.NewArray("notifier.tlsServerName", "Optional TLS server name to use for connections to -notifier.url. "+ tlsServerName = flagutil.NewArrayString("notifier.tlsServerName", "Optional TLS server name to use for connections to -notifier.url. "+
"By default the server name from -notifier.url is used") "By default the server name from -notifier.url is used")
oauth2ClientID = flagutil.NewArray("notifier.oauth2.clientID", "Optional OAuth2 clientID to use for -notifier.url. "+ oauth2ClientID = flagutil.NewArrayString("notifier.oauth2.clientID", "Optional OAuth2 clientID to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url") "If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2ClientSecret = flagutil.NewArray("notifier.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -notifier.url. "+ oauth2ClientSecret = flagutil.NewArrayString("notifier.oauth2.clientSecret", "Optional OAuth2 clientSecret to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url") "If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2ClientSecretFile = flagutil.NewArray("notifier.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -notifier.url. "+ oauth2ClientSecretFile = flagutil.NewArrayString("notifier.oauth2.clientSecretFile", "Optional OAuth2 clientSecretFile to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url") "If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2TokenURL = flagutil.NewArray("notifier.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for -notifier.url. "+ oauth2TokenURL = flagutil.NewArrayString("notifier.oauth2.tokenUrl", "Optional OAuth2 tokenURL to use for -notifier.url. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url") "If multiple args are set, then they are applied independently for the corresponding -notifier.url")
oauth2Scopes = flagutil.NewArray("notifier.oauth2.scopes", "Optional OAuth2 scopes to use for -notifier.url. Scopes must be delimited by ';'. "+ oauth2Scopes = flagutil.NewArrayString("notifier.oauth2.scopes", "Optional OAuth2 scopes to use for -notifier.url. Scopes must be delimited by ';'. "+
"If multiple args are set, then they are applied independently for the corresponding -notifier.url") "If multiple args are set, then they are applied independently for the corresponding -notifier.url")
) )

View file

@ -8,11 +8,11 @@ import (
"time" "time"
) )
// NewArray returns new Array with the given name and description. // NewArrayString returns new ArrayString with the given name and description.
func NewArray(name, description string) *Array { func NewArrayString(name, description string) *ArrayString {
description += "\nSupports an `array` of values separated by comma" + description += "\nSupports an `array` of values separated by comma" +
" or specified via multiple flags." " or specified via multiple flags."
var a Array var a ArrayString
flag.Var(&a, name, description) flag.Var(&a, name, description)
return &a return &a
} }
@ -36,7 +36,7 @@ func NewArrayBool(name, description string) *ArrayBool {
} }
// NewArrayInt returns new ArrayInt with the given name and description. // NewArrayInt returns new ArrayInt with the given name and description.
func NewArrayInt(name string, description string) *ArrayInt { func NewArrayInt(name, description string) *ArrayInt {
description += "\nSupports `array` of values separated by comma" + description += "\nSupports `array` of values separated by comma" +
" or specified via multiple flags." " or specified via multiple flags."
var a ArrayInt var a ArrayInt
@ -44,7 +44,16 @@ func NewArrayInt(name string, description string) *ArrayInt {
return &a return &a
} }
// Array is a flag that holds an array of values. // NewArrayBytes returns new ArrayBytes with the given name and description.
func NewArrayBytes(name, description string) *ArrayBytes {
description += "\nSupports `array` of values separated by comma" +
" or specified via multiple flags."
var a ArrayBytes
flag.Var(&a, name, description)
return &a
}
// ArrayString is a flag that holds an array of strings.
// //
// It may be set either by specifying multiple flags with the given name // It may be set either by specifying multiple flags with the given name
// passed to NewArray or by joining flag values by comma. // passed to NewArray or by joining flag values by comma.
@ -57,10 +66,10 @@ func NewArrayInt(name string, description string) *ArrayInt {
// Flag values may be quoted. For instance, the following arg creates an array of ("a", "b, c") items: // Flag values may be quoted. For instance, the following arg creates an array of ("a", "b, c") items:
// //
// -foo='a,"b, c"' // -foo='a,"b, c"'
type Array []string type ArrayString []string
// String implements flag.Value interface // String implements flag.Value interface
func (a *Array) String() string { func (a *ArrayString) String() string {
aEscaped := make([]string, len(*a)) aEscaped := make([]string, len(*a))
for i, v := range *a { for i, v := range *a {
if strings.ContainsAny(v, `", `+"\n") { if strings.ContainsAny(v, `", `+"\n") {
@ -72,7 +81,7 @@ func (a *Array) String() string {
} }
// Set implements flag.Value interface // Set implements flag.Value interface
func (a *Array) Set(value string) error { func (a *ArrayString) Set(value string) error {
values := parseArrayValues(value) values := parseArrayValues(value)
*a = append(*a, values...) *a = append(*a, values...)
return nil return nil
@ -141,7 +150,7 @@ func getNextArrayValue(s string) (string, string) {
} }
// GetOptionalArg returns optional arg under the given argIdx. // GetOptionalArg returns optional arg under the given argIdx.
func (a *Array) GetOptionalArg(argIdx int) string { func (a *ArrayString) GetOptionalArg(argIdx int) string {
x := *a x := *a
if argIdx >= len(x) { if argIdx >= len(x) {
if len(x) == 1 { if len(x) == 1 {
@ -153,7 +162,8 @@ func (a *Array) GetOptionalArg(argIdx int) string {
} }
// ArrayBool is a flag that holds an array of booleans values. // ArrayBool is a flag that holds an array of booleans values.
// have the same api as Array. //
// Has the same api as ArrayString.
type ArrayBool []bool type ArrayBool []bool
// IsBoolFlag implements flag.IsBoolFlag interface // IsBoolFlag implements flag.IsBoolFlag interface
@ -194,7 +204,8 @@ func (a *ArrayBool) GetOptionalArg(argIdx int) bool {
} }
// ArrayDuration is a flag that holds an array of time.Duration values. // ArrayDuration is a flag that holds an array of time.Duration values.
// have the same api as Array. //
// Has the same api as ArrayString.
type ArrayDuration []time.Duration type ArrayDuration []time.Duration
// String implements flag.Value interface // String implements flag.Value interface
@ -233,6 +244,8 @@ func (a *ArrayDuration) GetOptionalArgOrDefault(argIdx int, defaultValue time.Du
} }
// ArrayInt is flag that holds an array of ints. // ArrayInt is flag that holds an array of ints.
//
// Has the same api as ArrayString.
type ArrayInt []int type ArrayInt []int
// String implements flag.Value interface // String implements flag.Value interface
@ -259,7 +272,7 @@ func (a *ArrayInt) Set(value string) error {
} }
// GetOptionalArgOrDefault returns optional arg under the given argIdx. // GetOptionalArgOrDefault returns optional arg under the given argIdx.
func (a *ArrayInt) GetOptionalArgOrDefault(argIdx int, defaultValue int) int { func (a *ArrayInt) GetOptionalArgOrDefault(argIdx, defaultValue int) int {
x := *a x := *a
if argIdx < len(x) { if argIdx < len(x) {
return x[argIdx] return x[argIdx]
@ -269,3 +282,43 @@ func (a *ArrayInt) GetOptionalArgOrDefault(argIdx int, defaultValue int) int {
} }
return defaultValue return defaultValue
} }
// ArrayBytes is flag that holds an array of Bytes.
//
// Has the same api as ArrayString.
type ArrayBytes []*Bytes
// String implements flag.Value interface
func (a *ArrayBytes) String() string {
x := *a
formattedBytes := make([]string, len(x))
for i, v := range x {
formattedBytes[i] = v.String()
}
return strings.Join(formattedBytes, ",")
}
// Set implemented flag.Value interface
func (a *ArrayBytes) Set(value string) error {
values := parseArrayValues(value)
for _, v := range values {
var b Bytes
if err := b.Set(v); err != nil {
return err
}
*a = append(*a, &b)
}
return nil
}
// GetOptionalArgOrDefault returns optional arg under the given argIdx.
func (a *ArrayBytes) GetOptionalArgOrDefault(argIdx, defaultValue int) int {
x := *a
if argIdx < len(x) {
return x[argIdx].N
}
if len(x) == 1 {
return x[0].N
}
return defaultValue
}

View file

@ -9,21 +9,24 @@ import (
) )
var ( var (
fooFlag Array fooFlagString ArrayString
fooFlagDuration ArrayDuration fooFlagDuration ArrayDuration
fooFlagBool ArrayBool fooFlagBool ArrayBool
fooFlagInt ArrayInt fooFlagInt ArrayInt
fooFlagBytes ArrayBytes
) )
func init() { func init() {
os.Args = append(os.Args, "--fooFlag=foo", "--fooFlag=bar") os.Args = append(os.Args, "-fooFlagString=foo", "-fooFlagString=bar")
os.Args = append(os.Args, "--fooFlagDuration=10s", "--fooFlagDuration=5m") os.Args = append(os.Args, "-fooFlagDuration=10s", "-fooFlagDuration=5m")
os.Args = append(os.Args, "--fooFlagBool=true", "--fooFlagBool=false,true", "--fooFlagBool") os.Args = append(os.Args, "-fooFlagBool=true", "-fooFlagBool=false,true", "-fooFlagBool")
os.Args = append(os.Args, "--fooFlagInt=1", "--fooFlagInt=2,3") os.Args = append(os.Args, "-fooFlagInt=1", "-fooFlagInt=2,3")
flag.Var(&fooFlag, "fooFlag", "test") os.Args = append(os.Args, "-fooFlagBytes=10MB", "-fooFlagBytes=23,10kib")
flag.Var(&fooFlagString, "fooFlagString", "test")
flag.Var(&fooFlagDuration, "fooFlagDuration", "test") flag.Var(&fooFlagDuration, "fooFlagDuration", "test")
flag.Var(&fooFlagBool, "fooFlagBool", "test") flag.Var(&fooFlagBool, "fooFlagBool", "test")
flag.Var(&fooFlagInt, "fooFlagInt", "test") flag.Var(&fooFlagInt, "fooFlagInt", "test")
flag.Var(&fooFlagBytes, "fooFlagBytes", "test")
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
@ -31,25 +34,20 @@ func TestMain(m *testing.M) {
os.Exit(m.Run()) os.Exit(m.Run())
} }
func TestArray(t *testing.T) { func TestArrayString(t *testing.T) {
expected := []string{ expected := ArrayString{
"foo", "foo",
"bar", "bar",
} }
if len(expected) != len(fooFlag) { if !reflect.DeepEqual(expected, fooFlagString) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected)) t.Fatalf("unexpected flag values; got\n%q\nwant\n%q", fooFlagString, expected)
}
for i, v := range fooFlag {
if v != expected[i] {
t.Errorf("unexpected item in array %q", v)
}
} }
} }
func TestArraySet(t *testing.T) { func TestArrayString_Set(t *testing.T) {
f := func(s string, expectedValues []string) { f := func(s string, expectedValues []string) {
t.Helper() t.Helper()
var a Array var a ArrayString
_ = a.Set(s) _ = a.Set(s)
if !reflect.DeepEqual([]string(a), expectedValues) { if !reflect.DeepEqual([]string(a), expectedValues) {
t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues) t.Fatalf("unexpected values parsed;\ngot\n%q\nwant\n%q", a, expectedValues)
@ -66,10 +64,10 @@ func TestArraySet(t *testing.T) {
f(`,fo,"\"b, a'\\",,r,`, []string{``, `fo`, `"b, a'\`, ``, `r`, ``}) f(`,fo,"\"b, a'\\",,r,`, []string{``, `fo`, `"b, a'\`, ``, `r`, ``})
} }
func TestArrayGetOptionalArg(t *testing.T) { func TestArrayString_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue string) { f := func(s string, argIdx int, expectedValue string) {
t.Helper() t.Helper()
var a Array var a ArrayString
_ = a.Set(s) _ = a.Set(s)
v := a.GetOptionalArg(argIdx) v := a.GetOptionalArg(argIdx)
if v != expectedValue { if v != expectedValue {
@ -85,10 +83,10 @@ func TestArrayGetOptionalArg(t *testing.T) {
f("foo,bar", 2, "") f("foo,bar", 2, "")
} }
func TestArrayString(t *testing.T) { func TestArrayString_String(t *testing.T) {
f := func(s string) { f := func(s string) {
t.Helper() t.Helper()
var a Array var a ArrayString
_ = a.Set(s) _ = a.Set(s)
result := a.String() result := a.String()
if result != s { if result != s {
@ -105,21 +103,16 @@ func TestArrayString(t *testing.T) {
} }
func TestArrayDuration(t *testing.T) { func TestArrayDuration(t *testing.T) {
expected := []time.Duration{ expected := ArrayDuration{
time.Second * 10, time.Second * 10,
time.Minute * 5, time.Minute * 5,
} }
if len(expected) != len(fooFlagDuration) { if !reflect.DeepEqual(expected, fooFlagDuration) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected)) t.Fatalf("unexpected flag values; got\n%s\nwant\n%s", fooFlagDuration, expected)
}
for i, v := range fooFlagDuration {
if v != expected[i] {
t.Errorf("unexpected item in array %s", v)
}
} }
} }
func TestArrayDurationSet(t *testing.T) { func TestArrayDuration_Set(t *testing.T) {
f := func(s string, expectedValues []time.Duration) { f := func(s string, expectedValues []time.Duration) {
t.Helper() t.Helper()
var a ArrayDuration var a ArrayDuration
@ -133,8 +126,8 @@ func TestArrayDurationSet(t *testing.T) {
f(`5m,1s,1h`, []time.Duration{time.Minute * 5, time.Second, time.Hour}) f(`5m,1s,1h`, []time.Duration{time.Minute * 5, time.Second, time.Hour})
} }
func TestArrayDurationGetOptionalArg(t *testing.T) { func TestArrayDuration_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue, defaultValue time.Duration) { f := func(s string, argIdx int, defaultValue, expectedValue time.Duration) {
t.Helper() t.Helper()
var a ArrayDuration var a ArrayDuration
_ = a.Set(s) _ = a.Set(s)
@ -146,10 +139,10 @@ func TestArrayDurationGetOptionalArg(t *testing.T) {
f("", 0, time.Second, time.Second) f("", 0, time.Second, time.Second)
f("", 1, time.Minute, time.Minute) f("", 1, time.Minute, time.Minute)
f("10s,1m", 1, time.Minute, time.Minute) f("10s,1m", 1, time.Minute, time.Minute)
f("10s", 3, time.Second*10, time.Minute) f("10s", 3, time.Minute, time.Second*10)
} }
func TestArrayDurationString(t *testing.T) { func TestArrayDuration_String(t *testing.T) {
f := func(s string) { f := func(s string) {
t.Helper() t.Helper()
var a ArrayDuration var a ArrayDuration
@ -165,20 +158,15 @@ func TestArrayDurationString(t *testing.T) {
} }
func TestArrayBool(t *testing.T) { func TestArrayBool(t *testing.T) {
expected := []bool{ expected := ArrayBool{
true, false, true, true, true, false, true, true,
} }
if len(expected) != len(fooFlagBool) { if !reflect.DeepEqual(expected, fooFlagBool) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected)) t.Fatalf("unexpected flag values; got\n%v\nwant\n%v", fooFlagBool, expected)
}
for i, v := range fooFlagBool {
if v != expected[i] {
t.Errorf("unexpected item in array index=%v,value=%v,want=%v", i, v, expected[i])
}
} }
} }
func TestArrayBoolSet(t *testing.T) { func TestArrayBool_Set(t *testing.T) {
f := func(s string, expectedValues []bool) { f := func(s string, expectedValues []bool) {
t.Helper() t.Helper()
var a ArrayBool var a ArrayBool
@ -192,7 +180,7 @@ func TestArrayBoolSet(t *testing.T) {
f(`false,True,False`, []bool{false, true, false}) f(`false,True,False`, []bool{false, true, false})
} }
func TestArrayBoolGetOptionalArg(t *testing.T) { func TestArrayBool_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue bool) { f := func(s string, argIdx int, expectedValue bool) {
t.Helper() t.Helper()
var a ArrayBool var a ArrayBool
@ -208,7 +196,7 @@ func TestArrayBoolGetOptionalArg(t *testing.T) {
f("true", 2, true) f("true", 2, true)
} }
func TestArrayBoolString(t *testing.T) { func TestArrayBool_String(t *testing.T) {
f := func(s string) { f := func(s string) {
t.Helper() t.Helper()
var a ArrayBool var a ArrayBool
@ -225,18 +213,13 @@ func TestArrayBoolString(t *testing.T) {
} }
func TestArrayInt(t *testing.T) { func TestArrayInt(t *testing.T) {
expected := []int{1, 2, 3} expected := ArrayInt{1, 2, 3}
if len(expected) != len(fooFlagInt) { if !reflect.DeepEqual(expected, fooFlagInt) {
t.Errorf("len array flag (%d) is not equal to %d", len(fooFlag), len(expected)) t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", fooFlagInt, expected)
}
for i, n := range fooFlagInt {
if n != expected[i] {
t.Errorf("unexpected item in array %d", n)
}
} }
} }
func TestArrayIntSet(t *testing.T) { func TestArrayInt_Set(t *testing.T) {
f := func(s string, expectedValues []int) { f := func(s string, expectedValues []int) {
t.Helper() t.Helper()
var a ArrayInt var a ArrayInt
@ -250,8 +233,8 @@ func TestArrayIntSet(t *testing.T) {
f(`-2,3,-64`, []int{-2, 3, -64}) f(`-2,3,-64`, []int{-2, 3, -64})
} }
func TestArrayIntGetOptionalArg(t *testing.T) { func TestArrayInt_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx int, expectedValue, defaultValue int) { f := func(s string, argIdx, defaultValue, expectedValue int) {
t.Helper() t.Helper()
var a ArrayInt var a ArrayInt
_ = a.Set(s) _ = a.Set(s)
@ -262,11 +245,11 @@ func TestArrayIntGetOptionalArg(t *testing.T) {
} }
f("", 0, 123, 123) f("", 0, 123, 123)
f("", 1, -34, -34) f("", 1, -34, -34)
f("10,1", 1, 1, 234) f("10,1", 1, 234, 1)
f("10", 3, 10, -34) f("10", 3, -34, 10)
} }
func TestArrayIntString(t *testing.T) { func TestArrayInt_String(t *testing.T) {
f := func(s string) { f := func(s string) {
t.Helper() t.Helper()
var a ArrayInt var a ArrayInt
@ -280,3 +263,64 @@ func TestArrayIntString(t *testing.T) {
f("10,1") f("10,1")
f("-5,1,123") f("-5,1,123")
} }
func TestArrayBytes(t *testing.T) {
expected := []int{10000000, 23, 10240}
result := make([]int, len(fooFlagBytes))
for i, b := range fooFlagBytes {
result[i] = b.N
}
if !reflect.DeepEqual(expected, result) {
t.Fatalf("unexpected flag values; got\n%d\nwant\n%d", result, expected)
}
}
func TestArrayBytes_Set(t *testing.T) {
f := func(s string, expectedValues []int) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
values := make([]int, len(a))
for i, v := range a {
values[i] = v.N
}
if !reflect.DeepEqual(values, expectedValues) {
t.Fatalf("unexpected values parsed;\ngot\n%d\nwant\n%d", values, expectedValues)
}
}
f("", []int{})
f(`1`, []int{1})
f(`-2,3,10kb`, []int{-2, 3, 10000})
}
func TestArrayBytes_GetOptionalArg(t *testing.T) {
f := func(s string, argIdx, defaultValue, expectedValue int) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
v := a.GetOptionalArgOrDefault(argIdx, defaultValue)
if v != expectedValue {
t.Fatalf("unexpected value; got %d; want %d", v, expectedValue)
}
}
f("", 0, 123, 123)
f("", 1, -34, -34)
f("10,1", 1, 234, 1)
f("10,1", 3, 234, 234)
f("10Kb", 3, -34, 10000)
}
func TestArrayBytes_String(t *testing.T) {
f := func(s string) {
t.Helper()
var a ArrayBytes
_ = a.Set(s)
result := a.String()
if result != s {
t.Fatalf("unexpected string;\ngot\n%s\nwant\n%s", result, s)
}
}
f("")
f("10.5KiB,1")
f("-5,1,123MB")
}

View file

@ -34,7 +34,7 @@ var (
tlsEnable = flag.Bool("tls", false, "Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set") tlsEnable = flag.Bool("tls", false, "Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set")
tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated") tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower. The provided certificate file is automatically re-read every second, so it can be dynamically updated")
tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated") tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key if -tls is set. The provided key file is automatically re-read every second, so it can be dynamically updated")
tlsCipherSuites = flagutil.NewArray("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants") tlsCipherSuites = flagutil.NewArrayString("tlsCipherSuites", "Optional list of TLS cipher suites for incoming requests over HTTPS if -tls is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants")
tlsMinVersion = flag.String("tlsMinVersion", "", "Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. "+ tlsMinVersion = flag.String("tlsMinVersion", "", "Optional minimum TLS version to use for incoming requests over HTTPS if -tls is set. "+
"Supported values: TLS10, TLS11, TLS12, TLS13") "Supported values: TLS10, TLS11, TLS12, TLS13")

View file

@ -8,7 +8,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
) )
var influxDatabaseNames = flagutil.NewArray("influx.databaseNames", "Comma-separated list of database names to return from /query and /influx/query API. "+ var influxDatabaseNames = flagutil.NewArrayString("influx.databaseNames", "Comma-separated list of database names to return from /query and /influx/query API. "+
"This can be needed for accepting data from Telegraf plugins such as https://github.com/fangli/fluent-plugin-influxdb") "This can be needed for accepting data from Telegraf plugins such as https://github.com/fangli/fluent-plugin-influxdb")
// WriteDatabaseNames writes influxDatabaseNames to w. // WriteDatabaseNames writes influxDatabaseNames to w.

View file

@ -12,10 +12,10 @@ import (
) )
var ( var (
pushURL = flagutil.NewArray("pushmetrics.url", "Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . "+ pushURL = flagutil.NewArrayString("pushmetrics.url", "Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . "+
"By default metrics exposed at /metrics page aren't pushed to any remote storage") "By default metrics exposed at /metrics page aren't pushed to any remote storage")
pushInterval = flag.Duration("pushmetrics.interval", 10*time.Second, "Interval for pushing metrics to -pushmetrics.url") pushInterval = flag.Duration("pushmetrics.interval", 10*time.Second, "Interval for pushing metrics to -pushmetrics.url")
pushExtraLabel = flagutil.NewArray("pushmetrics.extraLabel", "Optional labels to add to metrics pushed to -pushmetrics.url . "+ pushExtraLabel = flagutil.NewArrayString("pushmetrics.extraLabel", "Optional labels to add to metrics pushed to -pushmetrics.url . "+
`For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url`) `For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url`)
) )