diff --git a/.gitignore b/.gitignore index 9e144be5..b7be45b8 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,9 @@ .DS_Store Dockerfile.cross .idea -bin/ -build* -bundle* +/bin/ +/build* +/bundle* release* operator.zip coverage.txt diff --git a/api/operator/v1beta1/common_scrapeparams.go b/api/operator/v1beta1/common_scrapeparams.go new file mode 100644 index 00000000..4512b950 --- /dev/null +++ b/api/operator/v1beta1/common_scrapeparams.go @@ -0,0 +1,269 @@ +package v1beta1 + +import ( + "encoding/json" + "fmt" + "reflect" + + v1 "k8s.io/api/core/v1" +) + +// AttachMetadata configures metadata attachment +type AttachMetadata struct { + // Node instructs vmagent to add node specific metadata from service discovery + // Valid for roles: pod, endpoints, endpointslice. + // +optional + Node *bool `json:"node,omitempty"` +} + +// VMScrapeParams defines scrape target configuration that compatible only with VictoriaMetrics scrapers +// VMAgent and VMSingle +type VMScrapeParams struct { + // DisableCompression + // +optional + DisableCompression *bool `json:"disable_compression,omitempty"` + // disable_keepalive allows disabling HTTP keep-alive when scraping targets. + // By default, HTTP keep-alive is enabled, so TCP connections to scrape targets + // could be re-used. + // See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements + // +optional + DisableKeepAlive *bool `json:"disable_keep_alive,omitempty"` + // +optional + DisableStaleMarkers *bool `json:"no_stale_markers,omitempty"` + // +optional + StreamParse *bool `json:"stream_parse,omitempty"` + // +optional + ScrapeAlignInterval *string `json:"scrape_align_interval,omitempty"` + // +optional + ScrapeOffset *string `json:"scrape_offset,omitempty"` + // ProxyClientConfig configures proxy auth settings for scraping + // See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy + // +optional + ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` + // Headers allows sending custom headers to scrape targets + // must be in of semicolon separated header with it's value + // eg: + // headerName: headerValue + // vmagent supports since 1.79.0 version + // +optional + Headers []string `json:"headers,omitempty"` +} + +// ProxyAuth represent proxy auth config +// Only VictoriaMetrics scrapers supports it. +// See https://github.com/VictoriaMetrics/VictoriaMetrics/commit/a6a71ef861444eb11fe8ec6d2387f0fc0c4aea87 +type ProxyAuth struct { + BasicAuth *BasicAuth `json:"basic_auth,omitempty"` + BearerToken *v1.SecretKeySelector `json:"bearer_token,omitempty"` + BearerTokenFile string `json:"bearer_token_file,omitempty"` + TLSConfig *TLSConfig `json:"tls_config,omitempty"` +} + +// OAuth2 defines OAuth2 configuration +type OAuth2 struct { + // The secret or configmap containing the OAuth2 client id + // +required + ClientID SecretOrConfigMap `json:"client_id"` + // The secret containing the OAuth2 client secret + // +optional + ClientSecret *v1.SecretKeySelector `json:"client_secret,omitempty"` + // ClientSecretFile defines path for client secret file. + // +optional + ClientSecretFile string `json:"client_secret_file,omitempty"` + // The URL to fetch the token from + // +kubebuilder:validation:MinLength=1 + // +required + TokenURL string `json:"token_url"` + // OAuth2 scopes used for the token request + // +optional + Scopes []string `json:"scopes,omitempty"` + // Parameters to append to the token URL + // +optional + EndpointParams map[string]string `json:"endpoint_params,omitempty"` +} + +// Authorization configures generic authorization params +type Authorization struct { + // Type of authorization, default to bearer + // +optional + Type string `json:"type,omitempty"` + // Reference to the secret with value for authorization + Credentials *v1.SecretKeySelector `json:"credentials,omitempty"` + // File with value for authorization + // +optional + CredentialsFile string `json:"credentialsFile,omitempty"` +} + +// RelabelConfig allows dynamic rewriting of the label set +// More info: https://docs.victoriametrics.com/#relabeling +// +k8s:openapi-gen=true +type RelabelConfig struct { + // UnderScoreSourceLabels - additional form of source labels source_labels + // for compatibility with original relabel config. + // if set both sourceLabels and source_labels, sourceLabels has priority. + // for details https://github.com/VictoriaMetrics/operator/issues/131 + // +optional + UnderScoreSourceLabels []string `json:"source_labels,omitempty" yaml:"source_labels,omitempty"` + // UnderScoreTargetLabel - additional form of target label - target_label + // for compatibility with original relabel config. + // if set both targetLabel and target_label, targetLabel has priority. + // for details https://github.com/VictoriaMetrics/operator/issues/131 + // +optional + UnderScoreTargetLabel string `json:"target_label,omitempty" yaml:"target_label,omitempty"` + + // The source labels select values from existing labels. Their content is concatenated + // using the configured separator and matched against the configured regular expression + // for the replace, keep, and drop actions. + // +optional + SourceLabels []string `json:"sourceLabels,omitempty" yaml:"-"` + // Separator placed between concatenated source label values. default is ';'. + // +optional + Separator string `json:"separator,omitempty" yaml:"separator,omitempty"` + // Label to which the resulting value is written in a replace action. + // It is mandatory for replace actions. Regex capture groups are available. + // +optional + TargetLabel string `json:"targetLabel,omitempty" yaml:"-"` + // Regular expression against which the extracted value is matched. Default is '(.*)' + // victoriaMetrics supports multiline regex joined with | + // https://docs.victoriametrics.com/vmagent/#relabeling-enhancements + // +optional + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + Regex StringOrArray `json:"regex,omitempty" yaml:"regex,omitempty"` + // Modulus to take of the hash of the source label values. + // +optional + Modulus uint64 `json:"modulus,omitempty" yaml:"modulus,omitempty"` + // Replacement value against which a regex replace is performed if the + // regular expression matches. Regex capture groups are available. Default is '$1' + // +optional + Replacement string `json:"replacement,omitempty" yaml:"replacement,omitempty"` + // Action to perform based on regex matching. Default is 'replace' + // +optional + Action string `json:"action,omitempty" yaml:"action,omitempty"` + // If represents metricsQL match expression (or list of expressions): '{__name__=~"foo_.*"}' + // +optional + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + If StringOrArray `json:"if,omitempty" yaml:"if,omitempty"` + // Match is used together with Labels for `action: graphite` + // +optional + Match string `json:"match,omitempty" yaml:"match,omitempty"` + // Labels is used together with Match for `action: graphite` + // +optional + Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` +} + +// UnmarshalJSON implements interface +// handles cases for snake and camel cases of json tags +func (rc *RelabelConfig) UnmarshalJSON(src []byte) error { + type rcfg RelabelConfig + if err := json.Unmarshal(src, (*rcfg)(rc)); err != nil { + return fmt.Errorf("cannot parse relabelConfig: %w", err) + } + + if len(rc.SourceLabels) == 0 && len(rc.UnderScoreSourceLabels) > 0 { + rc.SourceLabels = append(rc.SourceLabels, rc.UnderScoreSourceLabels...) + } + if len(rc.UnderScoreSourceLabels) == 0 && len(rc.SourceLabels) > 0 { + rc.UnderScoreSourceLabels = append(rc.UnderScoreSourceLabels, rc.SourceLabels...) + } + if rc.TargetLabel == "" && rc.UnderScoreTargetLabel != "" { + rc.TargetLabel = rc.UnderScoreTargetLabel + } + if rc.UnderScoreTargetLabel == "" && rc.TargetLabel != "" { + rc.UnderScoreTargetLabel = rc.TargetLabel + } + return nil +} + +// IsEmpty checks if given relabelConfig has only empty values +func (rc *RelabelConfig) IsEmpty() bool { + if rc == nil { + return true + } + return reflect.DeepEqual(*rc, RelabelConfig{}) +} + +// ScrapeTargetParams defines common configuration params for all scrape endpoint targets +type EndpointScrapeParams struct { + // HTTP path to scrape for metrics. + // +optional + Path string `json:"path,omitempty"` + // HTTP scheme to use for scraping. + // +optional + // +kubebuilder:validation:Enum=http;https + Scheme string `json:"scheme,omitempty"` + // Optional HTTP URL parameters + // +optional + Params map[string][]string `json:"params,omitempty"` + // FollowRedirects controls redirects for scraping. + // +optional + FollowRedirects *bool `json:"follow_redirects,omitempty"` + // SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. + // +optional + SampleLimit uint64 `json:"sampleLimit,omitempty"` + // SeriesLimit defines per-scrape limit on number of unique time series + // a single target can expose during all the scrapes on the time window of 24h. + // +optional + SeriesLimit uint64 `json:"seriesLimit,omitempty"` + // Interval at which metrics should be scraped + // +optional + Interval string `json:"interval,omitempty"` + // ScrapeInterval is the same as Interval and has priority over it. + // one of scrape_interval or interval can be used + // +optional + ScrapeInterval string `json:"scrape_interval,omitempty"` + // Timeout after which the scrape is ended + // +optional + ScrapeTimeout string `json:"scrapeTimeout,omitempty"` + // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. + // +optional + ProxyURL *string `json:"proxyURL,omitempty"` + // HonorLabels chooses the metric's labels on collisions with target labels. + // +optional + HonorLabels bool `json:"honorLabels,omitempty"` + // HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. + // +optional + HonorTimestamps *bool `json:"honorTimestamps,omitempty"` + // MaxScrapeSize defines a maximum size of scraped data for a job + // +optional + MaxScrapeSize string `json:"max_scrape_size,omitempty"` + // VMScrapeParams defines VictoriaMetrics specific scrape parameters + // +optional + VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` +} + +// EndpointAuth defines target endpoint authorization options for scrapping +type EndpointAuth struct { + // OAuth2 defines auth configuration + // +optional + OAuth2 *OAuth2 `json:"oauth2,omitempty"` + // TLSConfig configuration to use when scraping the endpoint + // +optional + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + // File to read bearer token for scraping targets. + // +optional + BearerTokenFile string `json:"bearerTokenFile,omitempty"` + // Secret to mount to read bearer token for scraping targets. The secret + // needs to be in the same namespace as the scrape object and accessible by + // the victoria-metrics operator. + // +optional + // +nullable + BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` + // BasicAuth allow an endpoint to authenticate over basic authentication + // +optional + BasicAuth *BasicAuth `json:"basicAuth,omitempty"` + // Authorization with http header Authorization + // +optional + Authorization *Authorization `json:"authorization,omitempty"` +} + +// EndpointRelabelings defines service discovery and metrics relabeling configuration for endpoints +type EndpointRelabelings struct { + // MetricRelabelConfigs to apply to samples after scrapping. + // +optional + MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` + // RelabelConfigs to apply to samples during service discovery. + // +optional + RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` +} diff --git a/api/operator/v1beta1/vmagent_types.go b/api/operator/v1beta1/vmagent_types.go index caba7383..cb8b20c7 100644 --- a/api/operator/v1beta1/vmagent_types.go +++ b/api/operator/v1beta1/vmagent_types.go @@ -16,6 +16,32 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +// VMAgentSecurityEnforcements defines security configuration for endpoint scrapping +type VMAgentSecurityEnforcements struct { + // OverrideHonorLabels if set to true overrides all user configured honor_labels. + // If HonorLabels is set in scrape objects to true, this overrides honor_labels to false. + // +optional + OverrideHonorLabels bool `json:"overrideHonorLabels,omitempty"` + // OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. + // +optional + OverrideHonorTimestamps bool `json:"overrideHonorTimestamps,omitempty"` + // IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from + // scrape objects, and they will only discover endpoints + // within their current namespace. Defaults to false. + // +optional + IgnoreNamespaceSelectors bool `json:"ignoreNamespaceSelectors,omitempty"` + // EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert + // and metric that is user created. The label value will always be the namespace of the object that is + // being created. + // +optional + EnforcedNamespaceLabel string `json:"enforcedNamespaceLabel,omitempty"` + // ArbitraryFSAccessThroughSMs configures whether configuration + // based on EndpointAuth can access arbitrary files on the file system + // of the VMAgent container e.g. bearer token files, basic auth, tls certs + // +optional + ArbitraryFSAccessThroughSMs ArbitraryFSAccessThroughSMsConfig `json:"arbitraryFSAccessThroughSMs,omitempty"` +} + // VMAgentSpec defines the desired state of VMAgent // +k8s:openapi-gen=true // +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="The version of VMAgent" @@ -155,23 +181,6 @@ type VMAgentSpec struct { // and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. // +optional APIServerConfig *APIServerConfig `json:"aPIServerConfig,omitempty"` - // OverrideHonorLabels if set to true overrides all user configured honor_labels. - // If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. - // +optional - OverrideHonorLabels bool `json:"overrideHonorLabels,omitempty"` - // OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. - // +optional - OverrideHonorTimestamps bool `json:"overrideHonorTimestamps,omitempty"` - // IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from - // the podscrape and vmservicescrape configs, and they will only discover endpoints - // within their current namespace. Defaults to false. - // +optional - IgnoreNamespaceSelectors bool `json:"ignoreNamespaceSelectors,omitempty"` - // EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert - // and metric that is user created. The label value will always be the namespace of the object that is - // being created. - // +optional - EnforcedNamespaceLabel string `json:"enforcedNamespaceLabel,omitempty"` // VMAgentExternalLabelName Name of vmAgent external label used to denote vmAgent instance // name. Defaults to the value of `prometheus`. External label will // _not_ be added when value is set to empty string (`""`). @@ -304,11 +313,6 @@ type VMAgentSpec struct { // VMAgent after the upgrade. // +optional AdditionalScrapeConfigs *v1.SecretKeySelector `json:"additionalScrapeConfigs,omitempty"` - // ArbitraryFSAccessThroughSMs configures whether configuration - // based on a service scrape can access arbitrary files on the file system - // of the VMAgent container e.g. bearer token files. - // +optional - ArbitraryFSAccessThroughSMs ArbitraryFSAccessThroughSMsConfig `json:"arbitraryFSAccessThroughSMs,omitempty"` // InsertPorts - additional listen ports for data ingestion. InsertPorts *InsertPorts `json:"insertPorts,omitempty"` // Port listen address @@ -433,7 +437,8 @@ type VMAgentSpec struct { // Paused If set to true all actions on the underlying managed objects are not // going to be performed, except for delete actions. // +optional - Paused bool `json:"paused,omitempty"` + Paused bool `json:"paused,omitempty"` + VMAgentSecurityEnforcements `json:",inline"` } // UnmarshalJSON implements json.Unmarshaler interface @@ -853,6 +858,28 @@ func (cr *VMAgent) GetAdditionalService() *AdditionalServiceSpec { return cr.Spec.ServiceSpec } +// APIServerConfig defines a host and auth methods to access apiserver. +// +k8s:openapi-gen=true +type APIServerConfig struct { + // Host of apiserver. + // A valid string consisting of a hostname or IP followed by an optional port number + Host string `json:"host"` + // BasicAuth allow an endpoint to authenticate over basic authentication + // +optional + BasicAuth *BasicAuth `json:"basicAuth,omitempty"` + // Bearer token for accessing apiserver. + // +optional + BearerToken string `json:"bearerToken,omitempty"` + // File to read bearer token for accessing apiserver. + // +optional + BearerTokenFile string `json:"bearerTokenFile,omitempty"` + // TLSConfig Config to use for accessing apiserver. + // +optional + TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + // +optional + Authorization *Authorization `json:"authorization,omitempty"` +} + func init() { SchemeBuilder.Register(&VMAgent{}, &VMAgentList{}) } diff --git a/api/operator/v1beta1/vmextra_types.go b/api/operator/v1beta1/vmextra_types.go index 080be696..6786a0c7 100644 --- a/api/operator/v1beta1/vmextra_types.go +++ b/api/operator/v1beta1/vmextra_types.go @@ -289,17 +289,16 @@ type BearerAuth struct { // BasicAuth allow an endpoint to authenticate over basic authentication // +k8s:openapi-gen=true type BasicAuth struct { - // The secret in the service scrape namespace that contains the username - // for authentication. - // It must be at them same namespace as CRD + // Username defines reference for secret with username value + // The secret needs to be in the same namespace as scrape object // +optional Username v1.SecretKeySelector `json:"username,omitempty"` - // The secret in the service scrape namespace that contains the password - // for authentication. - // It must be at them same namespace as CRD + // Password defines reference for secret with password value + // The secret needs to be in the same namespace as scrape object // +optional Password v1.SecretKeySelector `json:"password,omitempty"` // PasswordFile defines path to password file at disk + // must be pre-mounted // +optional PasswordFile string `json:"password_file,omitempty"` } @@ -733,3 +732,169 @@ func (l *License) sanityCheck() error { return nil } + +// SecretOrConfigMap allows to specify data as a Secret or ConfigMap. Fields are mutually exclusive. +type SecretOrConfigMap struct { + // Secret containing data to use for the targets. + // +optional + Secret *v1.SecretKeySelector `json:"secret,omitempty"` + // ConfigMap containing data to use for the targets. + // +optional + ConfigMap *v1.ConfigMapKeySelector `json:"configMap,omitempty"` +} + +// TLSConfig specifies TLSConfig configuration parameters. +// +k8s:openapi-gen=true +type TLSConfig struct { + // Path to the CA cert in the container to use for the targets. + // +optional + CAFile string `json:"caFile,omitempty"` + // Stuct containing the CA cert to use for the targets. + // +optional + CA SecretOrConfigMap `json:"ca,omitempty"` + + // Path to the client cert file in the container for the targets. + // +optional + CertFile string `json:"certFile,omitempty"` + // Struct containing the client cert file for the targets. + // +optional + Cert SecretOrConfigMap `json:"cert,omitempty"` + + // Path to the client key file in the container for the targets. + // +optional + KeyFile string `json:"keyFile,omitempty"` + // Secret containing the client key file for the targets. + // +optional + KeySecret *v1.SecretKeySelector `json:"keySecret,omitempty"` + + // Used to verify the hostname for the targets. + // +optional + ServerName string `json:"serverName,omitempty"` + // Disable target certificate validation. + // +optional + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` +} + +func (c *TLSConfig) AsArgs(args []string, prefix, pathPrefix string) []string { + if c.CAFile != "" { + args = append(args, fmt.Sprintf("-%s.tlsCAFile=%s", prefix, c.CAFile)) + } else if c.CA.Name() != "" { + args = append(args, fmt.Sprintf("-%s.tlsCAFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.CA.Name(), c.CA.Key()))) + } + if c.CertFile != "" { + args = append(args, fmt.Sprintf("-%s.tlsCertFile=%s", prefix, c.CertFile)) + } else if c.Cert.Name() != "" { + args = append(args, fmt.Sprintf("-%s.tlsCertFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.Cert.Name(), c.Cert.Key()))) + } + if c.KeyFile != "" { + args = append(args, fmt.Sprintf("-%s.tlsKeyFile=%s", prefix, c.KeyFile)) + } else if c.KeySecret != nil { + args = append(args, fmt.Sprintf("-%s.tlsKeyFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.KeySecret.Name, c.KeySecret.Key))) + } + if c.ServerName != "" { + args = append(args, fmt.Sprintf("-%s.tlsServerName=%s", prefix, c.ServerName)) + } + if c.InsecureSkipVerify { + args = append(args, fmt.Sprintf("-%s.tlsInsecureSkipVerify=%v", prefix, c.InsecureSkipVerify)) + } + return args +} + +// TLSConfigValidationError is returned by TLSConfig.Validate() on semantically +// invalid tls configurations. +// +k8s:openapi-gen=false +type TLSConfigValidationError struct { + err string +} + +func (e *TLSConfigValidationError) Error() string { + return e.err +} + +// Validate semantically validates the given TLSConfig. +func (c *TLSConfig) Validate() error { + if c.CA != (SecretOrConfigMap{}) { + if c.CAFile != "" { + return &TLSConfigValidationError{"tls config can not both specify CAFile and CA"} + } + if err := c.CA.Validate(); err != nil { + return err + } + } + + if c.Cert != (SecretOrConfigMap{}) { + if c.CertFile != "" { + return &TLSConfigValidationError{"tls config can not both specify CertFile and Cert"} + } + if err := c.Cert.Validate(); err != nil { + return err + } + } + + if c.KeyFile != "" && c.KeySecret != nil { + return &TLSConfigValidationError{"tls config can not both specify KeyFile and KeySecret"} + } + + return nil +} + +// SecretOrConfigMapValidationError is returned by SecretOrConfigMap.Validate() +// on semantically invalid configurations. +// +k8s:openapi-gen=false +type SecretOrConfigMapValidationError struct { + err string +} + +func (e *SecretOrConfigMapValidationError) Error() string { + return e.err +} + +// Validate semantically validates the given TLSConfig. +func (c *SecretOrConfigMap) Validate() error { + if c.Secret != nil && c.ConfigMap != nil { + return &SecretOrConfigMapValidationError{"SecretOrConfigMap can not specify both Secret and ConfigMap"} + } + + return nil +} + +// BuildSelectorWithPrefix builds prefix path +func (c *SecretOrConfigMap) BuildSelectorWithPrefix(prefix string) string { + if c.Secret != nil { + return fmt.Sprintf("%s%s/%s", prefix, c.Secret.Name, c.Secret.Key) + } + if c.ConfigMap != nil { + return fmt.Sprintf("%s%s/%s", prefix, c.ConfigMap.Name, c.ConfigMap.Key) + } + return "" +} + +// Name returns actual name +func (c *SecretOrConfigMap) Name() string { + if c.Secret != nil { + return c.Secret.Name + } + if c.ConfigMap != nil { + return c.ConfigMap.Name + } + return "" +} + +// Key returns actual key name +func (c *SecretOrConfigMap) Key() string { + if c.Secret != nil { + return c.Secret.Key + } + if c.ConfigMap != nil { + return c.ConfigMap.Key + } + return "" +} + +// BuildAssetPath buildds path for usage with assets +func (c *TLSConfig) BuildAssetPath(prefix, name, key string) string { + if name == "" || key == "" { + return "" + } + return fmt.Sprintf("%s_%s_%s", prefix, name, key) +} diff --git a/api/operator/v1beta1/vmnodescrape_types.go b/api/operator/v1beta1/vmnodescrape_types.go index bbda9541..d36510a7 100644 --- a/api/operator/v1beta1/vmnodescrape_types.go +++ b/api/operator/v1beta1/vmnodescrape_types.go @@ -3,7 +3,6 @@ package v1beta1 import ( "fmt" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -17,81 +16,17 @@ type VMNodeScrapeSpec struct { TargetLabels []string `json:"targetLabels,omitempty"` // Name of the port exposed at Node. // +optional - Port string `json:"port,omitempty"` - // HTTP path to scrape for metrics. - // +optional - Path string `json:"path,omitempty"` - // HTTP scheme to use for scraping. - // +optional - // +kubebuilder:validation:Enum=http;https - Scheme string `json:"scheme,omitempty"` - // Optional HTTP URL parameters - // +optional - Params map[string][]string `json:"params,omitempty"` - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - // Interval at which metrics should be scraped - // +optional - Interval string `json:"interval,omitempty"` - // ScrapeInterval is the same as Interval and has priority over it. - // one of scrape_interval or interval can be used - // +optional - ScrapeInterval string `json:"scrape_interval,omitempty"` - // Timeout after which the scrape is ended - // +optional - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // Authorization with http header Authorization - // +optional - Authorization *Authorization `json:"authorization,omitempty"` // TLSConfig configuration to use when scraping the node - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // File to read bearer token for scraping targets. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // Secret to mount to read bearer token for scraping targets. The secret - // needs to be accessible by - // the victoria-metrics operator. - // +optional - // +nullable - BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` - // HonorLabels chooses the metric's labels on collisions with target labels. - // +optional - HonorLabels bool `json:"honorLabels,omitempty"` - // HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. - // +optional - HonorTimestamps *bool `json:"honorTimestamps,omitempty"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // MetricRelabelConfigs to apply to samples after scrapping. - // +optional - MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - // RelabelConfigs to apply to samples during service discovery. - // +optional - RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` + Port string `json:"port,omitempty"` + EndpointRelabelings `json:",inline"` + EndpointAuth `json:",inline"` + EndpointScrapeParams `json:",inline"` + // Selector to select kubernetes Nodes. // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Service selector" // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:selector:" // +optional Selector metav1.LabelSelector `json:"selector,omitempty"` - // SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters - // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` } // VMNodeScrapeStatus defines the observed state of VMNodeScrape diff --git a/api/operator/v1beta1/vmpodscrape_types.go b/api/operator/v1beta1/vmpodscrape_types.go index f1dfe8ac..556dcbb7 100644 --- a/api/operator/v1beta1/vmpodscrape_types.go +++ b/api/operator/v1beta1/vmpodscrape_types.go @@ -3,7 +3,6 @@ package v1beta1 import ( "fmt" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -73,82 +72,16 @@ type VMPodScrapeList struct { // PodMetricsEndpoint defines a scrapeable endpoint of a Kubernetes Pod serving metrics. // +k8s:openapi-gen=true type PodMetricsEndpoint struct { - // TargetPort - // Name or number of the pod port this endpoint refers to. Mutually exclusive with port. - // +optional - TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` - // Name of the pod port this endpoint refers to. Mutually exclusive with targetPort. + // Name of the port exposed at Pod. // +optional Port string `json:"port,omitempty"` - // HTTP path to scrape for metrics. - // +optional - Path string `json:"path,omitempty"` - // HTTP scheme to use for scraping. - // +optional - // +kubebuilder:validation:Enum=http;https - Scheme string `json:"scheme,omitempty"` - // Optional HTTP URL parameters - // +optional - Params map[string][]string `json:"params,omitempty"` - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - // Interval at which metrics should be scraped - // +optional - Interval string `json:"interval,omitempty"` - // ScrapeInterval is the same as Interval and has priority over it. - // one of scrape_interval or interval can be used - // +optional - ScrapeInterval string `json:"scrape_interval,omitempty"` - // Timeout after which the scrape is ended - // +optional - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // SampleLimit defines per-podEndpoint limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // HonorLabels chooses the metric's labels on collisions with target labels. - // +optional - HonorLabels bool `json:"honorLabels,omitempty"` - // HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. - // +optional - HonorTimestamps *bool `json:"honorTimestamps,omitempty"` - // MetricRelabelConfigs to apply to samples after scrapping. - // +optional - MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - // RelabelConfigs to apply to samples during service discovery. - // +optional - RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // File to read bearer token for scraping targets. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // Secret to mount to read bearer token for scraping targets. The secret - // needs to be in the same namespace as the service scrape and accessible by - // the victoria-metrics operator. - // +optional - // +nullable - BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` - // TLSConfig configuration to use when scraping the endpoint - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // Authorization with http header Authorization - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters + // TargetPort + // Name or number of the pod port this endpoint refers to. Mutually exclusive with port. // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` + TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` + EndpointRelabelings `json:",inline"` + EndpointAuth `json:",inline"` + EndpointScrapeParams `json:",inline"` // AttachMetadata configures metadata attaching from service discovery // +optional AttachMetadata AttachMetadata `json:"attach_metadata,omitempty"` diff --git a/api/operator/v1beta1/vmprobe_types.go b/api/operator/v1beta1/vmprobe_types.go index b84e6674..8c442a72 100644 --- a/api/operator/v1beta1/vmprobe_types.go +++ b/api/operator/v1beta1/vmprobe_types.go @@ -19,7 +19,6 @@ package v1beta1 import ( "fmt" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -37,55 +36,12 @@ type VMProbeSpec struct { Module string `json:"module,omitempty"` // Targets defines a set of static and/or dynamically discovered targets to be probed using the prober. Targets VMProbeTargets `json:"targets,omitempty"` - // Interval at which targets are probed using the configured prober. - // If not specified global scrape interval is used. - Interval string `json:"interval,omitempty"` - // ScrapeInterval is the same as Interval and has priority over it. - // one of scrape_interval or interval can be used + // MetricRelabelConfigs to apply to samples after scrapping. // +optional - ScrapeInterval string `json:"scrape_interval,omitempty"` - // Timeout for scraping metrics from the blackbox exporter. - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // Optional HTTP URL parameters - // +optional - Params map[string][]string `json:"params,omitempty"` - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - // SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // File to read bearer token for scraping targets. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // Secret to mount to read bearer token for scraping targets. The secret - // needs to be in the same namespace as the service scrape and accessible by - // the victoria-metrics operator. - // +optional - // +nullable - BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // Authorization with http header Authorization - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // TLSConfig configuration to use when scraping the endpoint - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters - // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` + MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` + + EndpointAuth `json:",inline"` + EndpointScrapeParams `json:",inline"` } // VMProbeTargets defines a set of static and dynamically discovered targets for the prober. diff --git a/api/operator/v1beta1/vmscrapeconfig_types.go b/api/operator/v1beta1/vmscrapeconfig_types.go index c02014e4..2e43f6a5 100644 --- a/api/operator/v1beta1/vmscrapeconfig_types.go +++ b/api/operator/v1beta1/vmscrapeconfig_types.go @@ -73,69 +73,9 @@ type VMScrapeConfigSpec struct { // DigitalOceanSDConfigs defines a list of DigitalOcean service discovery configurations. // +optional DigitalOceanSDConfigs []DigitalOceanSDConfig `json:"digitalOceanSDConfigs,omitempty"` - // MetricsPath HTTP path to scrape for metrics. If empty, use the default value (e.g. /metrics). - // +optional - MetricsPath *string `json:"metricsPath,omitempty"` - // ScrapeInterval is the interval between consecutive scrapes. - // +optional - ScrapeInterval string `json:"scrapeInterval,omitempty"` - // ScrapeTimeout is the number of seconds to wait until a scrape request times out. - // +optional - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // MaxScrapeSize defines a maximum size of scraped data for a job - // +optional - MaxScrapeSize string `json:"max_scrape_size,omitempty"` - // HonorTimestamps controls whether to respect the timestamps present in scraped data. - // +optional - HonorTimestamps *bool `json:"honorTimestamps,omitempty"` - // HonorLabels chooses the metric's labels on collisions with target labels. - // +optional - HonorLabels bool `json:"honorLabels,omitempty"` - // Optional HTTP URL parameters - // +optional - // +mapType:=atomic - Params map[string][]string `json:"params,omitempty"` - // Configures the protocol scheme used for requests. - // If empty, use HTTP by default. - // +kubebuilder:validation:Enum=HTTP;HTTPS - // +optional - Scheme *string `json:"scheme,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters - // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` - - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // BasicAuth information to use on every scrape request. - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // Authorization header to use on every scrape request. - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // TLS configuration to use on every scrape request - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // MetricRelabelConfigs to apply to samples after scrapping. - // +optional - MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - // RelabelConfigs to apply to samples during service discovery. - // +optional - RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` + EndpointScrapeParams `json:",inline"` + EndpointRelabelings `json:",inline"` + EndpointAuth `json:",inline"` } // StaticConfig defines a static configuration. diff --git a/api/operator/v1beta1/vmservicescrape_types.go b/api/operator/v1beta1/vmservicescrape_types.go index 3a81d04b..3c8b5d45 100644 --- a/api/operator/v1beta1/vmservicescrape_types.go +++ b/api/operator/v1beta1/vmservicescrape_types.go @@ -1,11 +1,8 @@ package v1beta1 import ( - "encoding/json" "fmt" - "reflect" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -115,447 +112,22 @@ func (ns *NamespaceSelector) IsMatch(item nsMatcher) bool { // Endpoint defines a scrapeable endpoint serving metrics. // +k8s:openapi-gen=true type Endpoint struct { - // Name of the service port this endpoint refers to. Mutually exclusive with targetPort. + // Name of the port exposed at Service. // +optional Port string `json:"port,omitempty"` + + // TargetPort // Name or number of the pod port this endpoint refers to. Mutually exclusive with port. // +optional TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` - // HTTP path to scrape for metrics. - // +optional - Path string `json:"path,omitempty"` - // HTTP scheme to use for scraping. - // +optional - // +kubebuilder:validation:Enum=http;https - Scheme string `json:"scheme,omitempty"` - // Optional HTTP URL parameters - // +optional - Params map[string][]string `json:"params,omitempty"` - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - // Interval at which metrics should be scraped - // +optional - Interval string `json:"interval,omitempty"` - // ScrapeInterval is the same as Interval and has priority over it. - // one of scrape_interval or interval can be used - // +optional - ScrapeInterval string `json:"scrape_interval,omitempty"` - // Timeout after which the scrape is ended - // +optional - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // SampleLimit defines per-endpoint limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // Authorization with http header Authorization - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // TLSConfig configuration to use when scraping the endpoint - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // File to read bearer token for scraping targets. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // Secret to mount to read bearer token for scraping targets. The secret - // needs to be in the same namespace as the service scrape and accessible by - // the victoria-metrics operator. - // +optional - // +nullable - BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` - // HonorLabels chooses the metric's labels on collisions with target labels. - // +optional - HonorLabels bool `json:"honorLabels,omitempty"` - // HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. - // +optional - HonorTimestamps *bool `json:"honorTimestamps,omitempty"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // MetricRelabelConfigs to apply to samples after scrapping. - // +optional - MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - // RelabelConfigs to apply to samples during service discovery. - // +optional - RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters - // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` - // AttachMetadata configures metadata attaching from service discovery - // +optional - AttachMetadata AttachMetadata `json:"attach_metadata,omitempty"` -} - -// AttachMetadata configures metadata attachment -type AttachMetadata struct { - // Node instructs vmagent to add node specific metadata from service discovery - // Valid for roles: pod, endpoints, endpointslice. - // +optional - Node *bool `json:"node,omitempty"` -} - -// VMScrapeParams defines scrape target configuration that compatible only with VictoriaMetrics scrapers -// VMAgent and VMSingle -type VMScrapeParams struct { - // deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), will be removed in next release - // +optional - RelabelDebug *bool `json:"relabel_debug,omitempty"` - // deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), will be removed in next release - // +optional - MetricRelabelDebug *bool `json:"metric_relabel_debug,omitempty"` - // +optional - DisableCompression *bool `json:"disable_compression,omitempty"` - // disable_keepalive allows disabling HTTP keep-alive when scraping targets. - // By default, HTTP keep-alive is enabled, so TCP connections to scrape targets - // could be re-used. - // See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) - // +optional - DisableKeepAlive *bool `json:"disable_keep_alive,omitempty"` - // +optional - DisableStaleMarkers *bool `json:"no_stale_markers,omitempty"` - // +optional - StreamParse *bool `json:"stream_parse,omitempty"` - // +optional - ScrapeAlignInterval *string `json:"scrape_align_interval,omitempty"` - // +optional - ScrapeOffset *string `json:"scrape_offset,omitempty"` - // ProxyClientConfig configures proxy auth settings for scraping - // See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) - // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` - // Headers allows sending custom headers to scrape targets - // must be in of semicolon separated header with it's value - // eg: - // headerName: headerValue - // vmagent supports since 1.79.0 version - // +optional - Headers []string `json:"headers,omitempty"` -} - -// ProxyAuth represent proxy auth config -// Only VictoriaMetrics scrapers supports it. -// See https://github.com/VictoriaMetrics/VictoriaMetrics/commit/a6a71ef861444eb11fe8ec6d2387f0fc0c4aea87 -type ProxyAuth struct { - BasicAuth *BasicAuth `json:"basic_auth,omitempty"` - BearerToken *v1.SecretKeySelector `json:"bearer_token,omitempty"` - BearerTokenFile string `json:"bearer_token_file,omitempty"` - TLSConfig *TLSConfig `json:"tls_config,omitempty"` -} - -// OAuth2 defines OAuth2 configuration -type OAuth2 struct { - // The secret or configmap containing the OAuth2 client id - // +required - ClientID SecretOrConfigMap `json:"client_id"` - // The secret containing the OAuth2 client secret - // +optional - ClientSecret *v1.SecretKeySelector `json:"client_secret,omitempty"` - // ClientSecretFile defines path for client secret file. - // +optional - ClientSecretFile string `json:"client_secret_file,omitempty"` - // The URL to fetch the token from - // +kubebuilder:validation:MinLength=1 - // +required - TokenURL string `json:"token_url"` - // OAuth2 scopes used for the token request - // +optional - Scopes []string `json:"scopes,omitempty"` - // Parameters to append to the token URL - // +optional - EndpointParams map[string]string `json:"endpoint_params,omitempty"` -} -// Authorization configures generic authorization params -type Authorization struct { - // Type of authorization, default to bearer - // +optional - Type string `json:"type,omitempty"` - // Reference to the secret with value for authorization - Credentials *v1.SecretKeySelector `json:"credentials,omitempty"` - // File with value for authorization - // +optional - CredentialsFile string `json:"credentialsFile,omitempty"` -} + EndpointRelabelings `json:",inline"` + EndpointAuth `json:",inline"` + EndpointScrapeParams `json:",inline"` -// TLSConfig specifies TLSConfig configuration parameters. -// +k8s:openapi-gen=true -type TLSConfig struct { - // Path to the CA cert in the container to use for the targets. - // +optional - CAFile string `json:"caFile,omitempty"` - // Stuct containing the CA cert to use for the targets. - // +optional - CA SecretOrConfigMap `json:"ca,omitempty"` - - // Path to the client cert file in the container for the targets. - // +optional - CertFile string `json:"certFile,omitempty"` - // Struct containing the client cert file for the targets. - // +optional - Cert SecretOrConfigMap `json:"cert,omitempty"` - - // Path to the client key file in the container for the targets. - // +optional - KeyFile string `json:"keyFile,omitempty"` - // Secret containing the client key file for the targets. - // +optional - KeySecret *v1.SecretKeySelector `json:"keySecret,omitempty"` - - // Used to verify the hostname for the targets. - // +optional - ServerName string `json:"serverName,omitempty"` - // Disable target certificate validation. - // +optional - InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` -} - -func (c *TLSConfig) AsArgs(args []string, prefix, pathPrefix string) []string { - if c.CAFile != "" { - args = append(args, fmt.Sprintf("-%s.tlsCAFile=%s", prefix, c.CAFile)) - } else if c.CA.Name() != "" { - args = append(args, fmt.Sprintf("-%s.tlsCAFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.CA.Name(), c.CA.Key()))) - } - if c.CertFile != "" { - args = append(args, fmt.Sprintf("-%s.tlsCertFile=%s", prefix, c.CertFile)) - } else if c.Cert.Name() != "" { - args = append(args, fmt.Sprintf("-%s.tlsCertFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.Cert.Name(), c.Cert.Key()))) - } - if c.KeyFile != "" { - args = append(args, fmt.Sprintf("-%s.tlsKeyFile=%s", prefix, c.KeyFile)) - } else if c.KeySecret != nil { - args = append(args, fmt.Sprintf("-%s.tlsKeyFile=%s", prefix, c.BuildAssetPath(pathPrefix, c.KeySecret.Name, c.KeySecret.Key))) - } - if c.ServerName != "" { - args = append(args, fmt.Sprintf("-%s.tlsServerName=%s", prefix, c.ServerName)) - } - if c.InsecureSkipVerify { - args = append(args, fmt.Sprintf("-%s.tlsInsecureSkipVerify=%v", prefix, c.InsecureSkipVerify)) - } - return args -} - -// SecretOrConfigMap allows to specify data as a Secret or ConfigMap. Fields are mutually exclusive. -type SecretOrConfigMap struct { - // Secret containing data to use for the targets. - // +optional - Secret *v1.SecretKeySelector `json:"secret,omitempty"` - // ConfigMap containing data to use for the targets. - // +optional - ConfigMap *v1.ConfigMapKeySelector `json:"configMap,omitempty"` -} - -// RelabelConfig allows dynamic rewriting of the label set -// More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) -// +k8s:openapi-gen=true -type RelabelConfig struct { - // UnderScoreSourceLabels - additional form of source labels source_labels - // for compatibility with original relabel config. - // if set both sourceLabels and source_labels, sourceLabels has priority. - // for details https://github.com/VictoriaMetrics/operator/issues/131 - // +optional - UnderScoreSourceLabels []string `json:"source_labels,omitempty" yaml:"source_labels,omitempty"` - // UnderScoreTargetLabel - additional form of target label - target_label - // for compatibility with original relabel config. - // if set both targetLabel and target_label, targetLabel has priority. - // for details https://github.com/VictoriaMetrics/operator/issues/131 - // +optional - UnderScoreTargetLabel string `json:"target_label,omitempty" yaml:"target_label,omitempty"` - - // The source labels select values from existing labels. Their content is concatenated - // using the configured separator and matched against the configured regular expression - // for the replace, keep, and drop actions. - // +optional - SourceLabels []string `json:"sourceLabels,omitempty" yaml:"-"` - // Separator placed between concatenated source label values. default is ';'. - // +optional - Separator string `json:"separator,omitempty" yaml:"separator,omitempty"` - // Label to which the resulting value is written in a replace action. - // It is mandatory for replace actions. Regex capture groups are available. - // +optional - TargetLabel string `json:"targetLabel,omitempty" yaml:"-"` - // Regular expression against which the extracted value is matched. Default is '(.*)' - // victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | - // +optional - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - Regex StringOrArray `json:"regex,omitempty" yaml:"regex,omitempty"` - // Modulus to take of the hash of the source label values. - // +optional - Modulus uint64 `json:"modulus,omitempty" yaml:"modulus,omitempty"` - // Replacement value against which a regex replace is performed if the - // regular expression matches. Regex capture groups are available. Default is '$1' - // +optional - Replacement string `json:"replacement,omitempty" yaml:"replacement,omitempty"` - // Action to perform based on regex matching. Default is 'replace' - // +optional - Action string `json:"action,omitempty" yaml:"action,omitempty"` - // If represents metricsQL match expression (or list of expressions): '{__name__=~"foo_.*"}' - // +optional - // +kubebuilder:validation:Schemaless - // +kubebuilder:pruning:PreserveUnknownFields - If StringOrArray `json:"if,omitempty" yaml:"if,omitempty"` - // Match is used together with Labels for `action: graphite` - // +optional - Match string `json:"match,omitempty" yaml:"match,omitempty"` - // Labels is used together with Match for `action: graphite` - // +optional - Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` -} - -// UnmarshalJSON implements interface -// handles cases for snake and camel cases of json tags -func (rc *RelabelConfig) UnmarshalJSON(src []byte) error { - type rcfg RelabelConfig - if err := json.Unmarshal(src, (*rcfg)(rc)); err != nil { - return fmt.Errorf("cannot parse relabelConfig: %w", err) - } - - if len(rc.SourceLabels) == 0 && len(rc.UnderScoreSourceLabels) > 0 { - rc.SourceLabels = append(rc.SourceLabels, rc.UnderScoreSourceLabels...) - } - if len(rc.UnderScoreSourceLabels) == 0 && len(rc.SourceLabels) > 0 { - rc.UnderScoreSourceLabels = append(rc.UnderScoreSourceLabels, rc.SourceLabels...) - } - if rc.TargetLabel == "" && rc.UnderScoreTargetLabel != "" { - rc.TargetLabel = rc.UnderScoreTargetLabel - } - if rc.UnderScoreTargetLabel == "" && rc.TargetLabel != "" { - rc.UnderScoreTargetLabel = rc.TargetLabel - } - return nil -} - -func (rc *RelabelConfig) IsEmpty() bool { - if rc == nil { - return true - } - return reflect.DeepEqual(*rc, RelabelConfig{}) -} - -// TLSConfigValidationError is returned by TLSConfig.Validate() on semantically -// invalid tls configurations. -// +k8s:openapi-gen=false -type TLSConfigValidationError struct { - err string -} - -func (e *TLSConfigValidationError) Error() string { - return e.err -} - -// Validate semantically validates the given TLSConfig. -func (c *TLSConfig) Validate() error { - if c.CA != (SecretOrConfigMap{}) { - if c.CAFile != "" { - return &TLSConfigValidationError{"tls config can not both specify CAFile and CA"} - } - if err := c.CA.Validate(); err != nil { - return err - } - } - - if c.Cert != (SecretOrConfigMap{}) { - if c.CertFile != "" { - return &TLSConfigValidationError{"tls config can not both specify CertFile and Cert"} - } - if err := c.Cert.Validate(); err != nil { - return err - } - } - - if c.KeyFile != "" && c.KeySecret != nil { - return &TLSConfigValidationError{"tls config can not both specify KeyFile and KeySecret"} - } - - return nil -} - -// SecretOrConfigMapValidationError is returned by SecretOrConfigMap.Validate() -// on semantically invalid configurations. -// +k8s:openapi-gen=false -type SecretOrConfigMapValidationError struct { - err string -} - -func (e *SecretOrConfigMapValidationError) Error() string { - return e.err -} - -// Validate semantically validates the given TLSConfig. -func (c *SecretOrConfigMap) Validate() error { - if c.Secret != nil && c.ConfigMap != nil { - return &SecretOrConfigMapValidationError{"SecretOrConfigMap can not specify both Secret and ConfigMap"} - } - - return nil -} - -func (c *SecretOrConfigMap) BuildSelectorWithPrefix(prefix string) string { - if c.Secret != nil { - return fmt.Sprintf("%s%s/%s", prefix, c.Secret.Name, c.Secret.Key) - } - if c.ConfigMap != nil { - return fmt.Sprintf("%s%s/%s", prefix, c.ConfigMap.Name, c.ConfigMap.Key) - } - return "" -} - -func (c *SecretOrConfigMap) Name() string { - if c.Secret != nil { - return c.Secret.Name - } - if c.ConfigMap != nil { - return c.ConfigMap.Name - } - return "" -} - -func (c *SecretOrConfigMap) Key() string { - if c.Secret != nil { - return c.Secret.Key - } - if c.ConfigMap != nil { - return c.ConfigMap.Key - } - return "" -} - -func (c *TLSConfig) BuildAssetPath(prefix, name, key string) string { - if name == "" || key == "" { - return "" - } - return fmt.Sprintf("%s_%s_%s", prefix, name, key) -} - -// APIServerConfig defines a host and auth methods to access apiserver. -// +k8s:openapi-gen=true -type APIServerConfig struct { - // Host of apiserver. - // A valid string consisting of a hostname or IP followed by an optional port number - Host string `json:"host"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // Bearer token for accessing apiserver. - // +optional - BearerToken string `json:"bearerToken,omitempty"` - // File to read bearer token for accessing apiserver. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // TLSConfig Config to use for accessing apiserver. - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + // AttachMetadata configures metadata attaching from service discovery // +optional - Authorization *Authorization `json:"authorization,omitempty"` + AttachMetadata AttachMetadata `json:"attach_metadata,omitempty"` } // AsProxyKey builds key for proxy cache maps diff --git a/api/operator/v1beta1/vmstaticscrape_types.go b/api/operator/v1beta1/vmstaticscrape_types.go index 4c7005b2..a2c1a1cc 100644 --- a/api/operator/v1beta1/vmstaticscrape_types.go +++ b/api/operator/v1beta1/vmstaticscrape_types.go @@ -3,7 +3,6 @@ package v1beta1 import ( "fmt" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -29,79 +28,10 @@ type TargetEndpoint struct { Targets []string `json:"targets"` // Labels static labels for targets. // +optional - Labels map[string]string `json:"labels,omitempty"` - // Default port for target. - // +optional - Port string `json:"port,omitempty"` - // HTTP path to scrape for metrics. - // +optional - Path string `json:"path,omitempty"` - // HTTP scheme to use for scraping. - // +optional - // +kubebuilder:validation:Enum=http;https - Scheme string `json:"scheme,omitempty"` - // Optional HTTP URL parameters - // +optional - Params map[string][]string `json:"params,omitempty"` - // FollowRedirects controls redirects for scraping. - // +optional - FollowRedirects *bool `json:"follow_redirects,omitempty"` - // SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. - // +optional - SampleLimit uint64 `json:"sampleLimit,omitempty"` - // SeriesLimit defines per-scrape limit on number of unique time series - // a single target can expose during all the scrapes on the time window of 24h. - // +optional - SeriesLimit uint64 `json:"seriesLimit,omitempty"` - // Interval at which metrics should be scraped - // +optional - Interval string `json:"interval,omitempty"` - // ScrapeInterval is the same as Interval and has priority over it. - // one of scrape_interval or interval can be used - // +optional - ScrapeInterval string `json:"scrape_interval,omitempty"` - // Timeout after which the scrape is ended - // +optional - ScrapeTimeout string `json:"scrapeTimeout,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // TLSConfig configuration to use when scraping the endpoint - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // File to read bearer token for scraping targets. - // +optional - BearerTokenFile string `json:"bearerTokenFile,omitempty"` - // Secret to mount to read bearer token for scraping targets. The secret - // needs to be in the same namespace as the service scrape and accessible by - // the victoria-metrics operator. - // +optional - // +nullable - BearerTokenSecret *v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` - // BasicAuth allow an endpoint to authenticate over basic authentication - // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // Authorization with http header Authorization - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // MetricRelabelConfigs to apply to samples after scrapping. - // +optional - MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - // RelabelConfigs to apply to samples during service discovery. - // +optional - RelabelConfigs []*RelabelConfig `json:"relabelConfigs,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // HonorLabels chooses the metric's labels on collisions with target labels. - // +optional - HonorLabels bool `json:"honorLabels,omitempty"` - // HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. - // +optional - HonorTimestamps *bool `json:"honorTimestamps,omitempty"` - // VMScrapeParams defines VictoriaMetrics specific scrape parameters - // +optional - VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + EndpointRelabelings `json:",inline"` + EndpointAuth `json:",inline"` + EndpointScrapeParams `json:",inline"` } // VMStaticScrapeStatus defines the observed state of VMStaticScrape diff --git a/api/operator/v1beta1/zz_generated.deepcopy.go b/api/operator/v1beta1/zz_generated.deepcopy.go index 82070d49..aa6ed042 100644 --- a/api/operator/v1beta1/zz_generated.deepcopy.go +++ b/api/operator/v1beta1/zz_generated.deepcopy.go @@ -823,37 +823,30 @@ func (in *Endpoint) DeepCopyInto(out *Endpoint) { *out = new(intstr.IntOrString) **out = **in } - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in + in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) + in.AttachMetadata.DeepCopyInto(&out.AttachMetadata) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. +func (in *Endpoint) DeepCopy() *Endpoint { + if in == nil { + return nil } + out := new(Endpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointAuth) DeepCopyInto(out *EndpointAuth) { + *out = *in if in.OAuth2 != nil { in, out := &in.OAuth2, &out.OAuth2 *out = new(OAuth2) (*in).DeepCopyInto(*out) } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } if in.TLSConfig != nil { in, out := &in.TLSConfig, &out.TLSConfig *out = new(TLSConfig) @@ -864,16 +857,31 @@ func (in *Endpoint) DeepCopyInto(out *Endpoint) { *out = new(v1.SecretKeySelector) (*in).DeepCopyInto(*out) } - if in.HonorTimestamps != nil { - in, out := &in.HonorTimestamps, &out.HonorTimestamps - *out = new(bool) - **out = **in - } if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) (*in).DeepCopyInto(*out) } + if in.Authorization != nil { + in, out := &in.Authorization, &out.Authorization + *out = new(Authorization) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointAuth. +func (in *EndpointAuth) DeepCopy() *EndpointAuth { + if in == nil { + return nil + } + out := new(EndpointAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointRelabelings) DeepCopyInto(out *EndpointRelabelings) { + *out = *in if in.MetricRelabelConfigs != nil { in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs *out = make([]*RelabelConfig, len(*in)) @@ -896,25 +904,65 @@ func (in *Endpoint) DeepCopyInto(out *Endpoint) { } } } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointRelabelings. +func (in *EndpointRelabelings) DeepCopy() *EndpointRelabelings { + if in == nil { + return nil + } + out := new(EndpointRelabelings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointScrapeParams) DeepCopyInto(out *EndpointScrapeParams) { + *out = *in + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } + if in.FollowRedirects != nil { + in, out := &in.FollowRedirects, &out.FollowRedirects + *out = new(bool) + **out = **in + } if in.ProxyURL != nil { in, out := &in.ProxyURL, &out.ProxyURL *out = new(string) **out = **in } + if in.HonorTimestamps != nil { + in, out := &in.HonorTimestamps, &out.HonorTimestamps + *out = new(bool) + **out = **in + } if in.VMScrapeParams != nil { in, out := &in.VMScrapeParams, &out.VMScrapeParams *out = new(VMScrapeParams) (*in).DeepCopyInto(*out) } - in.AttachMetadata.DeepCopyInto(&out.AttachMetadata) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. -func (in *Endpoint) DeepCopy() *Endpoint { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointScrapeParams. +func (in *EndpointScrapeParams) DeepCopy() *EndpointScrapeParams { if in == nil { return nil } - out := new(Endpoint) + out := new(EndpointScrapeParams) in.DeepCopyInto(out) return out } @@ -1617,89 +1665,9 @@ func (in *PodMetricsEndpoint) DeepCopyInto(out *PodMetricsEndpoint) { *out = new(intstr.IntOrString) **out = **in } - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.HonorTimestamps != nil { - in, out := &in.HonorTimestamps, &out.HonorTimestamps - *out = new(bool) - **out = **in - } - if in.MetricRelabelConfigs != nil { - in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.RelabelConfigs != nil { - in, out := &in.RelabelConfigs, &out.RelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.BearerTokenSecret != nil { - in, out := &in.BearerTokenSecret, &out.BearerTokenSecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } - if in.VMScrapeParams != nil { - in, out := &in.VMScrapeParams, &out.VMScrapeParams - *out = new(VMScrapeParams) - (*in).DeepCopyInto(*out) - } + in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.AttachMetadata.DeepCopyInto(&out.AttachMetadata) if in.FilterRunning != nil { in, out := &in.FilterRunning, &out.FilterRunning @@ -2625,96 +2593,16 @@ func (in *TargetEndpoint) DeepCopyInto(out *TargetEndpoint) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } - if in.BearerTokenSecret != nil { - in, out := &in.BearerTokenSecret, &out.BearerTokenSecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } - if in.MetricRelabelConfigs != nil { - in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.RelabelConfigs != nil { - in, out := &in.RelabelConfigs, &out.RelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.HonorTimestamps != nil { - in, out := &in.HonorTimestamps, &out.HonorTimestamps - *out = new(bool) - **out = **in - } - if in.VMScrapeParams != nil { - in, out := &in.VMScrapeParams, &out.VMScrapeParams - *out = new(VMScrapeParams) - (*in).DeepCopyInto(*out) - } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetEndpoint. @@ -3195,6 +3083,22 @@ func (in *VMAgentRemoteWriteSpec) DeepCopy() *VMAgentRemoteWriteSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VMAgentSecurityEnforcements) DeepCopyInto(out *VMAgentSecurityEnforcements) { + *out = *in + out.ArbitraryFSAccessThroughSMs = in.ArbitraryFSAccessThroughSMs +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAgentSecurityEnforcements. +func (in *VMAgentSecurityEnforcements) DeepCopy() *VMAgentSecurityEnforcements { + if in == nil { + return nil + } + out := new(VMAgentSecurityEnforcements) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = *in @@ -3400,7 +3304,6 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(v1.SecretKeySelector) (*in).DeepCopyInto(*out) } - out.ArbitraryFSAccessThroughSMs = in.ArbitraryFSAccessThroughSMs if in.InsertPorts != nil { in, out := &in.InsertPorts, &out.InsertPorts *out = new(InsertPorts) @@ -3582,6 +3485,7 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(License) (*in).DeepCopyInto(*out) } + out.VMAgentSecurityEnforcements = in.VMAgentSecurityEnforcements } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAgentSpec. @@ -5149,90 +5053,10 @@ func (in *VMNodeScrapeSpec) DeepCopyInto(out *VMNodeScrapeSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } - if in.BearerTokenSecret != nil { - in, out := &in.BearerTokenSecret, &out.BearerTokenSecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } - if in.HonorTimestamps != nil { - in, out := &in.HonorTimestamps, &out.HonorTimestamps - *out = new(bool) - **out = **in - } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.MetricRelabelConfigs != nil { - in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.RelabelConfigs != nil { - in, out := &in.RelabelConfigs, &out.RelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } + in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.Selector.DeepCopyInto(&out.Selector) - if in.VMScrapeParams != nil { - in, out := &in.VMScrapeParams, &out.VMScrapeParams - *out = new(VMScrapeParams) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMNodeScrapeSpec. @@ -5428,62 +5252,19 @@ func (in *VMProbeSpec) DeepCopyInto(out *VMProbeSpec) { *out = *in out.VMProberSpec = in.VMProberSpec in.Targets.DeepCopyInto(&out.Targets) - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) + if in.MetricRelabelConfigs != nil { + in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs + *out = make([]*RelabelConfig, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(RelabelConfig) + (*in).DeepCopyInto(*out) } - (*out)[key] = outVal } } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.BearerTokenSecret != nil { - in, out := &in.BearerTokenSecret, &out.BearerTokenSecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) - } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.VMScrapeParams != nil { - in, out := &in.VMScrapeParams, &out.VMScrapeParams - *out = new(VMScrapeParams) - (*in).DeepCopyInto(*out) - } + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMProbeSpec. @@ -5863,94 +5644,9 @@ func (in *VMScrapeConfigSpec) DeepCopyInto(out *VMScrapeConfigSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.MetricsPath != nil { - in, out := &in.MetricsPath, &out.MetricsPath - *out = new(string) - **out = **in - } - if in.HonorTimestamps != nil { - in, out := &in.HonorTimestamps, &out.HonorTimestamps - *out = new(bool) - **out = **in - } - if in.Params != nil { - in, out := &in.Params, &out.Params - *out = make(map[string][]string, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } - if in.Scheme != nil { - in, out := &in.Scheme, &out.Scheme - *out = new(string) - **out = **in - } - if in.VMScrapeParams != nil { - in, out := &in.VMScrapeParams, &out.VMScrapeParams - *out = new(VMScrapeParams) - (*in).DeepCopyInto(*out) - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.BasicAuth != nil { - in, out := &in.BasicAuth, &out.BasicAuth - *out = new(BasicAuth) - (*in).DeepCopyInto(*out) - } - if in.Authorization != nil { - in, out := &in.Authorization, &out.Authorization - *out = new(Authorization) - (*in).DeepCopyInto(*out) - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } - if in.MetricRelabelConfigs != nil { - in, out := &in.MetricRelabelConfigs, &out.MetricRelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } - if in.RelabelConfigs != nil { - in, out := &in.RelabelConfigs, &out.RelabelConfigs - *out = make([]*RelabelConfig, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(RelabelConfig) - (*in).DeepCopyInto(*out) - } - } - } + in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) + in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMScrapeConfigSpec. @@ -5981,16 +5677,6 @@ func (in *VMScrapeConfigStatus) DeepCopy() *VMScrapeConfigStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VMScrapeParams) DeepCopyInto(out *VMScrapeParams) { *out = *in - if in.RelabelDebug != nil { - in, out := &in.RelabelDebug, &out.RelabelDebug - *out = new(bool) - **out = **in - } - if in.MetricRelabelDebug != nil { - in, out := &in.MetricRelabelDebug, &out.MetricRelabelDebug - *out = new(bool) - **out = **in - } if in.DisableCompression != nil { in, out := &in.DisableCompression, &out.DisableCompression *out = new(bool) diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml index 9e46d2f4..5064194c 100644 --- a/config/crd/overlay/crd.yaml +++ b/config/crd/overlay/crd.yaml @@ -112,9 +112,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -140,14 +139,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at - disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -386,8 +385,8 @@ spec: arbitraryFSAccessThroughSMs: description: |- ArbitraryFSAccessThroughSMs configures whether configuration - based on a service scrape can access arbitrary files on the file system - of the VMAgent container e.g. bearer token files. + based on EndpointAuth can access arbitrary files on the file system + of the VMAgent container e.g. bearer token files, basic auth, tls certs properties: deny: type: boolean @@ -953,7 +952,7 @@ spec: ignoreNamespaceSelectors: description: |- IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from - the podscrape and vmservicescrape configs, and they will only discover endpoints + scrape objects, and they will only discover endpoints within their current namespace. Defaults to false. type: boolean image: @@ -1024,7 +1023,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -1052,7 +1051,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -1257,7 +1257,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -1285,7 +1285,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -1387,7 +1388,7 @@ spec: overrideHonorLabels: description: |- OverrideHonorLabels if set to true overrides all user configured honor_labels. - If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. + If HonorLabels is set in scrape objects to true, this overrides honor_labels to false. type: boolean overrideHonorTimestamps: description: OverrideHonorTimestamps allows to globally enforce honoring @@ -1519,7 +1520,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -1547,7 +1548,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -1704,7 +1706,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -1732,7 +1734,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -1885,9 +1888,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -1913,14 +1915,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -1988,7 +1990,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -2016,7 +2018,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -2237,7 +2240,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex @@ -2265,7 +2268,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -2334,7 +2338,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex @@ -2362,7 +2366,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -2877,7 +2882,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -2905,7 +2910,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -3087,7 +3093,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -3115,7 +3121,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -3810,7 +3817,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -3838,7 +3845,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -4326,9 +4334,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -4354,14 +4361,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -4917,9 +4924,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -4945,14 +4951,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -5770,9 +5776,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -5798,14 +5803,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6258,9 +6263,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6286,14 +6290,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6564,9 +6568,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6592,14 +6595,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6953,9 +6956,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -6981,14 +6983,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -9252,9 +9254,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -9280,14 +9281,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at - disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -9612,9 +9613,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -9640,14 +9640,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at - disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -9841,9 +9841,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -9869,14 +9868,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -10134,9 +10133,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -10162,14 +10160,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at - disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -10271,9 +10269,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -10299,14 +10296,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at - disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -16183,9 +16180,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -16211,13 +16207,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -16249,7 +16246,7 @@ spec: bearerTokenSecret: description: |- Secret to mount to read bearer token for scraping targets. The secret - needs to be accessible by + needs to be in the same namespace as the scrape object and accessible by the victoria-metrics operator. nullable: true properties: @@ -16292,12 +16289,16 @@ spec: jobLabel: description: The label to use to retrieve the job name from. type: string + max_scrape_size: + description: MaxScrapeSize defines a maximum size of scraped data + for a job + type: string metricRelabelConfigs: description: MetricRelabelConfigs to apply to samples after scrapping. items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -16325,7 +16326,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -16495,7 +16497,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -16523,7 +16525,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -16643,7 +16646,7 @@ spec: type: string type: array tlsConfig: - description: TLSConfig specifies TLSConfig configuration parameters. + description: TLSConfig configuration to use when scraping the endpoint properties: ca: description: Stuct containing the CA cert to use for the targets. @@ -16805,13 +16808,14 @@ spec: parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -16823,16 +16827,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate over @@ -16840,9 +16840,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -16868,14 +16867,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -17095,10 +17094,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: @@ -17245,9 +17240,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -17273,14 +17267,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -17312,7 +17306,7 @@ spec: bearerTokenSecret: description: |- Secret to mount to read bearer token for scraping targets. The secret - needs to be in the same namespace as the service scrape and accessible by + needs to be in the same namespace as the scrape object and accessible by the victoria-metrics operator. nullable: true properties: @@ -17359,13 +17353,17 @@ spec: interval: description: Interval at which metrics should be scraped type: string + max_scrape_size: + description: MaxScrapeSize defines a maximum size of scraped + data for a job + type: string metricRelabelConfigs: description: MetricRelabelConfigs to apply to samples after scrapping. items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -17393,7 +17391,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -17554,8 +17553,7 @@ spec: description: HTTP path to scrape for metrics. type: string port: - description: Name of the pod port this endpoint refers to. Mutually - exclusive with targetPort. + description: Name of the port exposed at Pod. type: string proxyURL: description: ProxyURL eg http://proxyserver:2195 Directs scrapes @@ -17567,7 +17565,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -17595,7 +17593,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -17638,7 +17637,7 @@ spec: type: object type: array sampleLimit: - description: SampleLimit defines per-podEndpoint limit on number + description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. format: int64 type: integer @@ -17839,13 +17838,14 @@ spec: scrape parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -17857,16 +17857,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate @@ -17874,9 +17870,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -17902,14 +17897,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -18131,10 +18126,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: @@ -18304,9 +18295,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -18332,13 +18322,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -18370,7 +18361,7 @@ spec: bearerTokenSecret: description: |- Secret to mount to read bearer token for scraping targets. The secret - needs to be in the same namespace as the service scrape and accessible by + needs to be in the same namespace as the scrape object and accessible by the victoria-metrics operator. nullable: true properties: @@ -18399,14 +18390,100 @@ spec: follow_redirects: description: FollowRedirects controls redirects for scraping. type: boolean + honorLabels: + description: HonorLabels chooses the metric's labels on collisions + with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether vmagent respects the + timestamps present in scraped data. + type: boolean interval: - description: |- - Interval at which targets are probed using the configured prober. - If not specified global scrape interval is used. + description: Interval at which metrics should be scraped type: string jobName: description: The job name assigned to scraped metrics by default. type: string + max_scrape_size: + description: MaxScrapeSize defines a maximum size of scraped data + for a job + type: string + metricRelabelConfigs: + description: MetricRelabelConfigs to apply to samples after scrapping. + items: + description: |- + RelabelConfig allows dynamic rewriting of the label set + More info: https://docs.victoriametrics.com/#relabeling + properties: + action: + description: Action to perform based on regex matching. Default + is 'replace' + type: string + if: + description: 'If represents metricsQL match expression (or list + of expressions): ''{__name__=~"foo_.*"}''' + x-kubernetes-preserve-unknown-fields: true + labels: + additionalProperties: + type: string + description: 'Labels is used together with Match for `action: + graphite`' + type: object + match: + description: 'Match is used together with Labels for `action: + graphite`' + type: string + modulus: + description: Modulus to take of the hash of the source label + values. + format: int64 + type: integer + regex: + description: |- + Regular expression against which the extracted value is matched. Default is '(.*)' + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements + x-kubernetes-preserve-unknown-fields: true + replacement: + description: |- + Replacement value against which a regex replace is performed if the + regular expression matches. Regex capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source label + values. default is ';'. + type: string + source_labels: + description: |- + UnderScoreSourceLabels - additional form of source labels source_labels + for compatibility with original relabel config. + if set both sourceLabels and source_labels, sourceLabels has priority. + for details https://github.com/VictoriaMetrics/operator/issues/131 + items: + type: string + type: array + sourceLabels: + description: |- + The source labels select values from existing labels. Their content is concatenated + using the configured separator and matched against the configured regular expression + for the replace, keep, and drop actions. + items: + type: string + type: array + target_label: + description: |- + UnderScoreTargetLabel - additional form of target label - target_label + for compatibility with original relabel config. + if set both targetLabel and target_label, targetLabel has priority. + for details https://github.com/VictoriaMetrics/operator/issues/131 + type: string + targetLabel: + description: |- + Label to which the resulting value is written in a replace action. + It is mandatory for replace actions. Regex capture groups are available. + type: string + type: object + type: array module: description: |- The module to use for probing specifying how to probe the target. @@ -18526,6 +18603,9 @@ spec: type: array description: Optional HTTP URL parameters type: object + path: + description: HTTP path to scrape for metrics. + type: string proxyURL: description: ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. @@ -18535,13 +18615,19 @@ spec: samples that will be accepted. format: int64 type: integer + scheme: + description: HTTP scheme to use for scraping. + enum: + - http + - https + type: string scrape_interval: description: |- ScrapeInterval is the same as Interval and has priority over it. one of scrape_interval or interval can be used type: string scrapeTimeout: - description: Timeout for scraping metrics from the blackbox exporter. + description: Timeout after which the scrape is ended type: string seriesLimit: description: |- @@ -18577,7 +18663,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -18605,7 +18691,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -18710,7 +18797,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -18738,7 +18825,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -18953,13 +19041,14 @@ spec: parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -18971,16 +19060,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate over @@ -18988,9 +19073,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -19016,14 +19100,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -19243,10 +19327,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: @@ -19548,7 +19628,7 @@ spec: description: VMScrapeConfigSpec defines the desired state of VMScrapeConfig properties: authorization: - description: Authorization header to use on every scrape request. + description: Authorization with http header Authorization properties: credentials: description: Reference to the secret with value for authorization @@ -19655,13 +19735,13 @@ spec: type: object type: array basicAuth: - description: BasicAuth information to use on every scrape request. + description: BasicAuth allow an endpoint to authenticate over basic + authentication properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -19687,13 +19767,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must be @@ -19719,6 +19800,38 @@ spec: type: object x-kubernetes-map-type: atomic type: object + bearerTokenFile: + description: File to read bearer token for scraping targets. + type: string + bearerTokenSecret: + description: |- + Secret to mount to read bearer token for scraping targets. The secret + needs to be in the same namespace as the scrape object and accessible by + the victoria-metrics operator. + nullable: true + properties: + key: + description: The key of the secret to select from. Must be a + valid secret key. + type: string + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + TODO: Add other useful fields. apiVersion, kind, uid? + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Drop `kubebuilder:default` when controller-gen doesn't need it https://github.com/kubernetes-sigs/kubebuilder/issues/3896. + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic consulSDConfigs: description: ConsulSDConfigs defines a list of Consul service discovery configurations. @@ -19773,9 +19886,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -19801,14 +19913,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -19975,9 +20087,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -20003,14 +20114,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -20630,9 +20741,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -20658,14 +20768,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21252,8 +21362,8 @@ spec: with target labels. type: boolean honorTimestamps: - description: HonorTimestamps controls whether to respect the timestamps - present in scraped data. + description: HonorTimestamps controls whether vmagent respects the + timestamps present in scraped data. type: boolean httpSDConfigs: description: HTTPSDConfigs defines a list of HTTP service discovery @@ -21304,9 +21414,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21332,14 +21441,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21376,9 +21485,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21404,14 +21512,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21808,6 +21916,9 @@ spec: - url type: object type: array + interval: + description: Interval at which metrics should be scraped + type: string kubernetesSDConfigs: description: KubernetesSDConfigs defines a list of Kubernetes service discovery configurations. @@ -21875,9 +21986,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -21903,14 +22013,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -22075,9 +22185,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -22103,14 +22212,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -22533,7 +22642,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -22561,7 +22670,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -22603,10 +22713,6 @@ spec: type: string type: object type: array - metricsPath: - description: MetricsPath HTTP path to scrape for metrics. If empty, - use the default value (e.g. /metrics). - type: string oauth2: description: OAuth2 defines auth configuration properties: @@ -23027,7 +23133,9 @@ spec: type: array description: Optional HTTP URL parameters type: object - x-kubernetes-map-type: atomic + path: + description: HTTP path to scrape for metrics. + type: string proxyURL: description: ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. @@ -23037,7 +23145,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. Default @@ -23065,7 +23173,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -23113,19 +23222,18 @@ spec: format: int64 type: integer scheme: - description: |- - Configures the protocol scheme used for requests. - If empty, use HTTP by default. + description: HTTP scheme to use for scraping. enum: - - HTTP - - HTTPS + - http + - https type: string - scrapeInterval: - description: ScrapeInterval is the interval between consecutive scrapes. + scrape_interval: + description: |- + ScrapeInterval is the same as Interval and has priority over it. + one of scrape_interval or interval can be used type: string scrapeTimeout: - description: ScrapeTimeout is the number of seconds to wait until - a scrape request times out. + description: Timeout after which the scrape is ended type: string seriesLimit: description: |- @@ -23156,7 +23264,7 @@ spec: type: object type: array tlsConfig: - description: TLS configuration to use on every scrape request + description: TLSConfig configuration to use when scraping the endpoint properties: ca: description: Stuct containing the CA cert to use for the targets. @@ -23318,13 +23426,14 @@ spec: parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -23336,16 +23445,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate over @@ -23353,9 +23458,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -23381,14 +23485,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -23608,10 +23712,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: @@ -23752,9 +23852,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -23780,14 +23879,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -23819,7 +23918,7 @@ spec: bearerTokenSecret: description: |- Secret to mount to read bearer token for scraping targets. The secret - needs to be in the same namespace as the service scrape and accessible by + needs to be in the same namespace as the scrape object and accessible by the victoria-metrics operator. nullable: true properties: @@ -23860,13 +23959,17 @@ spec: interval: description: Interval at which metrics should be scraped type: string + max_scrape_size: + description: MaxScrapeSize defines a maximum size of scraped + data for a job + type: string metricRelabelConfigs: description: MetricRelabelConfigs to apply to samples after scrapping. items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -23894,7 +23997,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -24055,8 +24159,7 @@ spec: description: HTTP path to scrape for metrics. type: string port: - description: Name of the service port this endpoint refers to. - Mutually exclusive with targetPort. + description: Name of the port exposed at Service. type: string proxyURL: description: ProxyURL eg http://proxyserver:2195 Directs scrapes @@ -24068,7 +24171,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -24096,7 +24199,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -24139,7 +24243,7 @@ spec: type: object type: array sampleLimit: - description: SampleLimit defines per-endpoint limit on number + description: SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. format: int64 type: integer @@ -24167,8 +24271,9 @@ spec: anyOf: - type: integer - type: string - description: Name or number of the pod port this endpoint refers - to. Mutually exclusive with port. + description: |- + TargetPort + Name or number of the pod port this endpoint refers to. Mutually exclusive with port. x-kubernetes-int-or-string: true tlsConfig: description: TLSConfig configuration to use when scraping the @@ -24339,13 +24444,14 @@ spec: scrape parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -24357,16 +24463,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate @@ -24374,9 +24476,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -24402,14 +24503,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -24631,10 +24732,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: @@ -25598,7 +25695,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -25626,7 +25723,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -25694,7 +25792,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -25722,7 +25820,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -26494,9 +26593,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -26522,14 +26620,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password file - at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select from. Must @@ -26561,7 +26659,7 @@ spec: bearerTokenSecret: description: |- Secret to mount to read bearer token for scraping targets. The secret - needs to be in the same namespace as the service scrape and accessible by + needs to be in the same namespace as the scrape object and accessible by the victoria-metrics operator. nullable: true properties: @@ -26607,13 +26705,17 @@ spec: type: string description: Labels static labels for targets. type: object + max_scrape_size: + description: MaxScrapeSize defines a maximum size of scraped + data for a job + type: string metricRelabelConfigs: description: MetricRelabelConfigs to apply to samples after scrapping. items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -26641,7 +26743,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -26801,9 +26904,6 @@ spec: path: description: HTTP path to scrape for metrics. type: string - port: - description: Default port for target. - type: string proxyURL: description: ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. @@ -26814,7 +26914,7 @@ spec: items: description: |- RelabelConfig allows dynamic rewriting of the label set - More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) + More info: https://docs.victoriametrics.com/#relabeling properties: action: description: Action to perform based on regex matching. @@ -26842,7 +26942,8 @@ spec: regex: description: |- Regular expression against which the extracted value is matched. Default is '(.*)' - victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with | + victoriaMetrics supports multiline regex joined with | + https://docs.victoriametrics.com/vmagent/#relabeling-enhancements x-kubernetes-preserve-unknown-fields: true replacement: description: |- @@ -27084,13 +27185,14 @@ spec: scrape parameters properties: disable_compression: + description: DisableCompression type: boolean disable_keep_alive: description: |- disable_keepalive allows disabling HTTP keep-alive when scraping targets. By default, HTTP keep-alive is enabled, so TCP connections to scrape targets could be re-used. - See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) + See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements type: boolean headers: description: |- @@ -27102,16 +27204,12 @@ spec: items: type: string type: array - metric_relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean no_stale_markers: type: boolean proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) + See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy properties: basic_auth: description: BasicAuth allow an endpoint to authenticate @@ -27119,9 +27217,8 @@ spec: properties: password: description: |- - The secret in the service scrape namespace that contains the password - for authentication. - It must be at them same namespace as CRD + Password defines reference for secret with password value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -27147,14 +27244,14 @@ spec: type: object x-kubernetes-map-type: atomic password_file: - description: PasswordFile defines path to password - file at disk + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string username: description: |- - The secret in the service scrape namespace that contains the username - for authentication. - It must be at them same namespace as CRD + Username defines reference for secret with username value + The secret needs to be in the same namespace as scrape object properties: key: description: The key of the secret to select @@ -27376,10 +27473,6 @@ spec: type: string type: object type: object - relabel_debug: - description: deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), - will be removed in next release - type: boolean scrape_align_interval: type: string scrape_offset: diff --git a/docs/api.md b/docs/api.md index 0a76d009..c2534ee0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -105,6 +105,7 @@ attack, users can instead use the BearerTokenSecret field. _Appears in:_ +- [VMAgentSecurityEnforcements](#vmagentsecurityenforcements) - [VMAgentSpec](#vmagentspec) | Field | Description | Scheme | Required | @@ -145,6 +146,7 @@ _Appears in:_ - [ConsulSDConfig](#consulsdconfig) - [DigitalOceanSDConfig](#digitaloceansdconfig) - [Endpoint](#endpoint) +- [EndpointAuth](#endpointauth) - [HTTPSDConfig](#httpsdconfig) - [KubernetesSDConfig](#kubernetessdconfig) - [PodMetricsEndpoint](#podmetricsendpoint) @@ -196,6 +198,7 @@ _Appears in:_ - [APIServerConfig](#apiserverconfig) - [ConsulSDConfig](#consulsdconfig) - [Endpoint](#endpoint) +- [EndpointAuth](#endpointauth) - [HTTPAuth](#httpauth) - [HTTPConfig](#httpconfig) - [HTTPSDConfig](#httpsdconfig) @@ -214,9 +217,9 @@ _Appears in:_ | Field | Description | Scheme | Required | | --- | --- | --- | --- | -| `password` | The secret in the service scrape namespace that contains the password
for authentication.
It must be at them same namespace as CRD | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | -| `password_file` | PasswordFile defines path to password file at disk | _string_ | false | -| `username` | The secret in the service scrape namespace that contains the username
for authentication.
It must be at them same namespace as CRD | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `password` | Password defines reference for secret with password value
The secret needs to be in the same namespace as scrape object | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `password_file` | PasswordFile defines path to password file at disk
must be pre-mounted | _string_ | false | +| `username` | Username defines reference for secret with username value
The secret needs to be in the same namespace as scrape object | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | #### BearerAuth @@ -636,28 +639,110 @@ _Appears in:_ | `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | | `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | -| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the service scrape and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | | `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | | `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | | `interval` | Interval at which metrics should be scraped | _string_ | false | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | | `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | | `path` | HTTP path to scrape for metrics. | _string_ | false | -| `port` | Name of the service port this endpoint refers to. Mutually exclusive with targetPort. | _string_ | false | +| `port` | Name of the port exposed at Service. | _string_ | false | | `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | | `relabelConfigs` | RelabelConfigs to apply to samples during service discovery. | _[RelabelConfig](#relabelconfig) array_ | false | -| `sampleLimit` | SampleLimit defines per-endpoint limit on number of scraped samples that will be accepted. | _integer_ | false | +| `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | | `scheme` | HTTP scheme to use for scraping. | _string_ | false | | `scrapeTimeout` | Timeout after which the scrape is ended | _string_ | false | | `scrape_interval` | ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | _string_ | false | | `seriesLimit` | SeriesLimit defines per-scrape limit on number of unique time series
a single target can expose during all the scrapes on the time window of 24h. | _integer_ | false | -| `targetPort` | Name or number of the pod port this endpoint refers to. Mutually exclusive with port. | _[IntOrString](#intorstring)_ | false | +| `targetPort` | TargetPort
Name or number of the pod port this endpoint refers to. Mutually exclusive with port. | _[IntOrString](#intorstring)_ | false | | `tlsConfig` | TLSConfig configuration to use when scraping the endpoint | _[TLSConfig](#tlsconfig)_ | false | | `vm_scrape_params` | VMScrapeParams defines VictoriaMetrics specific scrape parameters | _[VMScrapeParams](#vmscrapeparams)_ | false | +#### EndpointAuth + + + +EndpointAuth defines target endpoint authorization options for scrapping + + + +_Appears in:_ +- [Endpoint](#endpoint) +- [PodMetricsEndpoint](#podmetricsendpoint) +- [TargetEndpoint](#targetendpoint) +- [VMNodeScrapeSpec](#vmnodescrapespec) +- [VMProbeSpec](#vmprobespec) +- [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | Scheme | Required | +| --- | --- | --- | --- | +| `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | +| `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | +| `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | +| `tlsConfig` | TLSConfig configuration to use when scraping the endpoint | _[TLSConfig](#tlsconfig)_ | false | + + +#### EndpointRelabelings + + + +EndpointRelabelings defines service discovery and metrics relabeling configuration for endpoints + + + +_Appears in:_ +- [Endpoint](#endpoint) +- [PodMetricsEndpoint](#podmetricsendpoint) +- [TargetEndpoint](#targetendpoint) +- [VMNodeScrapeSpec](#vmnodescrapespec) +- [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | Scheme | Required | +| --- | --- | --- | --- | +| `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | +| `relabelConfigs` | RelabelConfigs to apply to samples during service discovery. | _[RelabelConfig](#relabelconfig) array_ | false | + + +#### EndpointScrapeParams + + + +ScrapeTargetParams defines common configuration params for all scrape endpoint targets + + + +_Appears in:_ +- [Endpoint](#endpoint) +- [PodMetricsEndpoint](#podmetricsendpoint) +- [TargetEndpoint](#targetendpoint) +- [VMNodeScrapeSpec](#vmnodescrapespec) +- [VMProbeSpec](#vmprobespec) +- [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | Scheme | Required | +| --- | --- | --- | --- | +| `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | +| `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | +| `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | +| `interval` | Interval at which metrics should be scraped | _string_ | false | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | +| `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | +| `path` | HTTP path to scrape for metrics. | _string_ | false | +| `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | +| `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | +| `scheme` | HTTP scheme to use for scraping. | _string_ | false | +| `scrapeTimeout` | Timeout after which the scrape is ended | _string_ | false | +| `scrape_interval` | ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | _string_ | false | +| `seriesLimit` | SeriesLimit defines per-scrape limit on number of unique time series
a single target can expose during all the scrapes on the time window of 24h. | _integer_ | false | +| `vm_scrape_params` | VMScrapeParams defines VictoriaMetrics specific scrape parameters | _[VMScrapeParams](#vmscrapeparams)_ | false | + + #### FileSDConfig @@ -1046,6 +1131,7 @@ _Appears in:_ - [ConsulSDConfig](#consulsdconfig) - [DigitalOceanSDConfig](#digitaloceansdconfig) - [Endpoint](#endpoint) +- [EndpointAuth](#endpointauth) - [HTTPAuth](#httpauth) - [KubernetesSDConfig](#kubernetessdconfig) - [PodMetricsEndpoint](#podmetricsendpoint) @@ -1201,20 +1287,21 @@ _Appears in:_ | `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | | `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | -| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the service scrape and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `filterRunning` | FilterRunning applies filter with pod status == running
it prevents from scrapping metrics at failed or succeed state pods.
enabled by default | _boolean_ | false | | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | | `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | | `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | | `interval` | Interval at which metrics should be scraped | _string_ | false | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | | `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | | `path` | HTTP path to scrape for metrics. | _string_ | false | -| `port` | Name of the pod port this endpoint refers to. Mutually exclusive with targetPort. | _string_ | false | +| `port` | Name of the port exposed at Pod. | _string_ | false | | `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | | `relabelConfigs` | RelabelConfigs to apply to samples during service discovery. | _[RelabelConfig](#relabelconfig) array_ | false | -| `sampleLimit` | SampleLimit defines per-podEndpoint limit on number of scraped samples that will be accepted. | _integer_ | false | +| `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | | `scheme` | HTTP scheme to use for scraping. | _string_ | false | | `scrapeTimeout` | Timeout after which the scrape is ended | _string_ | false | | `scrape_interval` | ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | _string_ | false | @@ -1344,12 +1431,13 @@ _Appears in:_ RelabelConfig allows dynamic rewriting of the label set -More info [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/#relabeling) +More info: https://docs.victoriametrics.com/#relabeling _Appears in:_ - [Endpoint](#endpoint) +- [EndpointRelabelings](#endpointrelabelings) - [PodMetricsEndpoint](#podmetricsendpoint) - [ProbeTargetIngress](#probetargetingress) - [StreamAggrRule](#streamaggrrule) @@ -1357,6 +1445,7 @@ _Appears in:_ - [VMAgentRemoteWriteSpec](#vmagentremotewritespec) - [VMAgentSpec](#vmagentspec) - [VMNodeScrapeSpec](#vmnodescrapespec) +- [VMProbeSpec](#vmprobespec) - [VMProbeTargetStaticConfig](#vmprobetargetstaticconfig) - [VMScrapeConfigSpec](#vmscrapeconfigspec) @@ -1367,7 +1456,7 @@ _Appears in:_ | `labels` | Labels is used together with Match for `action: graphite` | _object (keys:string, values:string)_ | false | | `match` | Match is used together with Labels for `action: graphite` | _string_ | false | | `modulus` | Modulus to take of the hash of the source label values. | _integer_ | false | -| `regex` | Regular expression against which the extracted value is matched. Default is '(.*)'
victoriaMetrics [supports](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#relabeling-enhancements) multiline regex joined with \| | _[StringOrArray](#stringorarray)_ | false | +| `regex` | Regular expression against which the extracted value is matched. Default is '(.*)'
victoriaMetrics supports multiline regex joined with \|
https://docs.victoriametrics.com/vmagent/#relabeling-enhancements | _[StringOrArray](#stringorarray)_ | false | | `replacement` | Replacement value against which a regex replace is performed if the
regular expression matches. Regex capture groups are available. Default is '$1' | _string_ | false | | `separator` | Separator placed between concatenated source label values. default is ';'. | _string_ | false | | `sourceLabels` | The source labels select values from existing labels. Their content is concatenated
using the configured separator and matched against the configured regular expression
for the replace, keep, and drop actions. | _string array_ | false | @@ -1763,6 +1852,7 @@ _Appears in:_ - [DigitalOceanSDConfig](#digitaloceansdconfig) - [EmailConfig](#emailconfig) - [Endpoint](#endpoint) +- [EndpointAuth](#endpointauth) - [HTTPAuth](#httpauth) - [HTTPConfig](#httpconfig) - [HTTPSDConfig](#httpsdconfig) @@ -1813,17 +1903,17 @@ _Appears in:_ | `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | | `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | -| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the service scrape and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | | `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | | `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | | `interval` | Interval at which metrics should be scraped | _string_ | false | | `labels` | Labels static labels for targets. | _object (keys:string, values:string)_ | false | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | | `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | | `path` | HTTP path to scrape for metrics. | _string_ | false | -| `port` | Default port for target. | _string_ | false | | `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | | `relabelConfigs` | RelabelConfigs to apply to samples during service discovery. | _[RelabelConfig](#relabelconfig) array_ | false | | `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | @@ -2093,6 +2183,26 @@ _Appears in:_ | `urlRelabelConfig` | ConfigMap with relabeling config which is applied to metrics before sending them to the corresponding -remoteWrite.url | _[ConfigMapKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#configmapkeyselector-v1-core)_ | false | +#### VMAgentSecurityEnforcements + + + +VMAgentSecurityEnforcements defines security configuration for endpoint scrapping + + + +_Appears in:_ +- [VMAgentSpec](#vmagentspec) + +| Field | Description | Scheme | Required | +| --- | --- | --- | --- | +| `arbitraryFSAccessThroughSMs` | ArbitraryFSAccessThroughSMs configures whether configuration
based on EndpointAuth can access arbitrary files on the file system
of the VMAgent container e.g. bearer token files, basic auth, tls certs | _[ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig)_ | false | +| `enforcedNamespaceLabel` | EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert
and metric that is user created. The label value will always be the namespace of the object that is
being created. | _string_ | false | +| `ignoreNamespaceSelectors` | IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from
scrape objects, and they will only discover endpoints
within their current namespace. Defaults to false. | _boolean_ | false | +| `overrideHonorLabels` | OverrideHonorLabels if set to true overrides all user configured honor_labels.
If HonorLabels is set in scrape objects to true, this overrides honor_labels to false. | _boolean_ | false | +| `overrideHonorTimestamps` | OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. | _boolean_ | false | + + #### VMAgentSpec @@ -2109,7 +2219,7 @@ _Appears in:_ | `aPIServerConfig` | APIServerConfig allows specifying a host and auth methods to access apiserver.
If left empty, VMAgent is assumed to run inside of the cluster
and will discover API servers automatically and use the pod's CA certificate
and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. | _[APIServerConfig](#apiserverconfig)_ | false | | `additionalScrapeConfigs` | AdditionalScrapeConfigs As scrape configs are appended, the user is responsible to make sure it
is valid. Note that using this feature may expose the possibility to
break upgrades of VMAgent. It is advised to review VMAgent release
notes to ensure that no incompatible scrape configs are going to break
VMAgent after the upgrade. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `affinity` | Affinity If specified, the pod's scheduling constraints. | _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#affinity-v1-core)_ | false | -| `arbitraryFSAccessThroughSMs` | ArbitraryFSAccessThroughSMs configures whether configuration
based on a service scrape can access arbitrary files on the file system
of the VMAgent container e.g. bearer token files. | _[ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig)_ | false | +| `arbitraryFSAccessThroughSMs` | ArbitraryFSAccessThroughSMs configures whether configuration
based on EndpointAuth can access arbitrary files on the file system
of the VMAgent container e.g. bearer token files, basic auth, tls certs | _[ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig)_ | false | | `claimTemplates` | ClaimTemplates allows adding additional VolumeClaimTemplates for VMAgent in StatefulMode | _[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#persistentvolumeclaim-v1-core) array_ | true | | `configMaps` | ConfigMaps is a list of ConfigMaps in the same namespace as the vmagent
object, which shall be mounted into the vmagent Pods.
will be mounted at path /etc/vm/configs | _string array_ | false | | `configReloaderExtraArgs` | ConfigReloaderExtraArgs that will be passed to VMAuths config-reloader container
for example resyncInterval: "30s" | _object (keys:string, values:string)_ | false | @@ -2122,7 +2232,7 @@ _Appears in:_ | `extraEnvs` | ExtraEnvs that will be added to VMAgent pod | _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#envvar-v1-core) array_ | false | | `hostNetwork` | HostNetwork controls whether the pod may use the node network namespace | _boolean_ | false | | `host_aliases` | HostAliases provides mapping between ip and hostnames,
that would be propagated to pod,
cannot be used with HostNetwork. | _[HostAlias](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#hostalias-v1-core) array_ | false | -| `ignoreNamespaceSelectors` | IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from
the podscrape and vmservicescrape configs, and they will only discover endpoints
within their current namespace. Defaults to false. | _boolean_ | false | +| `ignoreNamespaceSelectors` | IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from
scrape objects, and they will only discover endpoints
within their current namespace. Defaults to false. | _boolean_ | false | | `image` | Image - docker image settings for VMAgent
if no specified operator uses default config version | _[Image](#image)_ | false | | `imagePullSecrets` | ImagePullSecrets An optional list of references to secrets in the same namespace
to use for pulling images from registries
see https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod | _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#localobjectreference-v1-core) array_ | false | | `ingestOnlyMode` | IngestOnlyMode switches vmagent into unmanaged mode
it disables any config generation for scraping
Currently it prevents vmagent from managing tls and auth options for remote write | _boolean_ | false | @@ -2140,7 +2250,7 @@ _Appears in:_ | `nodeScrapeRelabelTemplate` | NodeScrapeRelabelTemplate defines relabel config, that will be added to each VMNodeScrape.
it's useful for adding specific labels to all targets | _[RelabelConfig](#relabelconfig) array_ | false | | `nodeScrapeSelector` | NodeScrapeSelector defines VMNodeScrape to be selected for scraping.
Works in combination with NamespaceSelector.
NamespaceSelector nil - only objects at VMAgent namespace.
Selector nil - only objects at NamespaceSelector namespaces.
If both nil - behaviour controlled by selectAllByDefault | _[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#labelselector-v1-meta)_ | false | | `nodeSelector` | NodeSelector Define which Nodes the Pods are scheduled on. | _object (keys:string, values:string)_ | false | -| `overrideHonorLabels` | OverrideHonorLabels if set to true overrides all user configured honor_labels.
If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. | _boolean_ | false | +| `overrideHonorLabels` | OverrideHonorLabels if set to true overrides all user configured honor_labels.
If HonorLabels is set in scrape objects to true, this overrides honor_labels to false. | _boolean_ | false | | `overrideHonorTimestamps` | OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. | _boolean_ | false | | `paused` | Paused If set to true all actions on the underlying managed objects are not
going to be performed, except for delete actions. | _boolean_ | false | | `podDisruptionBudget` | PodDisruptionBudget created by operator | _[EmbeddedPodDisruptionBudgetSpec](#embeddedpoddisruptionbudgetspec)_ | false | @@ -2766,12 +2876,13 @@ _Appears in:_ | `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | | `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | -| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | | `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | | `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | | `interval` | Interval at which metrics should be scraped | _string_ | false | | `jobLabel` | The label to use to retrieve the job name from. | _string_ | false | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | | `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | @@ -2786,7 +2897,7 @@ _Appears in:_ | `selector` | Selector to select kubernetes Nodes. | _[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#labelselector-v1-meta)_ | false | | `seriesLimit` | SeriesLimit defines per-scrape limit on number of unique time series
a single target can expose during all the scrapes on the time window of 24h. | _integer_ | false | | `targetLabels` | TargetLabels transfers labels on the Kubernetes Node onto the target. | _string array_ | false | -| `tlsConfig` | | _[TLSConfig](#tlsconfig)_ | false | +| `tlsConfig` | TLSConfig configuration to use when scraping the endpoint | _[TLSConfig](#tlsconfig)_ | false | | `vm_scrape_params` | VMScrapeParams defines VictoriaMetrics specific scrape parameters | _[VMScrapeParams](#vmscrapeparams)_ | false | @@ -2873,16 +2984,22 @@ _Appears in:_ | `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | | `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | -| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the service scrape and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | -| `interval` | Interval at which targets are probed using the configured prober.
If not specified global scrape interval is used. | _string_ | true | +| `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | +| `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | +| `interval` | Interval at which metrics should be scraped | _string_ | false | | `jobName` | The job name assigned to scraped metrics by default. | _string_ | true | +| `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | +| `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | | `module` | The module to use for probing specifying how to probe the target.
Example module configuring in the blackbox exporter:
https://github.com/prometheus/blackbox_exporter/blob/master/example.yml | _string_ | true | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | +| `path` | HTTP path to scrape for metrics. | _string_ | false | | `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | | `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | -| `scrapeTimeout` | Timeout for scraping metrics from the blackbox exporter. | _string_ | true | +| `scheme` | HTTP scheme to use for scraping. | _string_ | false | +| `scrapeTimeout` | Timeout after which the scrape is ended | _string_ | false | | `scrape_interval` | ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | _string_ | false | | `seriesLimit` | SeriesLimit defines per-scrape limit on number of unique time series
a single target can expose during all the scrapes on the time window of 24h. | _integer_ | false | | `targets` | Targets defines a set of static and/or dynamically discovered targets to be probed using the prober. | _[VMProbeTargets](#vmprobetargets)_ | true | @@ -3045,9 +3162,11 @@ _Appears in:_ | Field | Description | Scheme | Required | | --- | --- | --- | --- | -| `authorization` | Authorization header to use on every scrape request. | _[Authorization](#authorization)_ | false | +| `authorization` | Authorization with http header Authorization | _[Authorization](#authorization)_ | false | | `azureSDConfigs` | AzureSDConfigs defines a list of Azure service discovery configurations. | _[AzureSDConfig](#azuresdconfig) array_ | false | -| `basicAuth` | BasicAuth information to use on every scrape request. | _[BasicAuth](#basicauth)_ | false | +| `basicAuth` | BasicAuth allow an endpoint to authenticate over basic authentication | _[BasicAuth](#basicauth)_ | false | +| `bearerTokenFile` | File to read bearer token for scraping targets. | _string_ | false | +| `bearerTokenSecret` | Secret to mount to read bearer token for scraping targets. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | false | | `consulSDConfigs` | ConsulSDConfigs defines a list of Consul service discovery configurations. | _[ConsulSDConfig](#consulsdconfig) array_ | false | | `digitalOceanSDConfigs` | DigitalOceanSDConfigs defines a list of DigitalOcean service discovery configurations. | _[DigitalOceanSDConfig](#digitaloceansdconfig) array_ | false | | `dnsSDConfigs` | DNSSDConfigs defines a list of DNS service discovery configurations. | _[DNSSDConfig](#dnssdconfig) array_ | false | @@ -3056,24 +3175,25 @@ _Appears in:_ | `follow_redirects` | FollowRedirects controls redirects for scraping. | _boolean_ | false | | `gceSDConfigs` | GCESDConfigs defines a list of GCE service discovery configurations. | _[GCESDConfig](#gcesdconfig) array_ | false | | `honorLabels` | HonorLabels chooses the metric's labels on collisions with target labels. | _boolean_ | false | -| `honorTimestamps` | HonorTimestamps controls whether to respect the timestamps present in scraped data. | _boolean_ | false | +| `honorTimestamps` | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | _boolean_ | false | | `httpSDConfigs` | HTTPSDConfigs defines a list of HTTP service discovery configurations. | _[HTTPSDConfig](#httpsdconfig) array_ | false | +| `interval` | Interval at which metrics should be scraped | _string_ | false | | `kubernetesSDConfigs` | KubernetesSDConfigs defines a list of Kubernetes service discovery configurations. | _[KubernetesSDConfig](#kubernetessdconfig) array_ | false | | `max_scrape_size` | MaxScrapeSize defines a maximum size of scraped data for a job | _string_ | false | | `metricRelabelConfigs` | MetricRelabelConfigs to apply to samples after scrapping. | _[RelabelConfig](#relabelconfig) array_ | false | -| `metricsPath` | MetricsPath HTTP path to scrape for metrics. If empty, use the default value (e.g. /metrics). | _string_ | false | | `oauth2` | OAuth2 defines auth configuration | _[OAuth2](#oauth2)_ | false | | `openstackSDConfigs` | OpenStackSDConfigs defines a list of OpenStack service discovery configurations. | _[OpenStackSDConfig](#openstacksdconfig) array_ | false | | `params` | Optional HTTP URL parameters | _object (keys:string, values:string array)_ | false | +| `path` | HTTP path to scrape for metrics. | _string_ | false | | `proxyURL` | ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | _string_ | false | | `relabelConfigs` | RelabelConfigs to apply to samples during service discovery. | _[RelabelConfig](#relabelconfig) array_ | false | | `sampleLimit` | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | _integer_ | false | -| `scheme` | Configures the protocol scheme used for requests.
If empty, use HTTP by default. | _string_ | false | -| `scrapeInterval` | ScrapeInterval is the interval between consecutive scrapes. | _string_ | false | -| `scrapeTimeout` | ScrapeTimeout is the number of seconds to wait until a scrape request times out. | _string_ | false | +| `scheme` | HTTP scheme to use for scraping. | _string_ | false | +| `scrapeTimeout` | Timeout after which the scrape is ended | _string_ | false | +| `scrape_interval` | ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | _string_ | false | | `seriesLimit` | SeriesLimit defines per-scrape limit on number of unique time series
a single target can expose during all the scrapes on the time window of 24h. | _integer_ | false | | `staticConfigs` | StaticConfigs defines a list of static targets with a common label set. | _[StaticConfig](#staticconfig) array_ | false | -| `tlsConfig` | TLS configuration to use on every scrape request | _[TLSConfig](#tlsconfig)_ | false | +| `tlsConfig` | TLSConfig configuration to use when scraping the endpoint | _[TLSConfig](#tlsconfig)_ | false | | `vm_scrape_params` | VMScrapeParams defines VictoriaMetrics specific scrape parameters | _[VMScrapeParams](#vmscrapeparams)_ | false | @@ -3090,6 +3210,7 @@ VMAgent and VMSingle _Appears in:_ - [Endpoint](#endpoint) +- [EndpointScrapeParams](#endpointscrapeparams) - [PodMetricsEndpoint](#podmetricsendpoint) - [TargetEndpoint](#targetendpoint) - [VMNodeScrapeSpec](#vmnodescrapespec) @@ -3098,13 +3219,11 @@ _Appears in:_ | Field | Description | Scheme | Required | | --- | --- | --- | --- | -| `disable_compression` | | _boolean_ | false | -| `disable_keep_alive` | disable_keepalive allows disabling HTTP keep-alive when scraping targets.
By default, HTTP keep-alive is enabled, so TCP connections to scrape targets
could be re-used.
See [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scrape_config-enhancements) | _boolean_ | false | +| `disable_compression` | DisableCompression | _boolean_ | false | +| `disable_keep_alive` | disable_keepalive allows disabling HTTP keep-alive when scraping targets.
By default, HTTP keep-alive is enabled, so TCP connections to scrape targets
could be re-used.
See https://docs.victoriametrics.com/vmagent.html#scrape_config-enhancements | _boolean_ | false | | `headers` | Headers allows sending custom headers to scrape targets
must be in of semicolon separated header with it's value
eg:
headerName: headerValue
vmagent supports since 1.79.0 version | _string array_ | false | -| `metric_relabel_debug` | deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), will be removed in next release | _boolean_ | false | | `no_stale_markers` | | _boolean_ | false | -| `proxy_client_config` | ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/docs/vmagent.md#scraping-targets-via-a-proxy) | _[ProxyAuth](#proxyauth)_ | false | -| `relabel_debug` | deprecated since [v1.85](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.85.0), will be removed in next release | _boolean_ | false | +| `proxy_client_config` | ProxyClientConfig configures proxy auth settings for scraping
See feature description https://docs.victoriametrics.com/vmagent.html#scraping-targets-via-a-proxy | _[ProxyAuth](#proxyauth)_ | false | | `scrape_align_interval` | | _string_ | false | | `scrape_offset` | | _string_ | false | | `stream_parse` | | _boolean_ | false | diff --git a/internal/controller/operator/converter/apis.go b/internal/controller/operator/converter/apis.go index cdfe701e..39613260 100644 --- a/internal/controller/operator/converter/apis.go +++ b/internal/controller/operator/converter/apis.go @@ -189,29 +189,35 @@ func convertEndpoint(promEndpoint []promv1.Endpoint) []vmv1beta1.Endpoint { endpoints := make([]vmv1beta1.Endpoint, 0, len(promEndpoint)) for _, endpoint := range promEndpoint { ep := vmv1beta1.Endpoint{ - Port: endpoint.Port, - TargetPort: endpoint.TargetPort, - Path: endpoint.Path, - Scheme: endpoint.Scheme, - Params: endpoint.Params, - Interval: string(endpoint.Interval), - ScrapeTimeout: string(endpoint.ScrapeTimeout), - HonorLabels: endpoint.HonorLabels, - HonorTimestamps: endpoint.HonorTimestamps, - BasicAuth: ConvertBasicAuth(endpoint.BasicAuth), - TLSConfig: ConvertTLSConfig(endpoint.TLSConfig), - MetricRelabelConfigs: ConvertRelabelConfig(endpoint.MetricRelabelConfigs), - RelabelConfigs: ConvertRelabelConfig(endpoint.RelabelConfigs), - ProxyURL: endpoint.ProxyURL, - OAuth2: ConvertOAuth(endpoint.OAuth2), - FollowRedirects: endpoint.FollowRedirects, - Authorization: ConvertAuthorization(endpoint.Authorization, nil), - // Unless prometheus deletes BearerTokenFile, we have to support it for backward compatibility - //nolint:staticcheck - BearerTokenFile: ReplacePromDirPath(endpoint.BearerTokenFile), - // Unless prometheus deletes BearerTokenSecret, we have to support it for backward compatibility - //nolint:staticcheck - BearerTokenSecret: convertBearerToken(endpoint.BearerTokenSecret), + Port: endpoint.Port, + TargetPort: endpoint.TargetPort, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: endpoint.Path, + Scheme: endpoint.Scheme, + Params: endpoint.Params, + Interval: string(endpoint.Interval), + ScrapeTimeout: string(endpoint.ScrapeTimeout), + HonorLabels: endpoint.HonorLabels, + HonorTimestamps: endpoint.HonorTimestamps, + ProxyURL: endpoint.ProxyURL, + FollowRedirects: endpoint.FollowRedirects, + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: ConvertBasicAuth(endpoint.BasicAuth), + TLSConfig: ConvertTLSConfig(endpoint.TLSConfig), + OAuth2: ConvertOAuth(endpoint.OAuth2), + Authorization: ConvertAuthorization(endpoint.Authorization, nil), + // Unless prometheus deletes BearerTokenFile, we have to support it for backward compatibility + //nolint:staticcheck + BearerTokenFile: ReplacePromDirPath(endpoint.BearerTokenFile), + // Unless prometheus deletes BearerTokenSecret, we have to support it for backward compatibility + //nolint:staticcheck + BearerTokenSecret: convertBearerToken(endpoint.BearerTokenSecret), + }, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + MetricRelabelConfigs: ConvertRelabelConfig(endpoint.MetricRelabelConfigs), + RelabelConfigs: ConvertRelabelConfig(endpoint.RelabelConfigs), + }, } endpoints = append(endpoints, ep) @@ -336,23 +342,30 @@ func convertPodEndpoints(promPodEnpoints []promv1.PodMetricsEndpoint) []vmv1beta TargetPort: promEndPoint.TargetPort, // Unless prometheus deletes BearerTokenSecret, we have to support it for backward compatibility //nolint:staticcheck - BearerTokenSecret: convertBearerToken(&promEndPoint.BearerTokenSecret), - Interval: string(promEndPoint.Interval), - Path: promEndPoint.Path, - Scheme: promEndPoint.Scheme, - Params: promEndPoint.Params, - ScrapeTimeout: string(promEndPoint.ScrapeTimeout), - HonorLabels: promEndPoint.HonorLabels, - HonorTimestamps: promEndPoint.HonorTimestamps, - ProxyURL: promEndPoint.ProxyURL, - RelabelConfigs: ConvertRelabelConfig(promEndPoint.RelabelConfigs), - MetricRelabelConfigs: ConvertRelabelConfig(promEndPoint.MetricRelabelConfigs), - BasicAuth: ConvertBasicAuth(promEndPoint.BasicAuth), - TLSConfig: convertSafeTLSConfig(safeTLS), - OAuth2: ConvertOAuth(promEndPoint.OAuth2), - FollowRedirects: promEndPoint.FollowRedirects, - Authorization: ConvertAuthorization(promEndPoint.Authorization, nil), - FilterRunning: promEndPoint.FilterRunning, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Interval: string(promEndPoint.Interval), + Path: promEndPoint.Path, + Scheme: promEndPoint.Scheme, + Params: promEndPoint.Params, + ScrapeTimeout: string(promEndPoint.ScrapeTimeout), + HonorLabels: promEndPoint.HonorLabels, + HonorTimestamps: promEndPoint.HonorTimestamps, + ProxyURL: promEndPoint.ProxyURL, + FollowRedirects: promEndPoint.FollowRedirects, + }, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + RelabelConfigs: ConvertRelabelConfig(promEndPoint.RelabelConfigs), + MetricRelabelConfigs: ConvertRelabelConfig(promEndPoint.MetricRelabelConfigs), + }, + + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: ConvertBasicAuth(promEndPoint.BasicAuth), + BearerTokenSecret: convertBearerToken(&promEndPoint.BearerTokenSecret), + TLSConfig: convertSafeTLSConfig(safeTLS), + OAuth2: ConvertOAuth(promEndPoint.OAuth2), + Authorization: ConvertAuthorization(promEndPoint.Authorization, nil), + }, + FilterRunning: promEndPoint.FilterRunning, } endPoints = append(endPoints, ep) } @@ -449,13 +462,18 @@ func ConvertProbe(probe *promv1.Probe, conf *config.BaseOperatorConf) *vmv1beta1 Ingress: ingressTarget, StaticConfig: staticTargets, }, - Interval: string(probe.Spec.Interval), - ScrapeTimeout: string(probe.Spec.ScrapeTimeout), - BasicAuth: ConvertBasicAuth(probe.Spec.BasicAuth), - TLSConfig: convertSafeTLSConfig(safeTLS), - BearerTokenSecret: convertBearerToken(&probe.Spec.BearerTokenSecret), - OAuth2: ConvertOAuth(probe.Spec.OAuth2), - Authorization: ConvertAuthorization(probe.Spec.Authorization, nil), + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Interval: string(probe.Spec.Interval), + ScrapeTimeout: string(probe.Spec.ScrapeTimeout), + }, + MetricRelabelConfigs: ConvertRelabelConfig(probe.Spec.MetricRelabelConfigs), + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: ConvertBasicAuth(probe.Spec.BasicAuth), + BearerTokenSecret: convertBearerToken(&probe.Spec.BearerTokenSecret), + TLSConfig: convertSafeTLSConfig(safeTLS), + OAuth2: ConvertOAuth(probe.Spec.OAuth2), + Authorization: ConvertAuthorization(probe.Spec.Authorization, nil), + }, }, } if probe.Spec.ProberSpec.ProxyURL != "" { diff --git a/internal/controller/operator/converter/apis_test.go b/internal/controller/operator/converter/apis_test.go index 296b3b9b..1cc61561 100644 --- a/internal/controller/operator/converter/apis_test.go +++ b/internal/controller/operator/converter/apis_test.go @@ -162,12 +162,16 @@ func TestConvertEndpoint(t *testing.T) { }, want: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "9100", - RelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - Action: "drop", - SourceLabels: []string{"__meta__instance"}, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + RelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + Action: "drop", + SourceLabels: []string{"__meta__instance"}, + }, }, }, }, @@ -214,10 +218,12 @@ func TestConvertServiceMonitor(t *testing.T) { Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - Action: "drop", - SourceLabels: []string{"__meta__instance"}, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + Action: "drop", + SourceLabels: []string{"__meta__instance"}, + }, }, }, }, @@ -254,10 +260,12 @@ func TestConvertServiceMonitor(t *testing.T) { Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - Action: "drop", - SourceLabels: []string{"__meta__instance"}, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + Action: "drop", + SourceLabels: []string{"__meta__instance"}, + }, }, }, }, @@ -301,10 +309,12 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + }, }, }, }, @@ -326,12 +336,14 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - ServerName: "some-srv", - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + ServerName: "some-srv", + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + }, }, }, }, @@ -349,14 +361,16 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "bearer", + }, + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + }, + Password: corev1.SecretKeySelector{Key: "password"}, }, - Password: corev1.SecretKeySelector{Key: "password"}, }, }}, }, @@ -407,7 +421,9 @@ func TestConvertProbe(t *testing.T) { }, want: vmv1beta1.VMProbe{ Spec: vmv1beta1.VMProbeSpec{ - ProxyURL: ptr.To("http://proxy.com"), + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ProxyURL: ptr.To("http://proxy.com"), + }, Targets: vmv1beta1.VMProbeTargets{ StaticConfig: &vmv1beta1.VMProbeTargetStaticConfig{ Targets: []string{"target-1", "target-2"}, diff --git a/internal/controller/operator/converter/v1alpha1/apis_test.go b/internal/controller/operator/converter/v1alpha1/apis_test.go index a2a15867..d85caf09 100644 --- a/internal/controller/operator/converter/v1alpha1/apis_test.go +++ b/internal/controller/operator/converter/v1alpha1/apis_test.go @@ -104,30 +104,36 @@ func TestConvertScrapeConfig(t *testing.T) { }, want: vmv1beta1.VMScrapeConfig{ Spec: vmv1beta1.VMScrapeConfigSpec{ - ProxyURL: ptr.To("http://proxy.com"), + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ProxyURL: ptr.To("http://proxy.com"), + HonorTimestamps: ptr.To(true), + VMScrapeParams: &vmv1beta1.VMScrapeParams{DisableCompression: ptr.To(false)}, + }, StaticConfigs: []vmv1beta1.StaticConfig{ { Targets: []string{"target-1", "target-2"}, }, }, - HonorTimestamps: ptr.To(true), - VMScrapeParams: &vmv1beta1.VMScrapeParams{DisableCompression: ptr.To(false)}, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "username"}, - Password: corev1.SecretKeySelector{Key: "password"}, - }, - RelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - Action: "LabelMap", - Regex: vmv1beta1.StringOrArray{"__meta_kubernetes_pod_label_(.+)"}, - Replacement: "foo_$1", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "username"}, + Password: corev1.SecretKeySelector{Key: "password"}, }, }, - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - SourceLabels: []string{"__meta_kubernetes_pod_name", "__meta_kubernetes_pod_container_port_number"}, - Separator: ":", - TargetLabel: "host_port", + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + RelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + Action: "LabelMap", + Regex: vmv1beta1.StringOrArray{"__meta_kubernetes_pod_label_(.+)"}, + Replacement: "foo_$1", + }, + }, + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + SourceLabels: []string{"__meta_kubernetes_pod_name", "__meta_kubernetes_pod_container_port_number"}, + Separator: ":", + TargetLabel: "host_port", + }, }, }, }, diff --git a/internal/controller/operator/factory/build/vmservicescrape.go b/internal/controller/operator/factory/build/vmservicescrape.go index d747a363..f53f9835 100644 --- a/internal/controller/operator/factory/build/vmservicescrape.go +++ b/internal/controller/operator/factory/build/vmservicescrape.go @@ -24,7 +24,9 @@ func VMServiceScrapeForServiceWithSpec(service *v1.Service, serviceScrapeSpec *v endPoints = append(endPoints, vmv1beta1.Endpoint{ Port: servicePort.Name, - Path: metricPath, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: metricPath, + }, }) } diff --git a/internal/controller/operator/factory/build/vmservicescrape_test.go b/internal/controller/operator/factory/build/vmservicescrape_test.go index 720af620..b2f6099c 100644 --- a/internal/controller/operator/factory/build/vmservicescrape_test.go +++ b/internal/controller/operator/factory/build/vmservicescrape_test.go @@ -47,7 +47,9 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { wantServiceScrapeSpec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "http", }, }, @@ -78,7 +80,9 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { wantServiceScrapeSpec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "http", }, }, @@ -112,7 +116,9 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { wantServiceScrapeSpec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "http", }, }, @@ -144,14 +150,18 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { TargetLabels: []string{"key"}, Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "sidecar", }, { - Path: "/metrics", - Port: "http", - ScrapeInterval: "30s", - ScrapeTimeout: "10s", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + ScrapeInterval: "30s", + ScrapeTimeout: "10s", + }, + Port: "http", }, }, }, @@ -159,14 +169,18 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { wantServiceScrapeSpec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "sidecar", }, { - Path: "/metrics", - Port: "http", - ScrapeInterval: "30s", - ScrapeTimeout: "10s", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + ScrapeInterval: "30s", + ScrapeTimeout: "10s", + }, + Port: "http", }, }, TargetLabels: []string{"key"}, diff --git a/internal/controller/operator/factory/vmagent/collect_scrapes.go b/internal/controller/operator/factory/vmagent/collect_scrapes.go index cd3e05b9..208b6fd4 100644 --- a/internal/controller/operator/factory/vmagent/collect_scrapes.go +++ b/internal/controller/operator/factory/vmagent/collect_scrapes.go @@ -196,7 +196,7 @@ func selectServiceScrapes(ctx context.Context, cr *vmv1beta1.VMAgent, rclient cl if cr.Spec.ArbitraryFSAccessThroughSMs.Deny { for namespaceAndName, sm := range res { for _, endpoint := range sm.Spec.Endpoints { - if err := testForArbitraryFSAccess(endpoint); err != nil { + if err := testForArbitraryFSAccess(endpoint.EndpointAuth); err != nil { delete(res, namespaceAndName) logger.WithContext(ctx).Info("skipping vmservicescrape", "error", err.Error(), diff --git a/internal/controller/operator/factory/vmagent/nodescrape.go b/internal/controller/operator/factory/vmagent/nodescrape.go index deb5a1a4..e24db61b 100644 --- a/internal/controller/operator/factory/vmagent/nodescrape.go +++ b/internal/controller/operator/factory/vmagent/nodescrape.go @@ -3,154 +3,37 @@ package vmagent import ( "context" "fmt" - "sort" - "strings" vmv1beta1 "github.com/VictoriaMetrics/operator/api/operator/v1beta1" "gopkg.in/yaml.v2" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func generateNodeScrapeConfig( ctx context.Context, - crAgent *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, cr *vmv1beta1.VMNodeScrape, i int, apiserverConfig *vmv1beta1.APIServerConfig, ssCache *scrapesSecretsCache, - ignoreHonorLabels bool, - overrideHonorTimestamps bool, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { - nodeSpec := cr.Spec - hl := honorLabels(nodeSpec.HonorLabels, ignoreHonorLabels) + nodeSpec := &cr.Spec cfg := yaml.MapSlice{ { Key: "job_name", Value: fmt.Sprintf("nodeScrape/%s/%s/%d", cr.Namespace, cr.Name, i), }, - { - Key: "honor_labels", - Value: hl, - }, } - cfg = honorTimestamps(cfg, nodeSpec.HonorTimestamps, overrideHonorTimestamps) - cfg = append(cfg, generateK8SSDConfig(nil, apiserverConfig, ssCache, kubernetesSDRoleNode, nil)) + setScrapeIntervalToWithLimit(ctx, &nodeSpec.EndpointScrapeParams, vmagentCR) - var scrapeInterval string - if nodeSpec.ScrapeInterval != "" { - scrapeInterval = nodeSpec.ScrapeInterval - } else if nodeSpec.Interval != "" { - scrapeInterval = nodeSpec.Interval - } - scrapeInterval = limitScrapeInterval(ctx, scrapeInterval, crAgent.Spec.MinScrapeInterval, crAgent.Spec.MaxScrapeInterval) - if scrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) - } - - if nodeSpec.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: nodeSpec.ScrapeTimeout}) - } - if nodeSpec.Path != "" { - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: nodeSpec.Path}) - } - if nodeSpec.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: nodeSpec.ProxyURL}) - } - - if cr.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: cr.Spec.SampleLimit}) - } - if cr.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: cr.Spec.SeriesLimit}) - } - if nodeSpec.Params != nil { - cfg = append(cfg, yaml.MapItem{Key: "params", Value: nodeSpec.Params}) - } - if cr.Spec.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: cr.Spec.FollowRedirects}) - } - if nodeSpec.Scheme != "" { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: nodeSpec.Scheme}) - } - - cfg = addTLStoYaml(cfg, cr.Namespace, nodeSpec.TLSConfig, false) - - if nodeSpec.BearerTokenFile != "" { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: nodeSpec.BearerTokenFile}) - } - - if nodeSpec.BearerTokenSecret != nil && nodeSpec.BearerTokenSecret.Name != "" { - if s, ok := ssCache.bearerTokens[cr.AsMapKey()]; ok { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) - } - } - if cr.Spec.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[cr.AsMapKey()]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } - if len(cr.Spec.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: cr.Spec.BasicAuth.PasswordFile}) - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } + cfg = append(cfg, generateK8SSDConfig(nil, apiserverConfig, ssCache, kubernetesSDRoleNode, nil)) - var ( - relabelings []yaml.MapSlice - labelKeys []string - ) - // Filter targets by pods selected by the scrape. - // Exact label matches. - for k := range cr.Spec.Selector.MatchLabels { - labelKeys = append(labelKeys, k) - } - sort.Strings(labelKeys) + cfg = addCommonScrapeParamsTo(cfg, nodeSpec.EndpointScrapeParams, se) - for _, k := range labelKeys { - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_node_label_" + sanitizeLabelName(k)}}, - {Key: "regex", Value: cr.Spec.Selector.MatchLabels[k]}, - }) - } - // Set based label matching. We have to map the valid relations - // `In`, `NotIn`, `Exists`, and `DoesNotExist`, into relabeling rules. - for _, exp := range cr.Spec.Selector.MatchExpressions { - switch exp.Operator { - case metav1.LabelSelectorOpIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_node_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpNotIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_node_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpExists: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_node_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - case metav1.LabelSelectorOpDoesNotExist: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_node_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - } - } + var relabelings []yaml.MapSlice + relabelings = addSelectorToRelabelingFor(relabelings, "node", nodeSpec.Selector) // Add __address__ as internalIP and pod and service labels into proper labels. relabelings = append(relabelings, []yaml.MapSlice{ { @@ -200,29 +83,19 @@ func generateNodeScrapeConfig( for _, c := range nodeSpec.RelabelConfigs { relabelings = append(relabelings, generateRelabelConfig(c)) } - for _, trc := range crAgent.Spec.NodeScrapeRelabelTemplate { + for _, trc := range vmagentCR.Spec.NodeScrapeRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, cr.Namespace, enforcedNamespaceLabel) - cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + relabelings = enforceNamespaceLabel(relabelings, cr.Namespace, se.EnforcedNamespaceLabel) - if nodeSpec.MetricRelabelConfigs != nil { - var metricRelabelings []yaml.MapSlice - for _, c := range nodeSpec.MetricRelabelConfigs { - if c.TargetLabel != "" && enforcedNamespaceLabel != "" && c.TargetLabel == enforcedNamespaceLabel { - continue - } - relabeling := generateRelabelConfig(c) - - metricRelabelings = append(metricRelabelings, relabeling) - } - cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) - } + cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + cfg = addMetricRelabelingsTo(cfg, nodeSpec.MetricRelabelConfigs, se) cfg = append(cfg, buildVMScrapeParams(cr.Namespace, cr.AsProxyKey(), cr.Spec.VMScrapeParams, ssCache)...) - cfg = addOAuth2Config(cfg, cr.AsMapKey(), nodeSpec.OAuth2, ssCache.oauth2Secrets) - cfg = addAuthorizationConfig(cfg, cr.AsMapKey(), nodeSpec.Authorization, ssCache.authorizationSecrets) + cfg = addTLStoYaml(cfg, cr.Namespace, nodeSpec.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, nodeSpec.EndpointAuth, cr.AsMapKey(), ssCache) + return cfg } diff --git a/internal/controller/operator/factory/vmagent/nodescrape_test.go b/internal/controller/operator/factory/vmagent/nodescrape_test.go index 9a106076..b8dfe0af 100644 --- a/internal/controller/operator/factory/vmagent/nodescrape_test.go +++ b/internal/controller/operator/factory/vmagent/nodescrape_test.go @@ -15,14 +15,12 @@ import ( func Test_generateNodeScrapeConfig(t *testing.T) { type args struct { - cr vmv1beta1.VMAgent - m *vmv1beta1.VMNodeScrape - i int - apiserverConfig *vmv1beta1.APIServerConfig - ssCache *scrapesSecretsCache - ignoreHonorLabels bool - overrideHonorTimestamps bool - enforcedNamespaceLabel string + cr vmv1beta1.VMAgent + m *vmv1beta1.VMNodeScrape + i int + apiserverConfig *vmv1beta1.APIServerConfig + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -41,16 +39,19 @@ func Test_generateNodeScrapeConfig(t *testing.T) { Namespace: "default", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - Port: "9100", - Path: "/metrics", - Interval: "30s", + Port: "9100", + + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + Interval: "30s", + }, }, }, }, want: `job_name: nodeScrape/default/nodes-basic/1 -honor_labels: false kubernetes_sd_configs: - role: node +honor_labels: false scrape_interval: 30s metrics_path: /metrics relabel_configs: @@ -86,71 +87,72 @@ relabel_configs: Namespace: "default", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - Port: "9100", - Path: "/metrics", - Interval: "30s", - Scheme: "https", - HonorLabels: true, - ProxyURL: ptr.To("https://some-url"), - SampleLimit: 50, - SeriesLimit: 1000, - FollowRedirects: ptr.To(true), - ScrapeTimeout: "10s", - ScrapeInterval: "5s", - Params: map[string][]string{"module": {"client"}}, - JobLabel: "env", - HonorTimestamps: ptr.To(true), - TargetLabels: []string{"app", "env"}, - BearerTokenFile: "/tmp/bearer", - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "username", LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}}, - }, - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }, - OAuth2: &vmv1beta1.OAuth2{}, + Port: "9100", Selector: metav1.LabelSelector{ MatchLabels: map[string]string{"job": "prod"}, MatchExpressions: []metav1.LabelSelectorRequirement{ {Key: "external", Operator: metav1.LabelSelectorOpIn, Values: []string{"world"}}, }, }, - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + Interval: "30s", + Scheme: "https", + HonorLabels: true, + ProxyURL: ptr.To("https://some-url"), + SampleLimit: 50, + SeriesLimit: 1000, + FollowRedirects: ptr.To(true), + ScrapeTimeout: "10s", + ScrapeInterval: "5s", + Params: map[string][]string{"module": {"client"}}, + HonorTimestamps: ptr.To(true), + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + StreamParse: ptr.To(true), + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + BearerTokenFile: "/tmp/proxy-token", }, - BearerTokenFile: "/tmp/proxy-token", }, }, - RelabelConfigs: []*vmv1beta1.RelabelConfig{}, - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{}, + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenFile: "/tmp/bearer", + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "username", LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}}, + }, + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + OAuth2: &vmv1beta1.OAuth2{}, + }, + JobLabel: "env", + TargetLabels: []string{"app", "env"}, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + RelabelConfigs: []*vmv1beta1.RelabelConfig{}, + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{}, + }, }, }, }, want: `job_name: nodeScrape/default/nodes-basic/1 -honor_labels: true -honor_timestamps: true kubernetes_sd_configs: - role: node +honor_labels: true +honor_timestamps: true scrape_interval: 5s scrape_timeout: 10s metrics_path: /metrics proxy_url: https://some-url -sample_limit: 50 -series_limit: 1000 +follow_redirects: true params: module: - client -follow_redirects: true scheme: https -tls_config: - insecure_skip_verify: true -bearer_token_file: /tmp/bearer -basic_auth: - username: username - password: "" +sample_limit: 50 +series_limit: 1000 relabel_configs: - action: keep source_labels: @@ -185,17 +187,21 @@ relabel_configs: target_label: __address__ regex: ^(.*):(.*) replacement: ${1}:9100 -metric_relabel_configs: [] stream_parse: true proxy_tls_config: insecure_skip_verify: true proxy_bearer_token_file: /tmp/proxy-token +tls_config: + insecure_skip_verify: true +bearer_token_file: /tmp/bearer +basic_auth: + username: username `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generateNodeScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.ignoreHonorLabels, tt.args.overrideHonorTimestamps, tt.args.enforcedNamespaceLabel) + got := generateNodeScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Errorf("cannot marshal NodeScrapeConfig to yaml,err :%e", err) diff --git a/internal/controller/operator/factory/vmagent/podscrape.go b/internal/controller/operator/factory/vmagent/podscrape.go index 9f844e25..2cb0e314 100644 --- a/internal/controller/operator/factory/vmagent/podscrape.go +++ b/internal/controller/operator/factory/vmagent/podscrape.go @@ -3,8 +3,6 @@ package vmagent import ( "context" "fmt" - "sort" - "strings" vmv1beta1 "github.com/VictoriaMetrics/operator/api/operator/v1beta1" "gopkg.in/yaml.v2" @@ -13,98 +11,40 @@ import ( func generatePodScrapeConfig( ctx context.Context, - cr *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, m *vmv1beta1.VMPodScrape, ep vmv1beta1.PodMetricsEndpoint, i int, apiserverConfig *vmv1beta1.APIServerConfig, ssCache *scrapesSecretsCache, - ignoreHonorLabels bool, - overrideHonorTimestamps bool, - ignoreNamespaceSelectors bool, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { - hl := honorLabels(ep.HonorLabels, ignoreHonorLabels) cfg := yaml.MapSlice{ { Key: "job_name", Value: fmt.Sprintf("podScrape/%s/%s/%d", m.Namespace, m.Name, i), }, - { - Key: "honor_labels", - Value: hl, - }, } - cfg = honorTimestamps(cfg, ep.HonorTimestamps, overrideHonorTimestamps) - selectedNamespaces := getNamespacesFromNamespaceSelector(&m.Spec.NamespaceSelector, m.Namespace, ignoreNamespaceSelectors) + selectedNamespaces := getNamespacesFromNamespaceSelector(&m.Spec.NamespaceSelector, m.Namespace, se.IgnoreNamespaceSelectors) if ep.AttachMetadata.Node == nil && m.Spec.AttachMetadata.Node != nil { ep.AttachMetadata = m.Spec.AttachMetadata } cfg = append(cfg, generatePodK8SSDConfig(selectedNamespaces, m.Spec.Selector, apiserverConfig, ssCache, kubernetesSDRolePod, &ep.AttachMetadata)) - var scrapeInterval string - if ep.ScrapeInterval != "" { - scrapeInterval = ep.ScrapeInterval - } else if ep.Interval != "" { - scrapeInterval = ep.Interval - } - - scrapeInterval = limitScrapeInterval(ctx, scrapeInterval, cr.Spec.MinScrapeInterval, cr.Spec.MaxScrapeInterval) - if scrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) - } - if ep.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: ep.ScrapeTimeout}) - } - if ep.Path != "" { - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: ep.Path}) + // set defaults + if ep.SampleLimit == 0 { + ep.SampleLimit = m.Spec.SampleLimit } - if ep.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: ep.ProxyURL}) - } - if ep.Params != nil { - cfg = append(cfg, yaml.MapItem{Key: "params", Value: ep.Params}) + if ep.SeriesLimit == 0 { + ep.SeriesLimit = m.Spec.SeriesLimit } - if ep.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: ep.FollowRedirects}) - } - if ep.Scheme != "" { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: ep.Scheme}) - } - cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) + setScrapeIntervalToWithLimit(ctx, &ep.EndpointScrapeParams, vmagentCR) - if ep.BearerTokenFile != "" { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: ep.BearerTokenFile}) - } + cfg = addCommonScrapeParamsTo(cfg, ep.EndpointScrapeParams, se) - if ep.BearerTokenSecret != nil && ep.BearerTokenSecret.Name != "" { - if s, ok := ssCache.bearerTokens[m.AsMapKey(i)]; ok { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) - } - } - - if ep.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[m.AsMapKey(i)]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } - if len(ep.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: ep.BasicAuth.PasswordFile}) - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } - - var ( - relabelings []yaml.MapSlice - labelKeys []string - ) + var relabelings []yaml.MapSlice if ep.FilterRunning == nil || *ep.FilterRunning { relabelings = append(relabelings, yaml.MapSlice{ @@ -113,50 +53,8 @@ func generatePodScrapeConfig( {Key: "regex", Value: "(Failed|Succeeded)"}, }) } - // Filter targets by pods selected by the scrape. - // Exact label matches. - for k := range m.Spec.Selector.MatchLabels { - labelKeys = append(labelKeys, k) - } - sort.Strings(labelKeys) - for _, k := range labelKeys { - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_pod_label_" + sanitizeLabelName(k)}}, - {Key: "regex", Value: m.Spec.Selector.MatchLabels[k]}, - }) - } - // Set based label matching. We have to map the valid relations - // `In`, `NotIn`, `Exists`, and `DoesNotExist`, into relabeling rules. - for _, exp := range m.Spec.Selector.MatchExpressions { - switch exp.Operator { - case metav1.LabelSelectorOpIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_pod_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpNotIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_pod_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpExists: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_pod_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - case metav1.LabelSelectorOpDoesNotExist: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_pod_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - } - } + relabelings = addSelectorToRelabelingFor(relabelings, "pod", m.Spec.Selector) // Filter targets based on correct port for the endpoint. if ep.Port != "" { @@ -241,42 +139,19 @@ func generatePodScrapeConfig( for _, c := range ep.RelabelConfigs { relabelings = append(relabelings, generateRelabelConfig(c)) } - for _, trc := range cr.Spec.PodScrapeRelabelTemplate { + for _, trc := range vmagentCR.Spec.PodScrapeRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, m.Namespace, enforcedNamespaceLabel) - cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) - - if ep.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: ep.SampleLimit}) - } else if m.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: m.Spec.SampleLimit}) - } - if ep.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: ep.SeriesLimit}) - } else if m.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: m.Spec.SeriesLimit}) - } - - if ep.MetricRelabelConfigs != nil { - var metricRelabelings []yaml.MapSlice - for _, c := range ep.MetricRelabelConfigs { - if c.TargetLabel != "" && enforcedNamespaceLabel != "" && c.TargetLabel == enforcedNamespaceLabel { - continue - } - relabeling := generateRelabelConfig(c) - - metricRelabelings = append(metricRelabelings, relabeling) - } - cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) - } + relabelings = enforceNamespaceLabel(relabelings, m.Namespace, se.EnforcedNamespaceLabel) + cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + cfg = addMetricRelabelingsTo(cfg, ep.MetricRelabelConfigs, se) cfg = append(cfg, buildVMScrapeParams(m.Namespace, m.AsProxyKey(i), ep.VMScrapeParams, ssCache)...) + cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, ep.EndpointAuth, m.AsMapKey(i), ssCache) - cfg = addOAuth2Config(cfg, m.AsMapKey(i), ep.OAuth2, ssCache.oauth2Secrets) - cfg = addAuthorizationConfig(cfg, m.AsMapKey(i), ep.Authorization, ssCache.authorizationSecrets) return cfg } diff --git a/internal/controller/operator/factory/vmagent/podscrape_test.go b/internal/controller/operator/factory/vmagent/podscrape_test.go index 6cc8ec41..b4f30fce 100644 --- a/internal/controller/operator/factory/vmagent/podscrape_test.go +++ b/internal/controller/operator/factory/vmagent/podscrape_test.go @@ -13,16 +13,13 @@ import ( func Test_generatePodScrapeConfig(t *testing.T) { type args struct { - cr vmv1beta1.VMAgent - m *vmv1beta1.VMPodScrape - ep vmv1beta1.PodMetricsEndpoint - i int - apiserverConfig *vmv1beta1.APIServerConfig - ssCache *scrapesSecretsCache - ignoreHonorLabels bool - overrideHonorTimestamps bool - ignoreNamespaceSelectors bool - enforcedNamespaceLabel string + cr vmv1beta1.VMAgent + m *vmv1beta1.VMPodScrape + ep vmv1beta1.PodMetricsEndpoint + i int + apiserverConfig *vmv1beta1.APIServerConfig + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -39,7 +36,9 @@ func Test_generatePodScrapeConfig(t *testing.T) { }, }, ep: vmv1beta1.PodMetricsEndpoint{ - Path: "/metric", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metric", + }, Port: "web", AttachMetadata: vmv1beta1.AttachMetadata{ Node: ptr.To(true), @@ -48,7 +47,6 @@ func Test_generatePodScrapeConfig(t *testing.T) { ssCache: &scrapesSecretsCache{}, }, want: `job_name: podScrape/default/test-1/0 -honor_labels: false kubernetes_sd_configs: - role: pod attach_metadata: @@ -56,6 +54,7 @@ kubernetes_sd_configs: namespaces: names: - default +honor_labels: false metrics_path: /metric relabel_configs: - action: drop @@ -91,7 +90,9 @@ relabel_configs: }, }, ep: vmv1beta1.PodMetricsEndpoint{ - Path: "/metric", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metric", + }, Port: "web", AttachMetadata: vmv1beta1.AttachMetadata{ Node: ptr.To(true), @@ -101,7 +102,6 @@ relabel_configs: ssCache: &scrapesSecretsCache{}, }, want: `job_name: podScrape/default/test-1/0 -honor_labels: false kubernetes_sd_configs: - role: pod attach_metadata: @@ -109,6 +109,7 @@ kubernetes_sd_configs: namespaces: names: - default +honor_labels: false metrics_path: /metric relabel_configs: - action: keep @@ -158,18 +159,20 @@ relabel_configs: }, }, ep: vmv1beta1.PodMetricsEndpoint{ - Path: "/metric", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metric", + }, Port: "web", }, ssCache: &scrapesSecretsCache{}, }, want: `job_name: podScrape/default/test-1/0 -honor_labels: false kubernetes_sd_configs: - role: pod selectors: - role: pod label: label-1=value-1,label-2=value-2,label-3=value-3 +honor_labels: false metrics_path: /metric relabel_configs: - action: drop @@ -214,7 +217,7 @@ relabel_configs: } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generatePodScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.ignoreHonorLabels, tt.args.overrideHonorTimestamps, tt.args.ignoreNamespaceSelectors, tt.args.enforcedNamespaceLabel) + got := generatePodScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Errorf("cannot marshal PodScrapeConfig to yaml,err :%e", err) diff --git a/internal/controller/operator/factory/vmagent/probe.go b/internal/controller/operator/factory/vmagent/probe.go index 394fa982..6276f11b 100644 --- a/internal/controller/operator/factory/vmagent/probe.go +++ b/internal/controller/operator/factory/vmagent/probe.go @@ -3,23 +3,19 @@ package vmagent import ( "context" "fmt" - "sort" - "strings" vmv1beta1 "github.com/VictoriaMetrics/operator/api/operator/v1beta1" "gopkg.in/yaml.v2" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func generateProbeConfig( ctx context.Context, - crAgent *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, cr *vmv1beta1.VMProbe, i int, apiserverConfig *vmv1beta1.APIServerConfig, ssCache *scrapesSecretsCache, - ignoreNamespaceSelectors bool, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { cfg := yaml.MapSlice{ { @@ -27,45 +23,25 @@ func generateProbeConfig( Value: fmt.Sprintf("probe/%s/%s/%d", cr.Namespace, cr.Name, i), }, } - var relabelings []yaml.MapSlice + // add defaults if cr.Spec.VMProberSpec.Path == "" { cr.Spec.VMProberSpec.Path = "/probe" } - var scrapeInterval string - if cr.Spec.ScrapeInterval != "" { - scrapeInterval = cr.Spec.ScrapeInterval - } else if cr.Spec.Interval != "" { - scrapeInterval = cr.Spec.Interval - } - scrapeInterval = limitScrapeInterval(ctx, scrapeInterval, crAgent.Spec.MinScrapeInterval, crAgent.Spec.MaxScrapeInterval) - if scrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) - } + cr.Spec.EndpointScrapeParams.Path = cr.Spec.VMProberSpec.Path - if cr.Spec.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: cr.Spec.ScrapeTimeout}) - } - if cr.Spec.VMProberSpec.Scheme != "" { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: cr.Spec.VMProberSpec.Scheme}) - } - params := yaml.MapSlice{ - {Key: "module", Value: []string{cr.Spec.Module}}, - } - paramIdxes := make([]string, len(cr.Spec.Params)) - var idxCnt int - for k := range cr.Spec.Params { - paramIdxes[idxCnt] = k - idxCnt++ - } - sort.Strings(paramIdxes) - for _, k := range paramIdxes { - params = append(params, yaml.MapItem{Key: k, Value: cr.Spec.Params[k]}) + if len(cr.Spec.Module) > 0 { + if cr.Spec.Params == nil { + cr.Spec.Params = make(map[string][]string) + } + cr.Spec.Params["module"] = []string{cr.Spec.Module} } - cfg = append(cfg, yaml.MapItem{Key: "params", Value: params}) + setScrapeIntervalToWithLimit(ctx, &cr.Spec.EndpointScrapeParams, vmagentCR) - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: cr.Spec.VMProberSpec.Path}) + cfg = addCommonScrapeParamsTo(cfg, cr.Spec.EndpointScrapeParams, se) + + var relabelings []yaml.MapSlice if cr.Spec.Targets.StaticConfig != nil { staticConfig := yaml.MapSlice{ @@ -82,68 +58,20 @@ func generateProbeConfig( Key: "static_configs", Value: []yaml.MapSlice{staticConfig}, }) + relabelings = append(relabelings, yaml.MapSlice{ {Key: "source_labels", Value: []string{"__address__"}}, {Key: "target_label", Value: "__param_target"}, }) // Add configured relabelings. for _, r := range cr.Spec.Targets.StaticConfig.RelabelConfigs { - if r.TargetLabel != "" && enforcedNamespaceLabel != "" && r.TargetLabel == enforcedNamespaceLabel { - continue - } relabelings = append(relabelings, generateRelabelConfig(r)) } } if cr.Spec.Targets.Ingress != nil { - var labelKeys []string - - // Filter targets by ingresses selected by the probe. - // Exact label matches. - for k := range cr.Spec.Targets.Ingress.Selector.MatchLabels { - labelKeys = append(labelKeys, k) - } - sort.Strings(labelKeys) - - for _, k := range labelKeys { - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_ingress_label_" + sanitizeLabelName(k)}}, - {Key: "regex", Value: cr.Spec.Targets.Ingress.Selector.MatchLabels[k]}, - }) - } - - // Set based label matching. We have to map the valid relations - // `In`, `NotIn`, `Exists`, and `DoesNotExist`, into relabeling rules. - for _, exp := range cr.Spec.Targets.Ingress.Selector.MatchExpressions { - switch exp.Operator { - case metav1.LabelSelectorOpIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_ingress_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpNotIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_ingress_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpExists: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_ingress_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - case metav1.LabelSelectorOpDoesNotExist: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_ingress_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - } - } - selectedNamespaces := getNamespacesFromNamespaceSelector(&cr.Spec.Targets.Ingress.NamespaceSelector, cr.Namespace, ignoreNamespaceSelectors) + relabelings = addSelectorToRelabelingFor(relabelings, "ingress", cr.Spec.Targets.Ingress.Selector) + selectedNamespaces := getNamespacesFromNamespaceSelector(&cr.Spec.Targets.Ingress.NamespaceSelector, cr.Namespace, se.IgnoreNamespaceSelectors) cfg = append(cfg, generateK8SSDConfig(selectedNamespaces, apiserverConfig, ssCache, kubernetesSDRoleIngress, nil)) // Relabelings for ingress SD. @@ -176,9 +104,6 @@ func generateProbeConfig( // Add configured relabelings. for _, r := range cr.Spec.Targets.Ingress.RelabelConfigs { - if r.TargetLabel != "" && enforcedNamespaceLabel != "" && r.TargetLabel == enforcedNamespaceLabel { - continue - } relabelings = append(relabelings, generateRelabelConfig(r)) } @@ -191,24 +116,6 @@ func generateProbeConfig( }) } - if cr.Spec.BearerTokenSecret != nil && cr.Spec.BearerTokenSecret.Name != "" { - if token := ssCache.bearerTokens[cr.AsMapKey()]; len(token) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: token}) - } - } - if len(cr.Spec.BearerTokenFile) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: cr.Spec.BearerTokenFile}) - } - - if cr.Spec.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: cr.Spec.FollowRedirects}) - } - if cr.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: cr.Spec.SampleLimit}) - } - if cr.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: cr.Spec.SeriesLimit}) - } // Relabelings for prober. relabelings = append(relabelings, []yaml.MapSlice{ { @@ -221,37 +128,18 @@ func generateProbeConfig( }, }...) - for _, trc := range crAgent.Spec.ProbeScrapeRelabelTemplate { + for _, trc := range vmagentCR.Spec.ProbeScrapeRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, cr.Namespace, enforcedNamespaceLabel) + relabelings = enforceNamespaceLabel(relabelings, cr.Namespace, se.EnforcedNamespaceLabel) cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) - - if cr.Spec.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[cr.AsMapKey()]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } - if len(cr.Spec.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: cr.Spec.BasicAuth.PasswordFile}) - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } - cfg = addTLStoYaml(cfg, cr.Namespace, cr.Spec.TLSConfig, false) + cfg = addMetricRelabelingsTo(cfg, cr.Spec.MetricRelabelConfigs, se) cfg = append(cfg, buildVMScrapeParams(cr.Namespace, cr.AsProxyKey(), cr.Spec.VMScrapeParams, ssCache)...) - cfg = addOAuth2Config(cfg, cr.AsMapKey(), cr.Spec.OAuth2, ssCache.oauth2Secrets) - cfg = addAuthorizationConfig(cfg, cr.AsMapKey(), cr.Spec.Authorization, ssCache.authorizationSecrets) + cfg = addTLStoYaml(cfg, cr.Namespace, cr.Spec.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, cr.Spec.EndpointAuth, cr.AsMapKey(), ssCache) - if cr.Spec.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: cr.Spec.ProxyURL}) - } return cfg } diff --git a/internal/controller/operator/factory/vmagent/probe_test.go b/internal/controller/operator/factory/vmagent/probe_test.go index 4fd57452..35105881 100644 --- a/internal/controller/operator/factory/vmagent/probe_test.go +++ b/internal/controller/operator/factory/vmagent/probe_test.go @@ -15,13 +15,12 @@ import ( func Test_generateProbeConfig(t *testing.T) { type args struct { - crAgent vmv1beta1.VMAgent - cr *vmv1beta1.VMProbe - i int - apiserverConfig *vmv1beta1.APIServerConfig - ssCache *scrapesSecretsCache - ignoreNamespaceSelectors bool - enforcedNamespaceLabel string + crAgent vmv1beta1.VMAgent + cr *vmv1beta1.VMProbe + i int + apiserverConfig *vmv1beta1.APIServerConfig + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -51,10 +50,11 @@ func Test_generateProbeConfig(t *testing.T) { i: 0, }, want: `job_name: probe/default/static-probe/0 +honor_labels: false +metrics_path: /probe params: module: - http -metrics_path: /probe static_configs: - targets: - host-1 @@ -100,10 +100,11 @@ relabel_configs: }, }, want: `job_name: probe/monitor/probe-ingress/0 +honor_labels: false +metrics_path: /probe params: module: - http200 -metrics_path: /probe kubernetes_sd_configs: - role: ingress namespaces: @@ -158,35 +159,39 @@ relabel_configs: Name: "static-probe", }, Spec: vmv1beta1.VMProbeSpec{ - Module: "http", - BearerTokenFile: "/tmp/some_path", - FollowRedirects: ptr.To(true), - ScrapeInterval: "10s", - Interval: "5s", - Params: map[string][]string{ - "timeout": {"10s"}, - }, - ScrapeTimeout: "15s", - BasicAuth: &vmv1beta1.BasicAuth{ - PasswordFile: "/tmp/some-file-ba", - }, - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - StreamParse: ptr.To(false), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + Module: "http", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + FollowRedirects: ptr.To(true), + ScrapeInterval: "10s", + Interval: "5s", + Params: map[string][]string{ + "timeout": {"10s"}, + }, + ScrapeTimeout: "15s", + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + StreamParse: ptr.To(false), + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + }}, + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{Key: "cert", LocalObjectReference: corev1.LocalObjectReference{Name: "tls-secret"}}, }, - }}, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{Key: "cert", LocalObjectReference: corev1.LocalObjectReference{Name: "tls-secret"}}, + KeyFile: "/tmp/key-1", }, - KeyFile: "/tmp/key-1", }, }, }, + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenFile: "/tmp/some_path", + BasicAuth: &vmv1beta1.BasicAuth{ + PasswordFile: "/tmp/some-file-ba", + }, + }, VMProberSpec: vmv1beta1.VMProberSpec{URL: "blackbox-monitor:9115"}, Targets: vmv1beta1.VMProbeTargets{ StaticConfig: &vmv1beta1.VMProbeTargetStaticConfig{ @@ -199,22 +204,22 @@ relabel_configs: i: 0, }, want: `job_name: probe/default/static-probe/0 +honor_labels: false scrape_interval: 10s scrape_timeout: 15s +metrics_path: /probe +follow_redirects: true params: module: - http timeout: - 10s -metrics_path: /probe static_configs: - targets: - host-1 - host-2 labels: label1: value1 -bearer_token_file: /tmp/some_path -follow_redirects: true relabel_configs: - source_labels: - __address__ @@ -224,20 +229,21 @@ relabel_configs: target_label: instance - target_label: __address__ replacement: blackbox-monitor:9115 -basic_auth: - password_file: /tmp/some-file-ba stream_parse: false proxy_tls_config: insecure_skip_verify: false ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca cert_file: /etc/vmagent-tls/certs/default_tls-secret_cert key_file: /tmp/key-1 +bearer_token_file: /tmp/some_path +basic_auth: + password_file: /tmp/some-file-ba `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generateProbeConfig(context.Background(), &tt.args.crAgent, tt.args.cr, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.ignoreNamespaceSelectors, tt.args.enforcedNamespaceLabel) + got := generateProbeConfig(context.Background(), &tt.args.crAgent, tt.args.cr, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Errorf("cannot decode probe config, it must be in yaml format :%e", err) diff --git a/internal/controller/operator/factory/vmagent/scrapeconfig.go b/internal/controller/operator/factory/vmagent/scrapeconfig.go index 4a422e09..777e1d20 100644 --- a/internal/controller/operator/factory/vmagent/scrapeconfig.go +++ b/internal/controller/operator/factory/vmagent/scrapeconfig.go @@ -11,105 +11,39 @@ import ( func generateScrapeConfig( ctx context.Context, - cr *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, sc *vmv1beta1.VMScrapeConfig, ssCache *scrapesSecretsCache, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { jobName := fmt.Sprintf("scrapeConfig/%s/%s", sc.Namespace, sc.Name) - hl := honorLabels(sc.Spec.HonorLabels, cr.Spec.OverrideHonorLabels) cfg := yaml.MapSlice{ { Key: "job_name", Value: jobName, }, - { - Key: "honor_labels", - Value: hl, - }, } - cfg = honorTimestamps(cfg, sc.Spec.HonorTimestamps, cr.Spec.OverrideHonorTimestamps) - if sc.Spec.MetricsPath != nil { - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: *sc.Spec.MetricsPath}) - } + setScrapeIntervalToWithLimit(ctx, &sc.Spec.EndpointScrapeParams, vmagentCR) - scrapeInterval := limitScrapeInterval(ctx, sc.Spec.ScrapeInterval, cr.Spec.MinScrapeInterval, cr.Spec.MaxScrapeInterval) - if sc.Spec.ScrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) - } - if sc.Spec.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: sc.Spec.ScrapeTimeout}) - } - if len(sc.Spec.Params) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "params", Value: sc.Spec.Params}) - } - if sc.Spec.Scheme != nil { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: strings.ToLower(*sc.Spec.Scheme)}) - } - cfg = append(cfg, buildVMScrapeParams(cr.Namespace, sc.AsProxyKey("", 0), sc.Spec.VMScrapeParams, ssCache)...) - - if sc.Spec.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: sc.Spec.FollowRedirects}) - } - if sc.Spec.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: sc.Spec.ProxyURL}) - } - if sc.Spec.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[sc.AsMapKey("", 0)]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - ) - if s.Password != "" { - bac = append(bac, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } else if len(sc.Spec.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: sc.Spec.BasicAuth.PasswordFile}) - } - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } - cfg = addAuthorizationConfig(cfg, sc.AsMapKey("", 0), sc.Spec.Authorization, ssCache.authorizationSecrets) - cfg = addOAuth2Config(cfg, sc.AsMapKey("", 0), sc.Spec.OAuth2, ssCache.oauth2Secrets) - cfg = addTLStoYaml(cfg, sc.Namespace, sc.Spec.TLSConfig, false) - - if sc.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: sc.Spec.SampleLimit}) - } - if sc.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: sc.Spec.SeriesLimit}) - } - if sc.Spec.MaxScrapeSize != "" { - cfg = append(cfg, yaml.MapItem{Key: "max_scrape_size", Value: sc.Spec.MaxScrapeSize}) - } + cfg = addCommonScrapeParamsTo(cfg, sc.Spec.EndpointScrapeParams, se) var relabelings []yaml.MapSlice for _, c := range sc.Spec.RelabelConfigs { relabelings = append(relabelings, generateRelabelConfig(c)) } - for _, trc := range cr.Spec.ScrapeConfigRelabelTemplate { + for _, trc := range vmagentCR.Spec.ScrapeConfigRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, sc.Namespace, enforcedNamespaceLabel) - cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + relabelings = enforceNamespaceLabel(relabelings, sc.Namespace, se.EnforcedNamespaceLabel) - if sc.Spec.MetricRelabelConfigs != nil { - var metricRelabelings []yaml.MapSlice - for _, c := range sc.Spec.MetricRelabelConfigs { - if c.TargetLabel != "" && enforcedNamespaceLabel != "" && c.TargetLabel == enforcedNamespaceLabel { - continue - } - relabeling := generateRelabelConfig(c) - metricRelabelings = append(metricRelabelings, relabeling) - } - cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) - } + cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + cfg = addMetricRelabelingsTo(cfg, sc.Spec.MetricRelabelConfigs, se) + cfg = append(cfg, buildVMScrapeParams(sc.Namespace, sc.AsProxyKey("", 0), sc.Spec.VMScrapeParams, ssCache)...) + cfg = addTLStoYaml(cfg, sc.Namespace, sc.Spec.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, sc.Spec.EndpointAuth, sc.AsMapKey("", 0), ssCache) // build staticConfig if len(sc.Spec.StaticConfigs) > 0 { @@ -175,7 +109,7 @@ func generateScrapeConfig( configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: bac}) } } - configs[i] = addAuthorizationConfig(configs[i], sc.AsMapKey("httpsd", i), config.Authorization, ssCache.authorizationSecrets) + configs[i] = addAuthorizationConfigTo(configs[i], sc.AsMapKey("httpsd", i), config.Authorization, ssCache.authorizationSecrets) if config.TLSConfig != nil { configs[i] = addTLStoYaml(configs[i], sc.Namespace, config.TLSConfig, false) } @@ -224,11 +158,11 @@ func generateScrapeConfig( configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: bac}) } } - configs[i] = addAuthorizationConfig(configs[i], sc.AsMapKey("kubesd", i), config.Authorization, ssCache.authorizationSecrets) + configs[i] = addAuthorizationConfigTo(configs[i], sc.AsMapKey("kubesd", i), config.Authorization, ssCache.authorizationSecrets) if config.TLSConfig != nil { configs[i] = addTLStoYaml(configs[i], sc.Namespace, config.TLSConfig, false) } - configs[i] = addOAuth2Config(configs[i], sc.AsMapKey("kubesd", i), config.OAuth2, ssCache.oauth2Secrets) + configs[i] = addOAuth2ConfigTo(configs[i], sc.AsMapKey("kubesd", i), config.OAuth2, ssCache.oauth2Secrets) if config.ProxyURL != nil { configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) } @@ -394,8 +328,8 @@ func generateScrapeConfig( configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: bac}) } } - configs[i] = addAuthorizationConfig(configs[i], sc.AsMapKey("consulsd", i), config.Authorization, ssCache.authorizationSecrets) - configs[i] = addOAuth2Config(configs[i], sc.AsMapKey("consulsd", i), config.OAuth2, ssCache.oauth2Secrets) + configs[i] = addAuthorizationConfigTo(configs[i], sc.AsMapKey("consulsd", i), config.Authorization, ssCache.authorizationSecrets) + configs[i] = addOAuth2ConfigTo(configs[i], sc.AsMapKey("consulsd", i), config.OAuth2, ssCache.oauth2Secrets) if config.ProxyURL != nil { configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) } @@ -733,8 +667,8 @@ func generateScrapeConfig( if len(sc.Spec.DigitalOceanSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(sc.Spec.DigitalOceanSDConfigs)) for i, config := range sc.Spec.DigitalOceanSDConfigs { - configs[i] = addAuthorizationConfig(configs[i], sc.AsMapKey("digitaloceansd", i), config.Authorization, ssCache.authorizationSecrets) - configs[i] = addOAuth2Config(configs[i], sc.AsMapKey("digitaloceansd", i), config.OAuth2, ssCache.oauth2Secrets) + configs[i] = addAuthorizationConfigTo(configs[i], sc.AsMapKey("digitaloceansd", i), config.Authorization, ssCache.authorizationSecrets) + configs[i] = addOAuth2ConfigTo(configs[i], sc.AsMapKey("digitaloceansd", i), config.OAuth2, ssCache.oauth2Secrets) if config.ProxyURL != nil { configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) } diff --git a/internal/controller/operator/factory/vmagent/scrapeconfig_test.go b/internal/controller/operator/factory/vmagent/scrapeconfig_test.go index 0dec2ae6..11a627cf 100644 --- a/internal/controller/operator/factory/vmagent/scrapeconfig_test.go +++ b/internal/controller/operator/factory/vmagent/scrapeconfig_test.go @@ -15,10 +15,10 @@ import ( func TestGenerateScrapeConfig(t *testing.T) { type args struct { - cr vmv1beta1.VMAgent - m *vmv1beta1.VMScrapeConfig - ssCache *scrapesSecretsCache - enforceNamespaceLabel string + cr vmv1beta1.VMAgent + m *vmv1beta1.VMScrapeConfig + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -40,17 +40,21 @@ func TestGenerateScrapeConfig(t *testing.T) { Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - MaxScrapeSize: "60KB", - ScrapeInterval: "10s", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + MaxScrapeSize: "60KB", + ScrapeInterval: "10s", + }, StaticConfigs: []vmv1beta1.StaticConfig{ { Targets: []string{"http://test1.com", "http://test2.com"}, Labels: map[string]string{"bar": "baz"}, }, }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "username"}, - Password: corev1.SecretKeySelector{Key: "password"}, + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "username"}, + Password: corev1.SecretKeySelector{Key: "password"}, + }, }, }, }, @@ -66,11 +70,11 @@ func TestGenerateScrapeConfig(t *testing.T) { want: `job_name: scrapeConfig/default/static-1 honor_labels: false scrape_interval: 30s +max_scrape_size: 60KB +relabel_configs: [] basic_auth: username: admin password: dangerous -max_scrape_size: 60KB -relabel_configs: [] static_configs: - targets: - http://test1.com @@ -94,16 +98,20 @@ static_configs: Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - ScrapeInterval: "10m", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "username"}, + PasswordFile: "/var/run/secrets/password", + }, + }, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ScrapeInterval: "10m", + }, FileSDConfigs: []vmv1beta1.FileSDConfig{ { Files: []string{"test1.json", "test2.json"}, }, }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "username"}, - PasswordFile: "/var/run/secrets/password", - }, }, }, ssCache: &scrapesSecretsCache{ @@ -117,10 +125,10 @@ static_configs: want: `job_name: scrapeConfig/default/file-1 honor_labels: false scrape_interval: 5m +relabel_configs: [] basic_auth: username: user password_file: /var/run/secrets/password -relabel_configs: [] file_sd_configs: - files: - test1.json @@ -475,7 +483,7 @@ kubernetes_sd_configs: } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generateScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ssCache, tt.args.enforceNamespaceLabel) + got := generateScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/internal/controller/operator/factory/vmagent/servicescrape.go b/internal/controller/operator/factory/vmagent/servicescrape.go index 56079ba1..d64d726c 100644 --- a/internal/controller/operator/factory/vmagent/servicescrape.go +++ b/internal/controller/operator/factory/vmagent/servicescrape.go @@ -3,157 +3,55 @@ package vmagent import ( "context" "fmt" - "sort" - "strings" vmv1beta1 "github.com/VictoriaMetrics/operator/api/operator/v1beta1" "gopkg.in/yaml.v2" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func generateServiceScrapeConfig( ctx context.Context, - cr *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, m *vmv1beta1.VMServiceScrape, ep vmv1beta1.Endpoint, i int, apiserverConfig *vmv1beta1.APIServerConfig, ssCache *scrapesSecretsCache, - overrideHonorLabels bool, - overrideHonorTimestamps bool, - ignoreNamespaceSelectors bool, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { - hl := honorLabels(ep.HonorLabels, overrideHonorLabels) cfg := yaml.MapSlice{ { Key: "job_name", Value: fmt.Sprintf("serviceScrape/%s/%s/%d", m.Namespace, m.Name, i), }, - { - Key: "honor_labels", - Value: hl, - }, } // service role. if m.Spec.DiscoveryRole == "" { m.Spec.DiscoveryRole = kubernetesSDRoleEndpoint } - cfg = honorTimestamps(cfg, ep.HonorTimestamps, overrideHonorTimestamps) - selectedNamespaces := getNamespacesFromNamespaceSelector(&m.Spec.NamespaceSelector, m.Namespace, ignoreNamespaceSelectors) + selectedNamespaces := getNamespacesFromNamespaceSelector(&m.Spec.NamespaceSelector, m.Namespace, se.IgnoreNamespaceSelectors) if ep.AttachMetadata.Node == nil && m.Spec.AttachMetadata.Node != nil { ep.AttachMetadata = m.Spec.AttachMetadata } cfg = append(cfg, generateK8SSDConfig(selectedNamespaces, apiserverConfig, ssCache, m.Spec.DiscoveryRole, &ep.AttachMetadata)) - var scrapeInterval string - if ep.ScrapeInterval != "" { - scrapeInterval = ep.ScrapeInterval - } else if ep.Interval != "" { - scrapeInterval = ep.Interval - } - - scrapeInterval = limitScrapeInterval(ctx, scrapeInterval, cr.Spec.MinScrapeInterval, cr.Spec.MaxScrapeInterval) - - if scrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) - } - if ep.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: ep.ScrapeTimeout}) + if ep.SampleLimit == 0 { + ep.SampleLimit = m.Spec.SampleLimit } - if ep.Path != "" { - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: ep.Path}) - } - if ep.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: ep.ProxyURL}) - } - if ep.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: ep.FollowRedirects}) - } - if ep.Params != nil { - cfg = append(cfg, yaml.MapItem{Key: "params", Value: ep.Params}) - } - if ep.Scheme != "" { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: ep.Scheme}) - } - - cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) - - if ep.BearerTokenFile != "" { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: ep.BearerTokenFile}) + if ep.SeriesLimit == 0 { + ep.SeriesLimit = m.Spec.SeriesLimit } - if ep.BearerTokenSecret != nil && ep.BearerTokenSecret.Name != "" { - if s, ok := ssCache.bearerTokens[m.AsMapKey(i)]; ok { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) - } - } + setScrapeIntervalToWithLimit(ctx, &ep.EndpointScrapeParams, vmagentCR) - if ep.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[m.AsMapKey(i)]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } - if len(ep.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: ep.BasicAuth.PasswordFile}) - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } + cfg = addCommonScrapeParamsTo(cfg, ep.EndpointScrapeParams, se) var relabelings []yaml.MapSlice // Filter targets by services selected by the scrape. // Exact label matches. - var labelKeys []string - for k := range m.Spec.Selector.MatchLabels { - labelKeys = append(labelKeys, k) - } - sort.Strings(labelKeys) - - for _, k := range labelKeys { - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_service_label_" + sanitizeLabelName(k)}}, - {Key: "regex", Value: m.Spec.Selector.MatchLabels[k]}, - }) - } - // Set based label matching. We have to map the valid relations - // `In`, `NotIn`, `Exists`, and `DoesNotExist`, into relabeling rules. - for _, exp := range m.Spec.Selector.MatchExpressions { - switch exp.Operator { - case metav1.LabelSelectorOpIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_service_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpNotIn: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_service_label_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: strings.Join(exp.Values, "|")}, - }) - case metav1.LabelSelectorOpExists: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "keep"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_service_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - case metav1.LabelSelectorOpDoesNotExist: - relabelings = append(relabelings, yaml.MapSlice{ - {Key: "action", Value: "drop"}, - {Key: "source_labels", Value: []string{"__meta_kubernetes_service_labelpresent_" + sanitizeLabelName(exp.Key)}}, - {Key: "regex", Value: "true"}, - }) - } - } + relabelings = addSelectorToRelabelingFor(relabelings, "service", m.Spec.Selector) // Filter targets based on correct port for the endpoint. if ep.Port != "" { @@ -316,42 +214,19 @@ func generateServiceScrapeConfig( relabelings = append(relabelings, generateRelabelConfig(c)) } - for _, trc := range cr.Spec.ServiceScrapeRelabelTemplate { + for _, trc := range vmagentCR.Spec.ServiceScrapeRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, m.Namespace, enforcedNamespaceLabel) - cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) - - if ep.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: ep.SampleLimit}) - } else if m.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: m.Spec.SampleLimit}) - } - if ep.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: ep.SeriesLimit}) - } else if m.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: m.Spec.SeriesLimit}) - } - - if ep.MetricRelabelConfigs != nil { - var metricRelabelings []yaml.MapSlice - for _, c := range ep.MetricRelabelConfigs { - if c.TargetLabel != "" && enforcedNamespaceLabel != "" && c.TargetLabel == enforcedNamespaceLabel { - continue - } - relabeling := generateRelabelConfig(c) - - metricRelabelings = append(metricRelabelings, relabeling) - } - cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) - } + relabelings = enforceNamespaceLabel(relabelings, m.Namespace, se.EnforcedNamespaceLabel) + cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + cfg = addMetricRelabelingsTo(cfg, ep.MetricRelabelConfigs, se) cfg = append(cfg, buildVMScrapeParams(m.Namespace, m.AsProxyKey(i), ep.VMScrapeParams, ssCache)...) - cfg = addOAuth2Config(cfg, m.AsMapKey(i), ep.OAuth2, ssCache.oauth2Secrets) - cfg = addAuthorizationConfig(cfg, m.AsMapKey(i), ep.Authorization, ssCache.authorizationSecrets) + cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, ep.EndpointAuth, m.AsMapKey(i), ssCache) return cfg } diff --git a/internal/controller/operator/factory/vmagent/servicescrape_test.go b/internal/controller/operator/factory/vmagent/servicescrape_test.go index 604a88a3..98be68ce 100644 --- a/internal/controller/operator/factory/vmagent/servicescrape_test.go +++ b/internal/controller/operator/factory/vmagent/servicescrape_test.go @@ -16,16 +16,13 @@ import ( func Test_generateServiceScrapeConfig(t *testing.T) { type args struct { - cr vmv1beta1.VMAgent - m *vmv1beta1.VMServiceScrape - ep vmv1beta1.Endpoint - i int - apiserverConfig *vmv1beta1.APIServerConfig - ssCache *scrapesSecretsCache - overrideHonorLabels bool - overrideHonorTimestamps bool - ignoreNamespaceSelectors bool - enforcedNamespaceLabel string + cr vmv1beta1.VMAgent + m *vmv1beta1.VMServiceScrape + ep vmv1beta1.Endpoint + i int + apiserverConfig *vmv1beta1.APIServerConfig + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -44,17 +41,19 @@ func Test_generateServiceScrapeConfig(t *testing.T) { Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, @@ -64,29 +63,32 @@ func Test_generateServiceScrapeConfig(t *testing.T) { Node: ptr.To(true), }, Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, + se: vmv1beta1.VMAgentSecurityEnforcements{ + OverrideHonorLabels: false, + OverrideHonorTimestamps: false, + IgnoreNamespaceSelectors: false, + EnforcedNamespaceLabel: "", + }, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: endpoints attach_metadata: @@ -94,10 +96,7 @@ kubernetes_sd_configs: namespaces: names: - default -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen +honor_labels: false relabel_configs: - action: keep source_labels: @@ -135,6 +134,10 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, @@ -155,57 +158,55 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, }, ep: vmv1beta1.Endpoint{ Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", + }, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ScrapeInterval: "60m", }, - BearerTokenFile: "/var/run/tolen", - ScrapeInterval: "60m", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default +honor_labels: false scrape_interval: 40m -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen relabel_configs: - action: keep source_labels: @@ -243,6 +244,10 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, { @@ -262,57 +267,56 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, }, ep: vmv1beta1.Endpoint{ Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ScrapeInterval: "10s", + }, + + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", - ScrapeInterval: "10s", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default +honor_labels: false scrape_interval: 1m -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen relabel_configs: - action: keep source_labels: @@ -350,6 +354,10 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, { @@ -365,55 +373,51 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, }, ep: vmv1beta1.Endpoint{ Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: endpointslices namespaces: names: - default -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen +honor_labels: false relabel_configs: - action: keep source_labels: @@ -448,6 +452,10 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, { @@ -463,17 +471,19 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, @@ -483,38 +493,32 @@ relabel_configs: Node: ptr.To(true), }, Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: service namespaces: names: - default -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen +honor_labels: false relabel_configs: - action: keep source_labels: @@ -532,6 +536,10 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, { @@ -560,21 +568,17 @@ relabel_configs: return &v }(), }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: service namespaces: names: - default +honor_labels: false relabel_configs: - source_labels: - __meta_kubernetes_namespace @@ -601,8 +605,10 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, }, }, }, @@ -610,29 +616,24 @@ relabel_configs: }, ep: vmv1beta1.Endpoint{ Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: service namespaces: names: - default -tls_config: - insecure_skip_verify: true -bearer_token_file: /var/run/tolen +honor_labels: false relabel_configs: - action: keep source_labels: @@ -650,6 +651,9 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" +tls_config: + insecure_skip_verify: true +bearer_token_file: /var/run/tolen `, }, { @@ -665,66 +669,75 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, }, }, }, }, }, ep: vmv1beta1.Endpoint{ - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - TLSConfig: &vmv1beta1.TLSConfig{InsecureSkipVerify: true}, - BearerTokenFile: "/tmp/some-file", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Params: map[string][]string{"module": {"base"}}, + ScrapeInterval: "10s", + ScrapeTimeout: "5s", + HonorTimestamps: ptr.To(true), + FollowRedirects: ptr.To(true), + ProxyURL: ptr.To("https://some-proxy"), + HonorLabels: true, + Scheme: "https", + Path: "/metrics", + + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + StreamParse: ptr.To(true), + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + TLSConfig: &vmv1beta1.TLSConfig{InsecureSkipVerify: true}, + BearerTokenFile: "/tmp/some-file", + }, }, }, - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{}, - RelabelConfigs: []*vmv1beta1.RelabelConfig{}, - OAuth2: &vmv1beta1.OAuth2{ - Scopes: []string{"scope-1"}, - TokenURL: "http://some-token-url", - EndpointParams: map[string]string{"timeout": "5s"}, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{}, + RelabelConfigs: []*vmv1beta1.RelabelConfig{}, + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + Scopes: []string{"scope-1"}, + TokenURL: "http://some-token-url", + EndpointParams: map[string]string{"timeout": "5s"}, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ Key: "bearer", LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, }, }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, + Password: corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, }, - }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, }, - Password: corev1.SecretKeySelector{ + BearerTokenFile: "/var/run/tolen", + BearerTokenSecret: &corev1.SecretKeySelector{ Key: "bearer", LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, }, }, - Params: map[string][]string{"module": {"base"}}, - ScrapeInterval: "10s", - ScrapeTimeout: "5s", - HonorTimestamps: ptr.To(true), - FollowRedirects: ptr.To(true), - ProxyURL: ptr.To("https://some-proxy"), - HonorLabels: true, - Scheme: "https", - Path: "/metrics", - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, - }, Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }, - BearerTokenFile: "/var/run/tolen", }, i: 0, apiserverConfig: nil, @@ -740,19 +753,15 @@ relabel_configs: "serviceScrape/default/test-scrape/0": {ClientSecret: "some-secret", ClientID: "some-id"}, }, }, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: true -honor_timestamps: true kubernetes_sd_configs: - role: service namespaces: names: - default +honor_labels: true +honor_timestamps: true scrape_interval: 10s scrape_timeout: 5s metrics_path: /metrics @@ -762,12 +771,6 @@ params: module: - base scheme: https -tls_config: - insecure_skip_verify: true -bearer_token_file: /var/run/tolen -basic_auth: - username: user - password: pass relabel_configs: - action: keep source_labels: @@ -785,11 +788,16 @@ relabel_configs: replacement: ${1} - target_label: endpoint replacement: "8080" -metric_relabel_configs: [] stream_parse: true proxy_tls_config: insecure_skip_verify: true proxy_bearer_token_file: /tmp/some-file +tls_config: + insecure_skip_verify: true +bearer_token_file: /var/run/tolen +basic_auth: + username: user + password: pass oauth2: client_id: some-id client_secret: some-secret @@ -823,55 +831,51 @@ oauth2: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, }, }, }, ep: vmv1beta1.Endpoint{ Port: "8080", - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "ca", }, - Key: "ca", }, }, + BearerTokenFile: "/var/run/tolen", }, - BearerTokenFile: "/var/run/tolen", }, - i: 0, - apiserverConfig: nil, - ssCache: &scrapesSecretsCache{}, - overrideHonorLabels: false, - overrideHonorTimestamps: false, - ignoreNamespaceSelectors: false, - enforcedNamespaceLabel: "", + i: 0, + apiserverConfig: nil, + ssCache: &scrapesSecretsCache{}, }, want: `job_name: serviceScrape/default/test-scrape/0 -honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default -tls_config: - insecure_skip_verify: false - ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca -bearer_token_file: /var/run/tolen +honor_labels: false relabel_configs: - action: keep source_labels: @@ -913,12 +917,16 @@ relabel_configs: - __meta_kubernetes_node_name target_label: node regex: .+ +tls_config: + insecure_skip_verify: false + ca_file: /etc/vmagent-tls/certs/default_tls-secret_ca +bearer_token_file: /var/run/tolen `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generateServiceScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.overrideHonorLabels, tt.args.overrideHonorTimestamps, tt.args.ignoreNamespaceSelectors, tt.args.enforcedNamespaceLabel) + got := generateServiceScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.apiserverConfig, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Errorf("cannot marshal ServiceScrapeConfig to yaml,err :%e", err) diff --git a/internal/controller/operator/factory/vmagent/staticscrape.go b/internal/controller/operator/factory/vmagent/staticscrape.go index af38aab7..e49a4738 100644 --- a/internal/controller/operator/factory/vmagent/staticscrape.go +++ b/internal/controller/operator/factory/vmagent/staticscrape.go @@ -10,26 +10,19 @@ import ( func generateStaticScrapeConfig( ctx context.Context, - cr *vmv1beta1.VMAgent, + vmagentCR *vmv1beta1.VMAgent, m *vmv1beta1.VMStaticScrape, ep *vmv1beta1.TargetEndpoint, i int, ssCache *scrapesSecretsCache, - overrideHonorLabels, overrideHonorTimestamps bool, - enforcedNamespaceLabel string, + se vmv1beta1.VMAgentSecurityEnforcements, ) yaml.MapSlice { - hl := honorLabels(ep.HonorLabels, overrideHonorLabels) cfg := yaml.MapSlice{ { Key: "job_name", Value: fmt.Sprintf("staticScrape/%s/%s/%d", m.Namespace, m.Name, i), }, - { - Key: "honor_labels", - Value: hl, - }, } - cfg = honorTimestamps(cfg, ep.HonorTimestamps, overrideHonorTimestamps) tgs := yaml.MapSlice{{Key: "targets", Value: ep.Targets}} if ep.Labels != nil { @@ -38,64 +31,19 @@ func generateStaticScrapeConfig( cfg = append(cfg, yaml.MapItem{Key: "static_configs", Value: []yaml.MapSlice{tgs}}) - var scrapeInterval string - if ep.ScrapeInterval != "" { - scrapeInterval = ep.ScrapeInterval - } else if ep.Interval != "" { - scrapeInterval = ep.Interval + // set defaults + if ep.SampleLimit == 0 { + ep.SampleLimit = m.Spec.SampleLimit } - scrapeInterval = limitScrapeInterval(ctx, scrapeInterval, cr.Spec.MinScrapeInterval, cr.Spec.MaxScrapeInterval) - - if scrapeInterval != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: scrapeInterval}) + if ep.SeriesLimit == 0 { + ep.SeriesLimit = m.Spec.SeriesLimit } - - if ep.ScrapeTimeout != "" { - cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: ep.ScrapeTimeout}) - } - if ep.Path != "" { - cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: ep.Path}) - } - if ep.ProxyURL != nil { - cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: ep.ProxyURL}) + if ep.ScrapeTimeout == "" { + ep.ScrapeTimeout = vmagentCR.Spec.ScrapeTimeout } + setScrapeIntervalToWithLimit(ctx, &ep.EndpointScrapeParams, vmagentCR) - if ep.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: ep.FollowRedirects}) - } - if ep.Params != nil { - cfg = append(cfg, yaml.MapItem{Key: "params", Value: ep.Params}) - } - if ep.Scheme != "" { - cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: ep.Scheme}) - } - - cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) - - if ep.BearerTokenFile != "" { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: ep.BearerTokenFile}) - } - - if ep.BearerTokenSecret != nil && ep.BearerTokenSecret.Name != "" { - if s, ok := ssCache.bearerTokens[m.AsMapKey(i)]; ok { - cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) - } - } - if ep.BasicAuth != nil { - var bac yaml.MapSlice - if s, ok := ssCache.baSecrets[m.AsMapKey(i)]; ok { - bac = append(bac, - yaml.MapItem{Key: "username", Value: s.Username}, - yaml.MapItem{Key: "password", Value: s.Password}, - ) - } - if len(ep.BasicAuth.PasswordFile) > 0 { - bac = append(bac, yaml.MapItem{Key: "password_file", Value: ep.BasicAuth.PasswordFile}) - } - if len(bac) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) - } - } + cfg = addCommonScrapeParamsTo(cfg, ep.EndpointScrapeParams, se) var relabelings []yaml.MapSlice @@ -109,39 +57,18 @@ func generateStaticScrapeConfig( for _, c := range ep.RelabelConfigs { relabelings = append(relabelings, generateRelabelConfig(c)) } - for _, trc := range cr.Spec.StaticScrapeRelabelTemplate { + for _, trc := range vmagentCR.Spec.StaticScrapeRelabelTemplate { relabelings = append(relabelings, generateRelabelConfig(trc)) } // Because of security risks, whenever enforcedNamespaceLabel is set, we want to append it to the // relabel_configs as the last relabeling, to ensure it overrides any other relabelings. - relabelings = enforceNamespaceLabel(relabelings, m.Namespace, enforcedNamespaceLabel) - cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) - - if ep.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: ep.SampleLimit}) - } else if m.Spec.SampleLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: m.Spec.SampleLimit}) - } - if ep.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: ep.SeriesLimit}) - } else if m.Spec.SeriesLimit > 0 { - cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: m.Spec.SeriesLimit}) - } - - if ep.MetricRelabelConfigs != nil { - var metricRelabelings []yaml.MapSlice - for _, c := range ep.MetricRelabelConfigs { - if c.TargetLabel != "" && enforcedNamespaceLabel != "" && c.TargetLabel == enforcedNamespaceLabel { - continue - } - relabeling := generateRelabelConfig(c) - metricRelabelings = append(metricRelabelings, relabeling) - } - cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) - } + relabelings = enforceNamespaceLabel(relabelings, m.Namespace, se.EnforcedNamespaceLabel) + cfg = append(cfg, yaml.MapItem{Key: "relabel_configs", Value: relabelings}) + cfg = addMetricRelabelingsTo(cfg, ep.MetricRelabelConfigs, se) cfg = append(cfg, buildVMScrapeParams(m.Namespace, m.AsProxyKey(i), ep.VMScrapeParams, ssCache)...) - cfg = addOAuth2Config(cfg, m.AsMapKey(i), ep.OAuth2, ssCache.oauth2Secrets) - cfg = addAuthorizationConfig(cfg, m.AsMapKey(i), ep.Authorization, ssCache.authorizationSecrets) + cfg = addTLStoYaml(cfg, m.Namespace, ep.TLSConfig, false) + cfg = addEndpointAuthTo(cfg, ep.EndpointAuth, m.AsMapKey(i), ssCache) + return cfg } diff --git a/internal/controller/operator/factory/vmagent/staticscrape_test.go b/internal/controller/operator/factory/vmagent/staticscrape_test.go index 5e80c184..dce906e9 100644 --- a/internal/controller/operator/factory/vmagent/staticscrape_test.go +++ b/internal/controller/operator/factory/vmagent/staticscrape_test.go @@ -15,14 +15,12 @@ import ( func Test_generateStaticScrapeConfig(t *testing.T) { type args struct { - cr vmv1beta1.VMAgent - m *vmv1beta1.VMStaticScrape - ep *vmv1beta1.TargetEndpoint - i int - ssCache *scrapesSecretsCache - overrideHonorLabels bool - overrideHonorTimestamps bool - enforceNamespaceLabel string + cr vmv1beta1.VMAgent + m *vmv1beta1.VMStaticScrape + ep *vmv1beta1.TargetEndpoint + i int + ssCache *scrapesSecretsCache + se vmv1beta1.VMAgentSecurityEnforcements } tests := []struct { name string @@ -48,7 +46,6 @@ func Test_generateStaticScrapeConfig(t *testing.T) { }, }, want: `job_name: staticScrape/default/static-1/0 -honor_labels: false static_configs: - targets: - 192.168.11.1:9100 @@ -56,6 +53,7 @@ static_configs: labels: env: dev group: prod +honor_labels: false relabel_configs: - target_label: job replacement: static-job @@ -75,24 +73,28 @@ relabel_configs: }, }, ep: &vmv1beta1.TargetEndpoint{ - Targets: []string{"192.168.11.1:9100", "some-host:9100"}, - Labels: map[string]string{"env": "dev", "group": "prod"}, - HonorTimestamps: ptr.To(true), - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - TargetLabel: "namespace", - SourceLabels: []string{"abuse"}, - Action: "replace", + Targets: []string{"192.168.11.1:9100", "some-host:9100"}, + Labels: map[string]string{"env": "dev", "group": "prod"}, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + HonorTimestamps: ptr.To(true), + }, + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + TargetLabel: "namespace", + SourceLabels: []string{"abuse"}, + Action: "replace", + }, }, }, }, - overrideHonorTimestamps: false, - overrideHonorLabels: true, - enforceNamespaceLabel: "namespace", + se: vmv1beta1.VMAgentSecurityEnforcements{ + OverrideHonorTimestamps: false, + OverrideHonorLabels: true, + EnforcedNamespaceLabel: "namespace", + }, }, want: `job_name: staticScrape/default/static-1/0 -honor_labels: false -honor_timestamps: true static_configs: - targets: - 192.168.11.1:9100 @@ -100,12 +102,13 @@ static_configs: labels: env: dev group: prod +honor_labels: false +honor_timestamps: true relabel_configs: - target_label: job replacement: static-job - target_label: namespace replacement: default -metric_relabel_configs: [] `, }, { @@ -141,101 +144,107 @@ metric_relabel_configs: [] }, }, ep: &vmv1beta1.TargetEndpoint{ - Params: map[string][]string{"timeout": {"50s"}, "follow": {"false"}}, - SampleLimit: 60, - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{Name: "tls-cfg"}, - }}, - CertFile: "/tmp/cert-part", - KeySecret: &corev1.SecretKeySelector{ - Key: "key", - LocalObjectReference: corev1.LocalObjectReference{Name: "tls-cfg"}, - }, - InsecureSkipVerify: true, - }, - ScrapeTimeout: "55s", - Interval: "10s", - ScrapeInterval: "50s", - FollowRedirects: ptr.To(true), - Path: "/metrics-1", - Port: "8031", - Scheme: "https", - ProxyURL: ptr.To("https://some-proxy"), - HonorLabels: true, - RelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - Action: "drop", - SourceLabels: []string{"src"}, - Regex: []string{"vmagent", "vmalert"}, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Params: map[string][]string{"timeout": {"50s"}, "follow": {"false"}}, + SampleLimit: 60, + ScrapeTimeout: "55s", + Interval: "10s", + ScrapeInterval: "50s", + FollowRedirects: ptr.To(true), + Path: "/metrics-1", + Scheme: "https", + ProxyURL: ptr.To("https://some-proxy"), + HonorLabels: true, + HonorTimestamps: ptr.To(true), + + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + ScrapeOffset: ptr.To("10s"), + DisableKeepAlive: ptr.To(true), + DisableCompression: ptr.To(true), + ScrapeAlignInterval: ptr.To("5s"), + StreamParse: ptr.To(true), + Headers: []string{"customer-header: with-value"}, + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "user", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-proxy-secret"}, + }, + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-proxy-secret"}, + }, + }, + }, }, }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "user", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{Name: "tls-cfg"}, + }}, + CertFile: "/tmp/cert-part", + KeySecret: &corev1.SecretKeySelector{ + Key: "key", + LocalObjectReference: corev1.LocalObjectReference{Name: "tls-cfg"}, + }, + InsecureSkipVerify: true, }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "user", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + }, + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + }, }, - }, - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "token", - LocalObjectReference: corev1.LocalObjectReference{Name: "token-secret"}, - }, - OAuth2: &vmv1beta1.OAuth2{ - ClientSecret: &corev1.SecretKeySelector{Key: "client-s", LocalObjectReference: corev1.LocalObjectReference{Name: "oauth-2s"}}, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{Key: "client-id", LocalObjectReference: corev1.LocalObjectReference{Name: "oauth-2s"}}, + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "token", + LocalObjectReference: corev1.LocalObjectReference{Name: "token-secret"}, }, - }, - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - RelabelDebug: ptr.To(true), - ScrapeOffset: ptr.To("10s"), - MetricRelabelDebug: ptr.To(false), - DisableKeepAlive: ptr.To(true), - DisableCompression: ptr.To(true), - ScrapeAlignInterval: ptr.To("5s"), - StreamParse: ptr.To(true), - Headers: []string{"customer-header: with-value"}, - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "user", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-proxy-secret"}, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-proxy-secret"}, - }, + OAuth2: &vmv1beta1.OAuth2{ + ClientSecret: &corev1.SecretKeySelector{Key: "client-s", LocalObjectReference: corev1.LocalObjectReference{Name: "oauth-2s"}}, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{Key: "client-id", LocalObjectReference: corev1.LocalObjectReference{Name: "oauth-2s"}}, }, }, }, - Targets: []string{"192.168.11.1:9100", "some-host:9100"}, - Labels: map[string]string{"env": "dev", "group": "prod"}, - HonorTimestamps: ptr.To(true), - MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ - { - TargetLabel: "namespace", - SourceLabels: []string{"abuse"}, - Action: "replace", + EndpointRelabelings: vmv1beta1.EndpointRelabelings{ + RelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + Action: "drop", + SourceLabels: []string{"src"}, + Regex: []string{"vmagent", "vmalert"}, + }, }, - { - TargetLabel: "pod_status", - SourceLabels: []string{"pod"}, - Action: "replace", + + MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{ + { + TargetLabel: "namespace", + SourceLabels: []string{"abuse"}, + Action: "replace", + }, + { + TargetLabel: "pod_status", + SourceLabels: []string{"pod"}, + Action: "replace", + }, }, }, + + Targets: []string{"192.168.11.1:9100", "some-host:9100"}, + Labels: map[string]string{"env": "dev", "group": "prod"}, + }, + se: vmv1beta1.VMAgentSecurityEnforcements{ + OverrideHonorTimestamps: false, + OverrideHonorLabels: true, + EnforcedNamespaceLabel: "namespace", }, - overrideHonorTimestamps: false, - overrideHonorLabels: true, - enforceNamespaceLabel: "namespace", }, want: `job_name: staticScrape/default/static-1/0 -honor_labels: false -honor_timestamps: true static_configs: - targets: - 192.168.11.1:9100 @@ -243,6 +252,8 @@ static_configs: labels: env: dev group: prod +honor_labels: false +honor_timestamps: true scrape_interval: 50s scrape_timeout: 55s metrics_path: /metrics-1 @@ -254,14 +265,7 @@ params: timeout: - 50s scheme: https -tls_config: - insecure_skip_verify: true - ca_file: /etc/vmagent-tls/certs/default_tls-cfg_ca - cert_file: /tmp/cert-part - key_file: /etc/vmagent-tls/certs/default_tls-cfg_key -basic_auth: - username: admin - password: pass +sample_limit: 60 relabel_configs: - target_label: job replacement: static-job @@ -273,7 +277,6 @@ relabel_configs: action: drop - target_label: namespace replacement: default -sample_limit: 60 metric_relabel_configs: - source_labels: - pod @@ -284,13 +287,19 @@ stream_parse: true disable_compression: true scrape_offset: 10s disable_keepalive: true -relabel_debug: true -metric_relabel_debug: false headers: - 'customer-header: with-value' proxy_basic_auth: username: proxy-user password: proxy-password +tls_config: + insecure_skip_verify: true + ca_file: /etc/vmagent-tls/certs/default_tls-cfg_ca + cert_file: /tmp/cert-part + key_file: /etc/vmagent-tls/certs/default_tls-cfg_key +basic_auth: + username: admin + password: pass oauth2: client_id: some-id client_secret: some-secret @@ -299,7 +308,7 @@ oauth2: } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := generateStaticScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.ssCache, tt.args.overrideHonorLabels, tt.args.overrideHonorTimestamps, tt.args.enforceNamespaceLabel) + got := generateStaticScrapeConfig(context.Background(), &tt.args.cr, tt.args.m, tt.args.ep, tt.args.i, tt.args.ssCache, tt.args.se) gotBytes, err := yaml.Marshal(got) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig.go b/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig.go index 7912cb58..52bf2bbc 100644 --- a/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig.go +++ b/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig.go @@ -792,10 +792,17 @@ func loadAdditionalScrapeConfigsSecret(ctx context.Context, rclient client.Clien return nil, nil } -func testForArbitraryFSAccess(e vmv1beta1.Endpoint) error { +func testForArbitraryFSAccess(e vmv1beta1.EndpointAuth) error { if e.BearerTokenFile != "" { return fmt.Errorf("it accesses file system via bearer token file which VMAgent specification prohibits") } + if e.BasicAuth != nil && e.BasicAuth.PasswordFile != "" { + return fmt.Errorf("it accesses file system via basicAuth password file which VMAgent specification prohibits") + } + + if e.OAuth2 != nil && e.OAuth2.ClientSecretFile != "" { + return fmt.Errorf("it accesses file system via oauth2 client secret file which VMAgent specification prohibits") + } tlsConf := e.TLSConfig if tlsConf == nil { @@ -822,39 +829,46 @@ func gzipConfig(buf *bytes.Buffer, conf []byte) error { return nil } -func limitScrapeInterval(ctx context.Context, origin string, minIntervalStr, maxIntervalStr *string) string { - if origin == "" || (minIntervalStr == nil && maxIntervalStr == nil) { +func setScrapeIntervalToWithLimit(ctx context.Context, dst *vmv1beta1.EndpointScrapeParams, vmagentCR *vmv1beta1.VMAgent) { + if dst.ScrapeInterval == "" { + dst.ScrapeInterval = dst.Interval + } + + originInterval, minIntervalStr, maxIntervalStr := dst.ScrapeInterval, vmagentCR.Spec.MinScrapeInterval, vmagentCR.Spec.MaxScrapeInterval + if originInterval == "" || (minIntervalStr == nil && maxIntervalStr == nil) { // fast path - return origin + return } - originDurationMs, err := metricsql.DurationValue(origin, 0) + originDurationMs, err := metricsql.DurationValue(originInterval, 0) if err != nil { - logger.WithContext(ctx).Error(err, "cannot parse duration value during limiting interval, using original value: %s", origin) - return origin + logger.WithContext(ctx).Error(err, "cannot parse duration value during limiting interval, using original value: %s", originInterval) + return } if minIntervalStr != nil { parsedMinMs, err := metricsql.DurationValue(*minIntervalStr, 0) if err != nil { - logger.WithContext(ctx).Error(err, "cannot parse minScrapeInterval: %s, using original value: %s", *minIntervalStr, origin) - return origin + logger.WithContext(ctx).Error(err, "cannot parse minScrapeInterval: %s, using original value: %s", *minIntervalStr, originInterval) + return } if parsedMinMs >= originDurationMs { - return *minIntervalStr + dst.ScrapeInterval = *minIntervalStr + return } } if maxIntervalStr != nil { parsedMaxMs, err := metricsql.DurationValue(*maxIntervalStr, 0) if err != nil { - logger.WithContext(ctx).Error(err, "cannot parse maxScrapeInterval: %s, using origin value: %s", *maxIntervalStr, origin) - return origin + logger.WithContext(ctx).Error(err, "cannot parse maxScrapeInterval: %s, using origin value: %s", *maxIntervalStr, originInterval) + return } if parsedMaxMs < originDurationMs { - return *maxIntervalStr + dst.ScrapeInterval = *maxIntervalStr + return } } - return origin + return } const ( @@ -975,10 +989,8 @@ func generateConfig( ep, i, apiserverConfig, secretsCache, - cr.Spec.OverrideHonorLabels, - cr.Spec.OverrideHonorTimestamps, - cr.Spec.IgnoreNamespaceSelectors, - cr.Spec.EnforcedNamespaceLabel)) + cr.Spec.VMAgentSecurityEnforcements, + )) } } for _, identifier := range pMonIdentifiers { @@ -990,10 +1002,8 @@ func generateConfig( pMons[identifier], ep, i, apiserverConfig, secretsCache, - cr.Spec.OverrideHonorLabels, - cr.Spec.OverrideHonorTimestamps, - cr.Spec.IgnoreNamespaceSelectors, - cr.Spec.EnforcedNamespaceLabel)) + cr.Spec.VMAgentSecurityEnforcements, + )) } } @@ -1006,8 +1016,8 @@ func generateConfig( i, apiserverConfig, secretsCache, - cr.Spec.IgnoreNamespaceSelectors, - cr.Spec.EnforcedNamespaceLabel)) + cr.Spec.VMAgentSecurityEnforcements, + )) } for i, identifier := range nodeIdentifiers { scrapeConfigs = append(scrapeConfigs, @@ -1018,9 +1028,8 @@ func generateConfig( i, apiserverConfig, secretsCache, - cr.Spec.OverrideHonorLabels, - cr.Spec.OverrideHonorTimestamps, - cr.Spec.EnforcedNamespaceLabel)) + cr.Spec.VMAgentSecurityEnforcements, + )) } for _, identifier := range staticsIdentifiers { @@ -1032,9 +1041,7 @@ func generateConfig( statics[identifier], ep, i, secretsCache, - cr.Spec.OverrideHonorLabels, - cr.Spec.OverrideHonorTimestamps, - cr.Spec.EnforcedNamespaceLabel, + cr.Spec.VMAgentSecurityEnforcements, )) } } @@ -1046,7 +1053,7 @@ func generateConfig( cr, scrapeConfs[identifier], secretsCache, - cr.Spec.EnforcedNamespaceLabel, + cr.Spec.VMAgentSecurityEnforcements, )) } @@ -1345,7 +1352,7 @@ func generateK8SSDConfig(namespaces []string, apiserverConfig *vmv1beta1.APIServ } } if apiserverConfig.Authorization != nil { - k8sSDConfig = addAuthorizationConfig(k8sSDConfig, "apiserver", apiserverConfig.Authorization, ssCache.authorizationSecrets) + k8sSDConfig = addAuthorizationConfigTo(k8sSDConfig, "apiserver", apiserverConfig.Authorization, ssCache.authorizationSecrets) } if apiserverConfig.BearerToken != "" { @@ -1420,8 +1427,6 @@ func buildVMScrapeParams(namespace, cacheKey string, cfg *vmv1beta1.VMScrapePara toYaml("scrape_offset", cfg.ScrapeOffset) toYaml("no_stale_markers", cfg.DisableStaleMarkers) toYaml("disable_keepalive", cfg.DisableKeepAlive) - toYaml("relabel_debug", cfg.RelabelDebug) - toYaml("metric_relabel_debug", cfg.MetricRelabelDebug) if len(cfg.Headers) > 0 { r = append(r, yaml.MapItem{Key: "headers", Value: cfg.Headers}) } @@ -1431,7 +1436,7 @@ func buildVMScrapeParams(namespace, cacheKey string, cfg *vmv1beta1.VMScrapePara return r } -func addAuthorizationConfig(dst yaml.MapSlice, cacheKey string, cfg *vmv1beta1.Authorization, authorizationCache map[string]string) yaml.MapSlice { +func addAuthorizationConfigTo(dst yaml.MapSlice, cacheKey string, cfg *vmv1beta1.Authorization, authorizationCache map[string]string) yaml.MapSlice { if cfg == nil { // fast path return dst @@ -1456,7 +1461,7 @@ func addAuthorizationConfig(dst yaml.MapSlice, cacheKey string, cfg *vmv1beta1.A return dst } -func addOAuth2Config(dst yaml.MapSlice, cacheKey string, cfg *vmv1beta1.OAuth2, oauth2Cache map[string]*k8stools.OAuthCreds) yaml.MapSlice { +func addOAuth2ConfigTo(dst yaml.MapSlice, cacheKey string, cfg *vmv1beta1.OAuth2, oauth2Cache map[string]*k8stools.OAuthCreds) yaml.MapSlice { cachedSecret := oauth2Cache[cacheKey] if cfg == nil || cachedSecret == nil { // fast path @@ -1522,3 +1527,157 @@ func buildProxyAuthConfig(namespace, cacheKey string, proxyAuth *vmv1beta1.Proxy } return r } + +func addSelectorToRelabelingFor(relabelings []yaml.MapSlice, typeName string, selector metav1.LabelSelector) []yaml.MapSlice { + // Exact label matches. + var labelKeys []string + for k := range selector.MatchLabels { + labelKeys = append(labelKeys, k) + } + sort.Strings(labelKeys) + + for _, k := range labelKeys { + relabelings = append(relabelings, yaml.MapSlice{ + {Key: "action", Value: "keep"}, + {Key: "source_labels", Value: []string{fmt.Sprintf("__meta_kubernetes_%s_label_%s", typeName, sanitizeLabelName(k))}}, + {Key: "regex", Value: selector.MatchLabels[k]}, + }) + } + // Set based label matching. We have to map the valid relations + // `In`, `NotIn`, `Exists`, and `DoesNotExist`, into relabeling rules. + for _, exp := range selector.MatchExpressions { + switch exp.Operator { + case metav1.LabelSelectorOpIn: + relabelings = append(relabelings, yaml.MapSlice{ + {Key: "action", Value: "keep"}, + {Key: "source_labels", Value: []string{fmt.Sprintf("__meta_kubernetes_%s_label_%s", typeName, sanitizeLabelName(exp.Key))}}, + {Key: "regex", Value: strings.Join(exp.Values, "|")}, + }) + case metav1.LabelSelectorOpNotIn: + relabelings = append(relabelings, yaml.MapSlice{ + {Key: "action", Value: "drop"}, + {Key: "source_labels", Value: []string{fmt.Sprintf("__meta_kubernetes_%s_label_%s", typeName, sanitizeLabelName(exp.Key))}}, + {Key: "regex", Value: strings.Join(exp.Values, "|")}, + }) + case metav1.LabelSelectorOpExists: + relabelings = append(relabelings, yaml.MapSlice{ + {Key: "action", Value: "keep"}, + {Key: "source_labels", Value: []string{fmt.Sprintf("__meta_kubernetes_%s_labelpresent_%s", typeName, sanitizeLabelName(exp.Key))}}, + {Key: "regex", Value: "true"}, + }) + case metav1.LabelSelectorOpDoesNotExist: + relabelings = append(relabelings, yaml.MapSlice{ + {Key: "action", Value: "drop"}, + {Key: "source_labels", Value: []string{fmt.Sprintf("__meta_kubernetes_%s_labelpresent_%s", typeName, sanitizeLabelName(exp.Key))}}, + {Key: "regex", Value: "true"}, + }) + } + } + return relabelings +} + +func addCommonScrapeParamsTo(cfg yaml.MapSlice, cs vmv1beta1.EndpointScrapeParams, se vmv1beta1.VMAgentSecurityEnforcements) yaml.MapSlice { + hl := honorLabels(cs.HonorLabels, se.OverrideHonorLabels) + cfg = append(cfg, yaml.MapItem{ + Key: "honor_labels", + Value: hl, + }) + + cfg = honorTimestamps(cfg, cs.HonorTimestamps, se.OverrideHonorTimestamps) + + if cs.ScrapeInterval != "" { + cfg = append(cfg, yaml.MapItem{Key: "scrape_interval", Value: cs.ScrapeInterval}) + } + if cs.ScrapeTimeout != "" { + cfg = append(cfg, yaml.MapItem{Key: "scrape_timeout", Value: cs.ScrapeTimeout}) + } + if cs.Path != "" { + cfg = append(cfg, yaml.MapItem{Key: "metrics_path", Value: cs.Path}) + } + if cs.ProxyURL != nil { + cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: cs.ProxyURL}) + } + if cs.FollowRedirects != nil { + cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: cs.FollowRedirects}) + } + if cs.Params != nil && len(cs.Params) > 0 { + params := make(yaml.MapSlice, 0, len(cs.Params)) + paramIdxes := make([]string, len(cs.Params)) + var idxCnt int + for k := range cs.Params { + paramIdxes[idxCnt] = k + idxCnt++ + } + sort.Strings(paramIdxes) + for _, k := range paramIdxes { + params = append(params, yaml.MapItem{Key: k, Value: cs.Params[k]}) + } + cfg = append(cfg, yaml.MapItem{Key: "params", Value: params}) + } + if cs.Scheme != "" { + cfg = append(cfg, yaml.MapItem{Key: "scheme", Value: cs.Scheme}) + } + if cs.MaxScrapeSize != "" { + cfg = append(cfg, yaml.MapItem{Key: "max_scrape_size", Value: cs.MaxScrapeSize}) + } + if cs.SampleLimit > 0 { + cfg = append(cfg, yaml.MapItem{Key: "sample_limit", Value: cs.SampleLimit}) + } + if cs.SeriesLimit > 0 { + cfg = append(cfg, yaml.MapItem{Key: "series_limit", Value: cs.SeriesLimit}) + } + return cfg +} + +func addMetricRelabelingsTo(cfg yaml.MapSlice, src []*vmv1beta1.RelabelConfig, se vmv1beta1.VMAgentSecurityEnforcements) yaml.MapSlice { + if len(src) == 0 { + return cfg + } + var metricRelabelings []yaml.MapSlice + for _, c := range src { + if c.TargetLabel != "" && se.EnforcedNamespaceLabel != "" && c.TargetLabel == se.EnforcedNamespaceLabel { + continue + } + relabeling := generateRelabelConfig(c) + + metricRelabelings = append(metricRelabelings, relabeling) + } + if len(metricRelabelings) == 0 { + return cfg + } + cfg = append(cfg, yaml.MapItem{Key: "metric_relabel_configs", Value: metricRelabelings}) + return cfg +} + +func addEndpointAuthTo(cfg yaml.MapSlice, ac vmv1beta1.EndpointAuth, key string, ssCache *scrapesSecretsCache) yaml.MapSlice { + if ac.BearerTokenFile != "" { + cfg = append(cfg, yaml.MapItem{Key: "bearer_token_file", Value: ac.BearerTokenFile}) + } + + if ac.BearerTokenSecret != nil && ac.BearerTokenSecret.Name != "" { + if s, ok := ssCache.bearerTokens[key]; ok { + cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) + } + } + if ac.BasicAuth != nil { + var bac yaml.MapSlice + if s, ok := ssCache.baSecrets[key]; ok { + bac = append(bac, + yaml.MapItem{Key: "username", Value: s.Username}, + ) + if len(s.Password) > 0 { + bac = append(bac, yaml.MapItem{Key: "password", Value: s.Password}) + } + } + if len(ac.BasicAuth.PasswordFile) > 0 { + bac = append(bac, yaml.MapItem{Key: "password_file", Value: ac.BasicAuth.PasswordFile}) + } + if len(bac) > 0 { + cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: bac}) + } + } + cfg = addOAuth2ConfigTo(cfg, key, ac.OAuth2, ssCache.oauth2Secrets) + cfg = addAuthorizationConfigTo(cfg, key, ac.Authorization, ssCache.authorizationSecrets) + + return cfg +} diff --git a/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig_test.go b/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig_test.go index dd962889..aab06ad1 100644 --- a/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig_test.go +++ b/internal/controller/operator/factory/vmagent/vmagent_scrapeconfig_test.go @@ -241,17 +241,23 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { - Path: "/metrics", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics", + }, Port: "8085", - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, { - Path: "/metrics-2", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-2", + }, Port: "8083", }, }, @@ -291,31 +297,34 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { SampleLimit: 10, PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { - Path: "/metrics-3", Port: "805", - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - KeySecret: &corev1.SecretKeySelector{ - Key: "key", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", - }, - }, - Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-3", + + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + StreamParse: ptr.To(true), + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + KeySecret: &corev1.SecretKeySelector{ + Key: "key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, - }}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", + Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ + Key: "cert", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-creds", }, + }}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, + }, }, }, }, @@ -324,27 +333,31 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { }, { Port: "801", - Path: "/metrics-5", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - KeySecret: &corev1.SecretKeySelector{ - Key: "key", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", - }, - }, - Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-5", + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + KeySecret: &corev1.SecretKeySelector{ + Key: "key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, - }}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", + Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ + Key: "cert", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-creds", }, + }}, + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, + }, }, }, }, @@ -358,17 +371,19 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { Name: "test-vms", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -382,25 +397,28 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { Spec: vmv1beta1.VMStaticScrapeSpec{ TargetEndpoints: []*vmv1beta1.TargetEndpoint{ { - Path: "/metrics-3", - Port: "3031", - Scheme: "https", - ProxyURL: ptr.To("https://some-proxy-1"), - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "https://some-tr", - ClientSecret: &corev1.SecretKeySelector{ - Key: "cs", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", - }, - }, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cid", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-3", + Scheme: "https", + ProxyURL: ptr.To("https://some-proxy-1"), + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "https://some-tr", + ClientSecret: &corev1.SecretKeySelector{ + Key: "cs", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-creds", }, }, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cid", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, + }, + }, }, }, }, @@ -430,14 +448,13 @@ func TestCreateOrUpdateConfigurationSecret(t *testing.T) { prometheus: default/test scrape_configs: - job_name: serviceScrape/default/test-vms/0 - honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default + honor_labels: false metrics_path: /metrics - bearer_token: some-bearer relabel_configs: - action: keep source_labels: @@ -480,13 +497,14 @@ scrape_configs: replacement: ${1} - target_label: endpoint replacement: "8085" + bearer_token: some-bearer - job_name: serviceScrape/default/test-vms/1 - honor_labels: false kubernetes_sd_configs: - role: endpoints namespaces: names: - default + honor_labels: false metrics_path: /metrics-2 relabel_configs: - action: keep @@ -531,13 +549,14 @@ scrape_configs: - target_label: endpoint replacement: "8083" - job_name: podScrape/default/test-vps/0 - honor_labels: false kubernetes_sd_configs: - role: pod namespaces: names: - default + honor_labels: false metrics_path: /metrics-3 + sample_limit: 10 relabel_configs: - action: drop source_labels: @@ -569,7 +588,6 @@ scrape_configs: replacement: ${1} - target_label: endpoint replacement: "805" - sample_limit: 10 stream_parse: true proxy_tls_config: insecure_skip_verify: true @@ -577,18 +595,14 @@ scrape_configs: cert_file: /etc/vmagent-tls/certs/default_access-creds_cert key_file: /etc/vmagent-tls/certs/default_access-creds_key - job_name: podScrape/default/test-vps/1 - honor_labels: false kubernetes_sd_configs: - role: pod namespaces: names: - default + honor_labels: false metrics_path: /metrics-5 - tls_config: - insecure_skip_verify: true - ca_file: /etc/vmagent-tls/certs/default_access-creds_ca - cert_file: /etc/vmagent-tls/certs/default_access-creds_cert - key_file: /etc/vmagent-tls/certs/default_access-creds_key + sample_limit: 10 relabel_configs: - action: drop source_labels: @@ -620,11 +634,13 @@ scrape_configs: replacement: ${1} - target_label: endpoint replacement: "801" - sample_limit: 10 + tls_config: + insecure_skip_verify: true + ca_file: /etc/vmagent-tls/certs/default_access-creds_ca + cert_file: /etc/vmagent-tls/certs/default_access-creds_cert + key_file: /etc/vmagent-tls/certs/default_access-creds_key - job_name: probe/kube-system/test-vmp/0 - params: - module: - - "" + honor_labels: false metrics_path: /probe static_configs: - targets: @@ -639,22 +655,22 @@ scrape_configs: - target_label: __address__ replacement: http://blackbox - job_name: nodeScrape/default/test-vms/0 - honor_labels: false kubernetes_sd_configs: - role: node - basic_auth: - username: some-username - password: some-password + honor_labels: false relabel_configs: - source_labels: - __meta_kubernetes_node_name target_label: node - target_label: job replacement: default/test-vms + basic_auth: + username: some-username + password: some-password - job_name: staticScrape/default/test-vmstatic/0 - honor_labels: false static_configs: - targets: [] + honor_labels: false metrics_path: /metrics-3 proxy_url: https://some-proxy-1 scheme: https @@ -702,17 +718,19 @@ scrape_configs: Name: "test-bad-0", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -733,10 +751,12 @@ scrape_configs: Name: "bad-1", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -761,15 +781,17 @@ scrape_configs: SampleLimit: 10, PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { - Path: "/metrics-3", Port: "805", - VMScrapeParams: &vmv1beta1.VMScrapeParams{ - StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ - BearerToken: &corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-3", + VMScrapeParams: &vmv1beta1.VMScrapeParams{ + StreamParse: ptr.To(true), + ProxyClientConfig: &vmv1beta1.ProxyAuth{ + BearerToken: &corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -777,25 +799,31 @@ scrape_configs: }, { Port: "801", - Path: "/metrics-5", - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-5", + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, }, { Port: "801", - Path: "/metrics-5-good", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-5-good", + }, }, }, }, @@ -820,7 +848,9 @@ scrape_configs: PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { Port: "8011", - Path: "/metrics-1-good", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-1-good", + }, }, }, }, @@ -833,25 +863,28 @@ scrape_configs: Spec: vmv1beta1.VMStaticScrapeSpec{ TargetEndpoints: []*vmv1beta1.TargetEndpoint{ { - Path: "/metrics-3", - Port: "3031", - Scheme: "https", - ProxyURL: ptr.To("https://some-proxy-1"), - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "https://some-tr", - ClientSecret: &corev1.SecretKeySelector{ - Key: "cs", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", - }, - }, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cid", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-3", + Scheme: "https", + ProxyURL: ptr.To("https://some-proxy-1"), + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "https://some-tr", + ClientSecret: &corev1.SecretKeySelector{ + Key: "cs", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-creds", }, }, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cid", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, + }, + }, }, }, }, @@ -866,16 +899,19 @@ scrape_configs: Spec: vmv1beta1.VMStaticScrapeSpec{ TargetEndpoints: []*vmv1beta1.TargetEndpoint{ { - Path: "/metrics-3", - Port: "3031", - Scheme: "https", - ProxyURL: ptr.To("https://some-proxy-1"), - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Path: "/metrics-3", + Scheme: "https", + ProxyURL: ptr.To("https://some-proxy-1"), + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cert", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-creds", + }, }, }, }, @@ -891,12 +927,12 @@ scrape_configs: prometheus: default/test scrape_configs: - job_name: podScrape/default/test-vps-good/0 - honor_labels: false kubernetes_sd_configs: - role: pod namespaces: names: - default + honor_labels: false metrics_path: /metrics-1-good relabel_configs: - action: drop @@ -930,13 +966,14 @@ scrape_configs: - target_label: endpoint replacement: "8011" - job_name: podScrape/default/test-vps-mixed/0 - honor_labels: false kubernetes_sd_configs: - role: pod namespaces: names: - default + honor_labels: false metrics_path: /metrics-5-good + sample_limit: 10 relabel_configs: - action: drop source_labels: @@ -968,11 +1005,10 @@ scrape_configs: replacement: ${1} - target_label: endpoint replacement: "801" - sample_limit: 10 - job_name: nodeScrape/default/test-good/0 - honor_labels: false kubernetes_sd_configs: - role: node + honor_labels: false relabel_configs: - source_labels: - __meta_kubernetes_node_name diff --git a/internal/controller/operator/factory/vmagent/vmagent_test.go b/internal/controller/operator/factory/vmagent/vmagent_test.go index 2b73ebfd..9ac84270 100644 --- a/internal/controller/operator/factory/vmagent/vmagent_test.go +++ b/internal/controller/operator/factory/vmagent/vmagent_test.go @@ -170,11 +170,15 @@ func TestCreateOrUpdateVMAgent(t *testing.T) { Selector: metav1.LabelSelector{}, Endpoints: []vmv1beta1.Endpoint{ { - Interval: "30s", - Scheme: "http", - BasicAuth: &vmv1beta1.BasicAuth{ - Password: corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "bauth-secret"}, Key: "password"}, - Username: corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "bauth-secret"}, Key: "user"}, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Interval: "30s", + Scheme: "http", + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Password: corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "bauth-secret"}, Key: "password"}, + Username: corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "bauth-secret"}, Key: "user"}, + }, }, }, }, @@ -310,16 +314,20 @@ func TestCreateOrUpdateVMAgent(t *testing.T) { Selector: metav1.LabelSelector{}, Endpoints: []vmv1beta1.Endpoint{ { - Interval: "30s", - Scheme: "https", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "ca"}, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "ca"}, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + Interval: "30s", + Scheme: "https", + }, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "ca"}, + }, + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "ca"}, + }, + KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "key"}, }, - KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "tls-scrape"}, Key: "key"}, }, }, }, @@ -476,12 +484,14 @@ func Test_loadTLSAssets(t *testing.T) { Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - TLSConfig: &vmv1beta1.TLSConfig{ - KeySecret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + KeySecret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "cert", }, - Key: "cert", }, }, }, @@ -549,14 +559,18 @@ func Test_loadTLSAssets(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "vmagent-monitor", Namespace: "default"}, Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ - {TLSConfig: &vmv1beta1.TLSConfig{ - KeySecret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + { + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + KeySecret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + Key: "cert", + }, }, - Key: "cert", }, - }}, + }, }, }, },