From 7ae22db11fef50b2e11c80a5074452048c0cb655 Mon Sep 17 00:00:00 2001 From: Andrii Chubatiuk Date: Sat, 21 Feb 2026 16:14:55 +0200 Subject: [PATCH 1/5] scrapeconfig: support more discovery mechanisms --- .../v1beta1/vmalertmanagerconfig_types.go | 26 +- api/operator/v1beta1/vmscrapeconfig_types.go | 256 +- api/operator/v1beta1/zz_generated.deepcopy.go | 392 +- config/crd/overlay/crd.descriptionless.yaml | 3462 +++++++++-- config/crd/overlay/crd.yaml | 5456 ++++++++++++++--- docs/CHANGELOG.md | 1 + docs/api.md | 187 +- .../operator/factory/converter/apis.go | 9 + .../factory/converter/v1alpha1/apis.go | 4 +- .../factory/converter/v1alpha1/apis_test.go | 74 +- .../operator/factory/vmagent/scrapes_test.go | 66 +- .../operator/factory/vmalertmanager/config.go | 42 +- .../factory/vmalertmanager/config_test.go | 34 + .../factory/vmscrapes/scrapeconfig.go | 574 +- .../factory/vmscrapes/scrapeconfig_test.go | 422 +- .../operator/factory/vmsingle/scrapes_test.go | 24 +- 16 files changed, 8919 insertions(+), 2110 deletions(-) diff --git a/api/operator/v1beta1/vmalertmanagerconfig_types.go b/api/operator/v1beta1/vmalertmanagerconfig_types.go index 65ac5d0a6..3f7dc6bb7 100644 --- a/api/operator/v1beta1/vmalertmanagerconfig_types.go +++ b/api/operator/v1beta1/vmalertmanagerconfig_types.go @@ -1196,9 +1196,6 @@ type HTTPConfig struct { // TLS configuration for the client. // +optional TLSConfig *TLSConfig `json:"tls_config,omitempty" yaml:"tls_config,omitempty"` - // Optional proxy URL. - // +optional - ProxyURL string `json:"proxyURL,omitempty" yaml:"proxy_url,omitempty"` // Authorization header configuration for the client. // This is mutually exclusive with BasicAuth and is only available starting from Alertmanager v0.22+. // +optional @@ -1206,6 +1203,29 @@ type HTTPConfig struct { // OAuth2 client credentials used to fetch a token for the targets. // +optional OAuth2 *OAuth2 `json:"oauth2,omitempty"` + // FollowRedirects controls redirects for scraping. + // +optional + FollowRedirects *bool `json:"follow_redirects,omitempty"` + // +optional + ProxyConfig `json:",inline"` +} + +// ProxyConfig defines proxy configs +type ProxyConfig struct { + // ProxyUrl defines the HTTP proxy server to use. + // +kubebuilder:validation:Pattern:="^(http|https|socks5)://.+$" + // +optional + ProxyURL string `json:"proxyURL,omitempty" yaml:"proxy_url,omitempty"` + // NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + // IP and domain names can contain port numbers. + // +optional + NoProxy string `json:"noProxy,omitempty" yaml:"no_proxy,omitempty"` + // ProxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + // +optional + ProxyFromEnvironment bool `json:"proxyFromEnvironment,omitempty" yaml:"proxy_from_environment,omitempty"` + // ProxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. + // +optional + ProxyConnectHeader map[string][]corev1.SecretKeySelector `json:"proxyConnectHeader,omitempty" yaml:"proxy_connect_header,omitempty"` } // UnmarshalJSON implements json.Unmarshaller interface diff --git a/api/operator/v1beta1/vmscrapeconfig_types.go b/api/operator/v1beta1/vmscrapeconfig_types.go index 983305512..d0b3b2706 100644 --- a/api/operator/v1beta1/vmscrapeconfig_types.go +++ b/api/operator/v1beta1/vmscrapeconfig_types.go @@ -82,7 +82,25 @@ type VMScrapeConfigSpec struct { DigitalOceanSDConfigs []DigitalOceanSDConfig `json:"digitalOceanSDConfigs,omitempty"` // NomadSDConfigs defines a list of Nomad service discovery configurations. // +optional - NomadSDConfigs []NomadSDConfig `json:"nomadSDConfigs,omitempty"` + NomadSDConfigs []NomadSDConfig `json:"nomadSDConfigs,omitempty"` + // KumaSDConfigs defines a list of Kuma service discovery configurations. + // +optional + KumaSDConfigs []KumaSDConfig `json:"kumaSDConfigs,omitempty"` + // OVHCloudSDConfigs defines a list of OVH Cloud service discovery configurations. + // +optional + OVHCloudSDConfigs []OVHCloudSDConfig `json:"ovhcloudSDConfigs,omitempty"` + // PuppetDBSDConfigs defines a list of PuppetDB service discovery configurations. + // +optional + PuppetDBSDConfigs []PuppetDBSDConfig `json:"puppetDBSDConfigs,omitempty"` + // VultrSDConfigs defines a list of Vultr service discovery configurations. + // +optional + VultrSDConfigs []VultrSDConfig `json:"vultrSDConfigs,omitempty"` + // HetznerSDConfigs defines a list of Hetzner service discovery configurations. + // +optional + HetznerSDConfigs []HetznerSDConfig `json:"hetznerSDConfigs,omitempty"` + // EurekaSDConfigs defines a list of Eureka service discovery configurations. + // +optional + EurekaSDConfigs []EurekaSDConfig `json:"eurekaSDConfigs,omitempty"` EndpointScrapeParams `json:",inline"` EndpointRelabelings `json:",inline"` EndpointAuth `json:",inline"` @@ -121,19 +139,18 @@ type FileSDConfig struct { Files []string `json:"files"` } -// HTTPSDConfig defines a HTTP service discovery configuration. -// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http_sd_configs) -type HTTPSDConfig struct { - // URL from which the targets are fetched. - // +kubebuilder:validation:MinLength:=1 - // +kubebuilder:validation:Pattern:="^http(s)?://.+$" - URL string `json:"url"` +// HTTPSDOptions defines HTTP API client options +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http-api-client-options) +type HTTPSDOptions struct { + // Authorization header to use on every scrape request. + // +optional + Authorization *Authorization `json:"authorization,omitempty"` // BasicAuth information to use on every scrape request. // +optional BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // Authorization header to use on every scrape request. + // OAuth2 defines auth configuration // +optional - Authorization *Authorization `json:"authorization,omitempty"` + OAuth2 *OAuth2 `json:"oauth2,omitempty"` // TLS configuration to use on every scrape request // +optional TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` @@ -144,6 +161,19 @@ type HTTPSDConfig struct { // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) // +optional ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` + // Configure whether HTTP requests follow HTTP 3xx redirects. + // +optional + FollowRedirects *bool `json:"followRedirects,omitempty"` +} + +// HTTPSDConfig defines a HTTP service discovery configuration. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http_sd_configs) +type HTTPSDConfig struct { + // URL from which the targets are fetched. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:Pattern:="^http(s)?://.+$" + URL string `json:"url"` + HTTPSDOptions `json:",inline"` } // KubernetesSDConfig allows retrieving scrape targets from Kubernetes' REST API. @@ -161,28 +191,6 @@ type KubernetesSDConfig struct { // +kubebuilder:validation:Enum=node;pod;service;endpoints;endpointslice;ingress // +required Role string `json:"role"` - // 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"` - // TLS configuration to use on every scrape request - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // ProxyClientConfig configures proxy auth settings for scraping - // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) - // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` - // Configure whether HTTP requests follow HTTP 3xx redirects. - // +optional - FollowRedirects *bool `json:"followRedirects,omitempty"` // Optional namespace discovery. If omitted, discover targets across all namespaces. // +optional Namespaces *NamespaceDiscovery `json:"namespaces,omitempty"` @@ -193,7 +201,8 @@ type KubernetesSDConfig struct { // +optional // +listType=map // +listMapKey=role - Selectors []K8SSelectorConfig `json:"selectors,omitempty"` + Selectors []K8SSelectorConfig `json:"selectors,omitempty"` + HTTPSDOptions `json:",inline"` } // K8SSelectorConfig is Kubernetes Selector Config @@ -264,30 +273,8 @@ type ConsulSDConfig struct { // Filter defines filter for /v1/catalog/services requests // See https://developer.hashicorp.com/consul/api-docs/features/filtering // +optional - Filter string `json:"filter,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"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // ProxyClientConfig configures proxy auth settings for scraping - // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) - // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` - // Configure whether HTTP requests follow HTTP 3xx redirects. - // If unset, use its default value. - // +optional - FollowRedirects *bool `json:"followRedirects,omitempty"` - // TLS configuration to use on every scrape request - // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + Filter string `json:"filter,omitempty"` + HTTPSDOptions `json:",inline"` } // DNSSDConfig allows specifying a set of DNS domain names which are periodically queried to discover a list of targets. @@ -308,7 +295,7 @@ type DNSSDConfig struct { // The port number used if the query type is not SRV // Ignored for SRV records // +optional - Port *int `json:"port"` + Port *int32 `json:"port"` } // EC2SDConfig allow retrieving scrape targets from AWS EC2 instances. @@ -332,7 +319,7 @@ type EC2SDConfig struct { // The port to scrape metrics from. If using the public IP address, this must // instead be specified in the relabeling rule. // +optional - Port *int `json:"port"` + Port *int32 `json:"port"` // Filters can be used optionally to filter the instance list by other criteria. // Available filter criteria can be found here: // https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html @@ -378,7 +365,8 @@ type AzureSDConfig struct { // The port to scrape metrics from. If using the public IP address, this must // instead be specified in the relabeling rule. // +optional - Port *int `json:"port"` + Port *int32 `json:"port"` + HTTPSDOptions `json:",inline"` } // GCESDConfig configures scrape targets from GCP GCE instances. @@ -408,7 +396,7 @@ type GCESDConfig struct { // The port to scrape metrics from. If using the public IP address, this must // instead be specified in the relabeling rule. // +optional - Port *int `json:"port"` + Port *int32 `json:"port"` // The tag separator is used to separate the tags on concatenation // +optional TagSeparator *string `json:"tagSeparator,omitempty"` @@ -479,7 +467,7 @@ type OpenStackSDConfig struct { // The port to scrape metrics from. If using the public IP address, this must // instead be specified in the relabeling rule. // +optional - Port *int `json:"port"` + Port *int32 `json:"port"` // Availability of the endpoint to connect to. // +kubebuilder:validation:Enum=Public;public;Admin;admin;Internal;internal // +optional @@ -494,28 +482,14 @@ type OpenStackSDConfig struct { // See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#digitalocean_sd_configs) // +k8s:openapi-gen=true type DigitalOceanSDConfig struct { - // Authorization header to use on every scrape request. - // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // OAuth2 defines auth configuration - // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. - // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // ProxyClientConfig configures proxy auth settings for scraping - // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) - // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` - // Configure whether HTTP requests follow HTTP 3xx redirects. - // +optional - FollowRedirects *bool `json:"followRedirects,omitempty"` - // TLS configuration to use on every scrape request + // Server is an optional DigitalOcean API server to query. + // By default, https://api.digitalocean.com is used. // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` + Server string `json:"server,omitempty"` // The port to scrape metrics from. // +optional - Port *int `json:"port,omitempty"` + Port *int32 `json:"port,omitempty"` + HTTPSDOptions `json:",inline"` } // NomadSDConfig configurations allow retrieving scrape targets from Nomad's Service API. @@ -539,29 +513,117 @@ type NomadSDConfig struct { // Allow stale Nomad results to reduce load on Nomad. // If unset, use its default value. // +optional - AllowStale *bool `json:"allowStale,omitempty"` - // BasicAuth information to use on every scrape request. + AllowStale *bool `json:"allowStale,omitempty"` + HTTPSDOptions `json:",inline"` +} + +// KumaSDConfig configurations allows retrieving scrape targets from Kuma control plane. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#kuma_sd_configs) +// +k8s:openapi-gen=true +type KumaSDConfig struct { + // Server must contain the URL of Kuma Control Plane's MADS xDS server. + // +kubebuilder:validation:MinLength=1 + // +required + Server string `json:"server"` + // ClientID is an optional client ID to send to Kuma Control Plane. + // The hostname of the server where vmagent runs is used if it isn't set. + // If the hostname is empty, then "vmagent" string is used as client_id. // +optional - BasicAuth *BasicAuth `json:"basicAuth,omitempty"` - // Authorization header to use on every scrape request. + ClientID string `json:"clientID"` + HTTPSDOptions `json:",inline"` +} + +// OVHCloudSDConfig configurations allows retrieving scrape targets from OVH Cloud VPS and OVH Cloud dedicated server. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#ovhcloud_sd_configs) +// +k8s:openapi-gen=true +type OVHCloudSDConfig struct { + // Endpoint defines OVH Cloud endpoint // +optional - Authorization *Authorization `json:"authorization,omitempty"` - // OAuth2 defines auth configuration + Endpoint string `json:"endpoint,omitempty"` + // ApplicationKey defines a self generated token. + // +kubebuilder:validation:MinLength=1 + // +required + ApplicationKey string `json:"applicationKey"` + // ApplicationSecret defines a generated secret. + // +required + ApplicationSecret *corev1.SecretKeySelector `json:"applicationSecret"` + // ConsumerKey holds user/app specific token + // +required + ConsumerKey *corev1.SecretKeySelector `json:"consumerKey"` + // Service could be either `vps` or `dedicated_server` + // +kubebuilder:validation:Enum=vps;VPS;dedicated_server;DedicatedServer + // +required + Service string `json:"service"` + HTTPSDOptions `json:",inline"` +} + +// PuppetDBSDConfig configurations allows retrieving scrape targets from PuppetDB resources. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#puppetdb_sd_configs) +// +k8s:openapi-gen=true +type PuppetDBSDConfig struct { + // URL of the PuppetDB root query endpoint + // +required + URL string `json:"url"` + // Query defines PQL query that allows to filter discovered resources. + // +required + Query string `json:"query"` + // IncludeParameters defines if parameters should be included as meta labels. // +optional - OAuth2 *OAuth2 `json:"oauth2,omitempty"` - // TLS configuration to use on every scrape request + IncludeParameters bool `json:"includeParameters,omitempty"` + // Port defines port to scrape metrics from // +optional - TLSConfig *TLSConfig `json:"tlsConfig,omitempty"` - // ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. + Port *int32 `json:"port,omitempty"` + HTTPSDOptions `json:",inline"` +} + +// VultrSDConfig configurations allows retrieving scrape targets from Vultr instances. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#vultr_sd_configs) +// +k8s:openapi-gen=true +type VultrSDConfig struct { + // Label is an optional query arguments to filter instances by label. // +optional - ProxyURL *string `json:"proxyURL,omitempty"` - // ProxyClientConfig configures proxy auth settings for scraping - // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + Label string `json:"label,omitempty"` + // MainIP is an optional query arguments to filter instances by main ip address. // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` - // Configure whether HTTP requests follow HTTP 3xx redirects. + MainIP string `json:"mainIP,omitempty"` + // Region is an optional query arguments to filter instances by region id. // +optional - FollowRedirects *bool `json:"followRedirects,omitempty"` + Region string `json:"region,omitempty"` + // FirewallGroupID is an optional query arguments to filter instances by firewall group id. + // +optional + FirewallGroupID string `json:"firewallGroupID,omitempty"` + // Hostname is an optional query arguments to filter instances by hostname. + // +optional + Hostname string `json:"hostname,omitempty"` + // Port is an optional port to scrape metrics from. + // +optional + Port *int32 `json:"port,omitempty"` + HTTPSDOptions `json:",inline"` +} + +// HetznerSDConfig configurations allows retrieving scrape targets from Hetzner Cloud and Hetzner Robot. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#hetzner_sd_configs) +// +k8s:openapi-gen=true +type HetznerSDConfig struct { + // Role defines mandatory Hetzner role for entity discovery. + // +required + // +kubebuilder:validation:Enum=robot;Robot;hcloud;Cloud + Role string `json:"role"` + // Port is an optional port to scrape metrics from + // +optional + Port *int32 `json:"port,omitempty"` + HTTPSDOptions `json:",inline"` +} + +// EurekaSDConfig configurations allows retrieving scrape targets from Eureka REST API. +// See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#eureka_sd_configs) +// +k8s:openapi-gen=true +type EurekaSDConfig struct { + // Server is an optional URL to connect to the Eureka server. + // By default, the http://localhost:8080/eureka/v2 is used. + // +optional + Server string `json:"server,omitempty"` + HTTPSDOptions `json:",inline"` } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/api/operator/v1beta1/zz_generated.deepcopy.go b/api/operator/v1beta1/zz_generated.deepcopy.go index 597226e99..ddb397ccf 100644 --- a/api/operator/v1beta1/zz_generated.deepcopy.go +++ b/api/operator/v1beta1/zz_generated.deepcopy.go @@ -191,9 +191,10 @@ func (in *AzureSDConfig) DeepCopyInto(out *AzureSDConfig) { } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureSDConfig. @@ -851,41 +852,7 @@ func (in *ConsulSDConfig) DeepCopyInto(out *ConsulSDConfig) { *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) - } - if in.OAuth2 != nil { - in, out := &in.OAuth2, &out.OAuth2 - *out = new(OAuth2) - (*in).DeepCopyInto(*out) - } - if in.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.ProxyClientConfig != nil { - in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) - (*in).DeepCopyInto(*out) - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsulSDConfig. @@ -953,7 +920,7 @@ func (in *DNSSDConfig) DeepCopyInto(out *DNSSDConfig) { } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } } @@ -971,41 +938,12 @@ func (in *DNSSDConfig) DeepCopy() *DNSSDConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DigitalOceanSDConfig) DeepCopyInto(out *DigitalOceanSDConfig) { *out = *in - 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.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.ProxyClientConfig != nil { - in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) - (*in).DeepCopyInto(*out) - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(TLSConfig) - (*in).DeepCopyInto(*out) - } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DigitalOceanSDConfig. @@ -1123,7 +1061,7 @@ func (in *EC2SDConfig) DeepCopyInto(out *EC2SDConfig) { } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } if in.Filters != nil { @@ -1576,6 +1514,22 @@ func (in *EndpointScrapeParams) DeepCopy() *EndpointScrapeParams { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EurekaSDConfig) DeepCopyInto(out *EurekaSDConfig) { + *out = *in + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EurekaSDConfig. +func (in *EurekaSDConfig) DeepCopy() *EurekaSDConfig { + if in == nil { + return nil + } + out := new(EurekaSDConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExternalConfig) DeepCopyInto(out *ExternalConfig) { *out = *in @@ -1631,7 +1585,7 @@ func (in *GCESDConfig) DeepCopyInto(out *GCESDConfig) { } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } if in.TagSeparator != nil { @@ -1719,6 +1673,12 @@ func (in *HTTPConfig) DeepCopyInto(out *HTTPConfig) { *out = new(OAuth2) (*in).DeepCopyInto(*out) } + if in.FollowRedirects != nil { + in, out := &in.FollowRedirects, &out.FollowRedirects + *out = new(bool) + **out = **in + } + in.ProxyConfig.DeepCopyInto(&out.ProxyConfig) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPConfig. @@ -1734,14 +1694,35 @@ func (in *HTTPConfig) DeepCopy() *HTTPConfig { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPSDConfig) DeepCopyInto(out *HTTPSDConfig) { *out = *in + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPSDConfig. +func (in *HTTPSDConfig) DeepCopy() *HTTPSDConfig { + if in == nil { + return nil + } + out := new(HTTPSDConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPSDOptions) DeepCopyInto(out *HTTPSDOptions) { + *out = *in + if in.Authorization != nil { + in, out := &in.Authorization, &out.Authorization + *out = new(Authorization) + (*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) + if in.OAuth2 != nil { + in, out := &in.OAuth2, &out.OAuth2 + *out = new(OAuth2) (*in).DeepCopyInto(*out) } if in.TLSConfig != nil { @@ -1759,14 +1740,40 @@ func (in *HTTPSDConfig) DeepCopyInto(out *HTTPSDConfig) { *out = new(ProxyAuth) (*in).DeepCopyInto(*out) } + if in.FollowRedirects != nil { + in, out := &in.FollowRedirects, &out.FollowRedirects + *out = new(bool) + **out = **in + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPSDConfig. -func (in *HTTPSDConfig) DeepCopy() *HTTPSDConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPSDOptions. +func (in *HTTPSDOptions) DeepCopy() *HTTPSDOptions { if in == nil { return nil } - out := new(HTTPSDConfig) + out := new(HTTPSDOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HetznerSDConfig) DeepCopyInto(out *HetznerSDConfig) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int32) + **out = **in + } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HetznerSDConfig. +func (in *HetznerSDConfig) DeepCopy() *HetznerSDConfig { + if in == nil { + return nil + } + out := new(HetznerSDConfig) in.DeepCopyInto(out) return out } @@ -1941,41 +1948,6 @@ func (in *KubernetesSDConfig) DeepCopyInto(out *KubernetesSDConfig) { *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.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.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.ProxyClientConfig != nil { - in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) - (*in).DeepCopyInto(*out) - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } if in.Namespaces != nil { in, out := &in.Namespaces, &out.Namespaces *out = new(NamespaceDiscovery) @@ -1987,6 +1959,7 @@ func (in *KubernetesSDConfig) DeepCopyInto(out *KubernetesSDConfig) { *out = make([]K8SSelectorConfig, len(*in)) copy(*out, *in) } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesSDConfig. @@ -1999,6 +1972,22 @@ func (in *KubernetesSDConfig) DeepCopy() *KubernetesSDConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KumaSDConfig) DeepCopyInto(out *KumaSDConfig) { + *out = *in + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KumaSDConfig. +func (in *KumaSDConfig) DeepCopy() *KumaSDConfig { + if in == nil { + return nil + } + out := new(KumaSDConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *License) DeepCopyInto(out *License) { *out = *in @@ -2231,41 +2220,7 @@ func (in *NomadSDConfig) DeepCopyInto(out *NomadSDConfig) { *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) - } - 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.ProxyURL != nil { - in, out := &in.ProxyURL, &out.ProxyURL - *out = new(string) - **out = **in - } - if in.ProxyClientConfig != nil { - in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) - (*in).DeepCopyInto(*out) - } - if in.FollowRedirects != nil { - in, out := &in.FollowRedirects, &out.FollowRedirects - *out = new(bool) - **out = **in - } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NomadSDConfig. @@ -2316,6 +2271,32 @@ func (in *OAuth2) DeepCopy() *OAuth2 { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVHCloudSDConfig) DeepCopyInto(out *OVHCloudSDConfig) { + *out = *in + if in.ApplicationSecret != nil { + in, out := &in.ApplicationSecret, &out.ApplicationSecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.ConsumerKey != nil { + in, out := &in.ConsumerKey, &out.ConsumerKey + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVHCloudSDConfig. +func (in *OVHCloudSDConfig) DeepCopy() *OVHCloudSDConfig { + if in == nil { + return nil + } + out := new(OVHCloudSDConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenStackSDConfig) DeepCopyInto(out *OpenStackSDConfig) { *out = *in @@ -2381,7 +2362,7 @@ func (in *OpenStackSDConfig) DeepCopyInto(out *OpenStackSDConfig) { } if in.Port != nil { in, out := &in.Port, &out.Port - *out = new(int) + *out = new(int32) **out = **in } if in.Availability != nil { @@ -2584,6 +2565,60 @@ func (in *ProxyAuth) DeepCopy() *ProxyAuth { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProxyConfig) DeepCopyInto(out *ProxyConfig) { + *out = *in + if in.ProxyConnectHeader != nil { + in, out := &in.ProxyConnectHeader, &out.ProxyConnectHeader + *out = make(map[string][]v1.SecretKeySelector, len(*in)) + for key, val := range *in { + var outVal []v1.SecretKeySelector + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = make([]v1.SecretKeySelector, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + (*out)[key] = outVal + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfig. +func (in *ProxyConfig) DeepCopy() *ProxyConfig { + if in == nil { + return nil + } + out := new(ProxyConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PuppetDBSDConfig) DeepCopyInto(out *PuppetDBSDConfig) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int32) + **out = **in + } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PuppetDBSDConfig. +func (in *PuppetDBSDConfig) DeepCopy() *PuppetDBSDConfig { + if in == nil { + return nil + } + out := new(PuppetDBSDConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PushoverConfig) DeepCopyInto(out *PushoverConfig) { *out = *in @@ -6427,6 +6462,48 @@ func (in *VMScrapeConfigSpec) DeepCopyInto(out *VMScrapeConfigSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.KumaSDConfigs != nil { + in, out := &in.KumaSDConfigs, &out.KumaSDConfigs + *out = make([]KumaSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.OVHCloudSDConfigs != nil { + in, out := &in.OVHCloudSDConfigs, &out.OVHCloudSDConfigs + *out = make([]OVHCloudSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.PuppetDBSDConfigs != nil { + in, out := &in.PuppetDBSDConfigs, &out.PuppetDBSDConfigs + *out = make([]PuppetDBSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VultrSDConfigs != nil { + in, out := &in.VultrSDConfigs, &out.VultrSDConfigs + *out = make([]VultrSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.HetznerSDConfigs != nil { + in, out := &in.HetznerSDConfigs, &out.HetznerSDConfigs + *out = make([]HetznerSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EurekaSDConfigs != nil { + in, out := &in.EurekaSDConfigs, &out.EurekaSDConfigs + *out = make([]EurekaSDConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) @@ -7319,6 +7396,27 @@ func (in *VictorOpsConfig) DeepCopy() *VictorOpsConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VultrSDConfig) DeepCopyInto(out *VultrSDConfig) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int32) + **out = **in + } + in.HTTPSDOptions.DeepCopyInto(&out.HTTPSDOptions) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VultrSDConfig. +func (in *VultrSDConfig) DeepCopy() *VultrSDConfig { + if in == nil { + return nil + } + out := new(VultrSDConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WeChatConfig) DeepCopyInto(out *WeChatConfig) { *out = *in diff --git a/config/crd/overlay/crd.descriptionless.yaml b/config/crd/overlay/crd.descriptionless.yaml index 4886fcec2..c69138fbd 100644 --- a/config/crd/overlay/crd.descriptionless.yaml +++ b/config/crd/overlay/crd.descriptionless.yaml @@ -7216,6 +7216,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -7281,7 +7285,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -7672,6 +7696,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -7737,7 +7765,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -8348,6 +8396,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -8413,7 +8465,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -8681,6 +8753,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -8746,7 +8822,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -8920,6 +9016,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -8985,7 +9085,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -9204,6 +9324,10 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + type: boolean + noProxy: + type: string oauth2: properties: client_id: @@ -9269,7 +9393,27 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: object + proxyFromEnvironment: + type: boolean proxyURL: + pattern: ^(http|https|socks5)://.+$ type: string tls_config: properties: @@ -33553,88 +33697,6 @@ spec: - OAuth - ManagedIdentity type: string - clientID: - type: string - clientSecret: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - environment: - type: string - port: - type: integer - resourceGroup: - type: string - subscriptionID: - minLength: 1 - type: string - tenantID: - type: string - required: - - subscriptionID - type: object - type: array - basicAuth: - properties: - password: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - password_file: - type: string - username: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerTokenFile: - type: string - bearerTokenSecret: - nullable: true - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - consulSDConfigs: - items: - properties: - allowStale: - type: boolean authorization: properties: credentials: @@ -33686,19 +33748,25 @@ spec: type: object x-kubernetes-map-type: atomic type: object - datacenter: + clientID: type: string - filter: + clientSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + environment: type: string followRedirects: type: boolean - namespace: - type: string - nodeMeta: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic oauth2: properties: client_id: @@ -33764,8 +33832,9 @@ spec: - client_id - token_url type: object - partition: - type: string + port: + format: int32 + type: integer proxy_client_config: properties: basic_auth: @@ -33819,26 +33888,13 @@ spec: type: object proxyURL: type: string - scheme: - enum: - - HTTP - - HTTPS + resourceGroup: type: string - server: + subscriptionID: minLength: 1 type: string - services: - items: - type: string - type: array - x-kubernetes-list-type: atomic - tagSeparator: + tenantID: type: string - tags: - items: - type: string - type: array - x-kubernetes-list-type: atomic tlsConfig: properties: ca: @@ -33923,26 +33979,62 @@ spec: serverName: type: string type: object - tokenRef: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic required: - - server + - subscriptionID type: object type: array - digitalOceanSDConfigs: + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + type: string + bearerTokenSecret: + nullable: true + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + consulSDConfigs: items: properties: + allowStale: + type: boolean authorization: properties: credentials: @@ -33963,8 +34055,50 @@ spec: type: type: string type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + datacenter: + type: string + filter: + type: string followRedirects: type: boolean + namespace: + type: string + nodeMeta: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic oauth2: properties: client_id: @@ -34030,8 +34164,8 @@ spec: - client_id - token_url type: object - port: - type: integer + partition: + type: string proxy_client_config: properties: basic_auth: @@ -34085,6 +34219,26 @@ spec: type: object proxyURL: type: string + scheme: + enum: + - HTTP + - HTTPS + type: string + server: + minLength: 1 + type: string + services: + items: + type: string + type: array + x-kubernetes-list-type: atomic + tagSeparator: + type: string + tags: + items: + type: string + type: array + x-kubernetes-list-type: atomic tlsConfig: properties: ca: @@ -34169,66 +34323,7 @@ spec: serverName: type: string type: object - type: object - type: array - dnsSDConfigs: - items: - properties: - names: - items: - type: string - minItems: 1 - type: array - port: - type: integer - type: - enum: - - SRV - - A - - AAAA - - MX - type: string - required: - - names - type: object - type: array - ec2SDConfigs: - items: - properties: - accessKey: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - filters: - items: - properties: - name: - type: string - values: - items: - type: string - type: array - required: - - name - - values - type: object - type: array - port: - type: integer - region: - type: string - roleARN: - type: string - secretKey: + tokenRef: properties: key: type: string @@ -34241,46 +34336,11 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - type: array - fileSDConfigs: - items: - properties: - files: - items: - type: string - minItems: 1 - type: array - required: - - files - type: object - type: array - follow_redirects: - type: boolean - gceSDConfigs: - items: - properties: - filter: - type: string - port: - type: integer - project: - minLength: 1 - type: string - tagSeparator: - type: string - zone: - x-kubernetes-preserve-unknown-fields: true required: - - project - - zone + - server type: object type: array - honorLabels: - type: boolean - honorTimestamps: - type: boolean - httpSDConfigs: + digitalOceanSDConfigs: items: properties: authorization: @@ -34334,11 +34394,13 @@ spec: type: object x-kubernetes-map-type: atomic type: object - proxy_client_config: + followRedirects: + type: boolean + oauth2: properties: - basic_auth: + client_id: properties: - password: + configMap: properties: key: type: string @@ -34351,9 +34413,7 @@ spec: - key type: object x-kubernetes-map-type: atomic - password_file: - type: string - username: + secret: properties: key: type: string @@ -34367,7 +34427,7 @@ spec: type: object x-kubernetes-map-type: atomic type: object - bearer_token: + client_secret: properties: key: type: string @@ -34380,15 +34440,87 @@ spec: - key type: object x-kubernetes-map-type: atomic - bearer_token_file: + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: type: string + scopes: + items: + type: string + type: array tls_config: x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url type: object - proxyURL: - type: string - tlsConfig: - properties: + port: + format: int32 + type: integer + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + server: + type: string + tlsConfig: + properties: ca: properties: configMap: @@ -34471,28 +34603,85 @@ spec: serverName: type: string type: object - url: - minLength: 1 - pattern: ^http(s)?://.+$ + type: object + type: array + dnsSDConfigs: + items: + properties: + names: + items: + type: string + minItems: 1 + type: array + port: + format: int32 + type: integer + type: + enum: + - SRV + - A + - AAAA + - MX type: string required: - - url + - names type: object type: array - interval: - type: string - kubernetesSDConfigs: + ec2SDConfigs: items: properties: - apiServer: - type: string - attach_metadata: + accessKey: properties: - namespace: + key: + type: string + name: + default: "" + type: string + optional: type: boolean - node: + required: + - key + type: object + x-kubernetes-map-type: atomic + filters: + items: + properties: + name: + type: string + values: + items: + type: string + type: array + required: + - name + - values + type: object + type: array + port: + format: int32 + type: integer + region: + type: string + roleARN: + type: string + secretKey: + properties: + key: + type: string + name: + default: "" + type: string + optional: type: boolean + required: + - key type: object + x-kubernetes-map-type: atomic + type: object + type: array + eurekaSDConfigs: + items: + properties: authorization: properties: credentials: @@ -34546,15 +34735,6 @@ spec: type: object followRedirects: type: boolean - namespaces: - properties: - names: - items: - type: string - type: array - ownNamespace: - type: boolean - type: object oauth2: properties: client_id: @@ -34673,38 +34853,8 @@ spec: type: object proxyURL: type: string - role: - enum: - - node - - pod - - service - - endpoints - - endpointslice - - ingress + server: type: string - selectors: - items: - properties: - field: - type: string - label: - type: string - role: - enum: - - node - - pod - - service - - endpoints - - endpointslice - - ingress - type: string - required: - - role - type: object - type: array - x-kubernetes-list-map-keys: - - role - x-kubernetes-list-type: map tlsConfig: properties: ca: @@ -34789,53 +34939,45 @@ spec: serverName: type: string type: object - required: - - role type: object type: array - max_scrape_size: - type: string - metricRelabelConfigs: + fileSDConfigs: items: properties: - action: - type: string - if: - x-kubernetes-preserve-unknown-fields: true - labels: - additionalProperties: - type: string - type: object - match: - type: string - modulus: - format: int64 - type: integer - regex: - x-kubernetes-preserve-unknown-fields: true - replacement: - type: string - separator: - type: string - source_labels: - items: - type: string - type: array - sourceLabels: + files: items: type: string + minItems: 1 type: array - target_label: + required: + - files + type: object + type: array + follow_redirects: + type: boolean + gceSDConfigs: + items: + properties: + filter: type: string - targetLabel: + port: + format: int32 + type: integer + project: + minLength: 1 + type: string + tagSeparator: type: string + zone: + x-kubernetes-preserve-unknown-fields: true + required: + - project + - zone type: object type: array - nomadSDConfigs: + hetznerSDConfigs: items: properties: - allowStale: - type: boolean authorization: properties: credentials: @@ -34889,8 +35031,6 @@ spec: type: object followRedirects: type: boolean - namespace: - type: string oauth2: properties: client_id: @@ -34956,6 +35096,9 @@ spec: - client_id - token_url type: object + port: + format: int32 + type: integer proxy_client_config: properties: basic_auth: @@ -35009,12 +35152,12 @@ spec: type: object proxyURL: type: string - region: - type: string - server: - minLength: 1 - type: string - tagSeparator: + role: + enum: + - robot + - Robot + - hcloud + - Cloud type: string tlsConfig: properties: @@ -35101,12 +35244,2082 @@ spec: type: string type: object required: - - server + - role type: object type: array - oauth2: + honorLabels: + type: boolean + honorTimestamps: + type: boolean + httpSDConfigs: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + followRedirects: + type: boolean + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + minLength: 1 + pattern: ^http(s)?://.+$ + type: string + required: + - url + type: object + type: array + interval: + type: string + kubernetesSDConfigs: + items: + properties: + apiServer: + type: string + attach_metadata: + properties: + namespace: + type: boolean + node: + type: boolean + type: object + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + followRedirects: + type: boolean + namespaces: + properties: + names: + items: + type: string + type: array + ownNamespace: + type: boolean + type: object + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + role: + enum: + - node + - pod + - service + - endpoints + - endpointslice + - ingress + type: string + selectors: + items: + properties: + field: + type: string + label: + type: string + role: + enum: + - node + - pod + - service + - endpoints + - endpointslice + - ingress + type: string + required: + - role + type: object + type: array + x-kubernetes-list-map-keys: + - role + x-kubernetes-list-type: map + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - role + type: object + type: array + kumaSDConfigs: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientID: + type: string + followRedirects: + type: boolean + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + server: + minLength: 1 + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - server + type: object + type: array + max_scrape_size: + type: string + metricRelabelConfigs: + items: + properties: + action: + type: string + if: + x-kubernetes-preserve-unknown-fields: true + labels: + additionalProperties: + type: string + type: object + match: + type: string + modulus: + format: int64 + type: integer + regex: + x-kubernetes-preserve-unknown-fields: true + replacement: + type: string + separator: + type: string + source_labels: + items: + type: string + type: array + sourceLabels: + items: + type: string + type: array + target_label: + type: string + targetLabel: + type: string + type: object + type: array + nomadSDConfigs: + items: + properties: + allowStale: + type: boolean + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + followRedirects: + type: boolean + namespace: + type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + region: + type: string + server: + minLength: 1 + type: string + tagSeparator: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - server + type: object + type: array + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + openstackSDConfigs: + items: + properties: + allTenants: + type: boolean + applicationCredentialId: + type: string + applicationCredentialName: + type: string + applicationCredentialSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + availability: + enum: + - Public + - public + - Admin + - admin + - Internal + - internal + type: string + domainID: + type: string + domainName: + type: string + identityEndpoint: + type: string + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + port: + format: int32 + type: integer + projectID: + type: string + projectName: + type: string + region: + minLength: 1 + type: string + role: + enum: + - Instance + - instance + - Hypervisor + - hypervisor + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + userid: + type: string + username: + type: string + required: + - region + - role + type: object + type: array + ovhcloudSDConfigs: + items: + properties: + applicationKey: + minLength: 1 + type: string + applicationSecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + consumerKey: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpoint: + type: string + followRedirects: + type: boolean + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + service: + enum: + - vps + - VPS + - dedicated_server + - DedicatedServer + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + required: + - applicationKey + - applicationSecret + - consumerKey + - service + type: object + type: array + params: + additionalProperties: + items: + type: string + type: array + type: object + path: + type: string + proxyURL: + type: string + puppetDBSDConfigs: + items: + properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + followRedirects: + type: boolean + includeParameters: + type: boolean + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + port: + format: int32 + type: integer + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + query: + type: string + tlsConfig: + properties: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + url: + type: string + required: + - query + - url + type: object + type: array + relabelConfigs: + items: + properties: + action: + type: string + if: + x-kubernetes-preserve-unknown-fields: true + labels: + additionalProperties: + type: string + type: object + match: + type: string + modulus: + format: int64 + type: integer + regex: + x-kubernetes-preserve-unknown-fields: true + replacement: + type: string + separator: + type: string + source_labels: + items: + type: string + type: array + sourceLabels: + items: + type: string + type: array + target_label: + type: string + targetLabel: + type: string + type: object + type: array + sampleLimit: + type: integer + scheme: + enum: + - http + - https + - HTTPS + - HTTP + type: string + scrape_interval: + type: string + scrapeClass: + type: string + scrapeTimeout: + type: string + seriesLimit: + type: integer + staticConfigs: + items: + properties: + labels: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + targets: + items: + type: string + type: array + type: object + type: array + tlsConfig: properties: - client_id: + ca: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + type: string + cert: properties: configMap: properties: @@ -35115,13 +37328,94 @@ spec: name: default: "" type: string - optional: - type: boolean - required: - - key + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + type: string + insecureSkipVerify: + type: boolean + keyFile: + type: string + keySecret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + type: string + type: object + vm_scrape_params: + properties: + disable_compression: + type: boolean + disable_keep_alive: + type: boolean + headers: + items: + type: string + type: array + no_stale_markers: + type: boolean + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic type: object - x-kubernetes-map-type: atomic - secret: + bearer_token: properties: key: type: string @@ -35134,106 +37428,204 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - client_secret: - properties: - key: - type: string - name: - default: "" + bearer_token_file: type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - client_secret_file: - type: string - endpoint_params: - additionalProperties: - type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true type: object - proxy_url: + scrape_align_interval: type: string - scopes: - items: - type: string - type: array - tls_config: - x-kubernetes-preserve-unknown-fields: true - token_url: - minLength: 1 + scrape_offset: type: string - required: - - client_id - - token_url + stream_parse: + type: boolean type: object - openstackSDConfigs: + vultrSDConfigs: items: properties: - allTenants: - type: boolean - applicationCredentialId: - type: string - applicationCredentialName: - type: string - applicationCredentialSecret: + authorization: properties: - key: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: type: string - name: - default: "" + type: type: string - optional: - type: boolean - required: - - key type: object - x-kubernetes-map-type: atomic - availability: - enum: - - Public - - public - - Admin - - admin - - Internal - - internal + basicAuth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + firewallGroupID: type: string - domainID: + followRedirects: + type: boolean + hostname: type: string - domainName: + label: type: string - identityEndpoint: + mainIP: type: string - password: + oauth2: properties: - key: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 type: string - optional: - type: boolean required: - - key + - client_id + - token_url + type: object + port: + format: int32 + type: integer + proxy_client_config: + properties: + basic_auth: + properties: + password: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true type: object - x-kubernetes-map-type: atomic - port: - type: integer - projectID: - type: string - projectName: + proxyURL: type: string region: - minLength: 1 - type: string - role: - enum: - - Instance - - instance - - Hypervisor - - hypervisor type: string tlsConfig: properties: @@ -35319,246 +37711,8 @@ spec: serverName: type: string type: object - userid: - type: string - username: - type: string - required: - - region - - role - type: object - type: array - params: - additionalProperties: - items: - type: string - type: array - type: object - path: - type: string - proxyURL: - type: string - relabelConfigs: - items: - properties: - action: - type: string - if: - x-kubernetes-preserve-unknown-fields: true - labels: - additionalProperties: - type: string - type: object - match: - type: string - modulus: - format: int64 - type: integer - regex: - x-kubernetes-preserve-unknown-fields: true - replacement: - type: string - separator: - type: string - source_labels: - items: - type: string - type: array - sourceLabels: - items: - type: string - type: array - target_label: - type: string - targetLabel: - type: string - type: object - type: array - sampleLimit: - type: integer - scheme: - enum: - - http - - https - - HTTPS - - HTTP - type: string - scrape_interval: - type: string - scrapeClass: - type: string - scrapeTimeout: - type: string - seriesLimit: - type: integer - staticConfigs: - items: - properties: - labels: - additionalProperties: - type: string - type: object - x-kubernetes-map-type: atomic - targets: - items: - type: string - type: array type: object type: array - tlsConfig: - properties: - ca: - properties: - configMap: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - type: string - cert: - properties: - configMap: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - type: string - insecureSkipVerify: - type: boolean - keyFile: - type: string - keySecret: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - type: string - type: object - vm_scrape_params: - properties: - disable_compression: - type: boolean - disable_keep_alive: - type: boolean - headers: - items: - type: string - type: array - no_stale_markers: - type: boolean - proxy_client_config: - properties: - basic_auth: - properties: - password: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - password_file: - type: string - username: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearer_token: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string - tls_config: - x-kubernetes-preserve-unknown-fields: true - type: object - scrape_align_interval: - type: string - scrape_offset: - type: string - stream_parse: - type: boolean - type: object type: object status: properties: diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml index 14048d61e..17a1f1610 100644 --- a/config/crd/overlay/crd.yaml +++ b/config/crd/overlay/crd.yaml @@ -14318,6 +14318,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -14438,8 +14447,46 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean proxyURL: - description: Optional proxy URL. + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ type: string tls_config: description: TLS configuration for the client. @@ -15172,6 +15219,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -15292,8 +15348,46 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean proxyURL: - description: Optional proxy URL. + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ type: string tls_config: description: TLS configuration for the client. @@ -16334,6 +16428,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -16454,8 +16557,46 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean proxyURL: - description: Optional proxy URL. + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ type: string tls_config: description: TLS configuration for the client. @@ -16961,6 +17102,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -17081,8 +17231,46 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean proxyURL: - description: Optional proxy URL. + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ type: string tls_config: description: TLS configuration for the client. @@ -17406,6 +17594,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -17526,140 +17723,178 @@ spec: - client_id - token_url type: object - proxyURL: - description: Optional proxy URL. - type: string - tls_config: - description: TLS configuration for the client. - properties: - ca: - description: Struct containing the CA cert to - use for the targets. - properties: - configMap: - description: ConfigMap containing data to - use for the targets. - properties: - key: - description: The key to select. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use - for the targets. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - 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 - type: object - caFile: - description: Path to the CA cert in the container - to use for the targets. - type: string - cert: - description: Struct containing the client cert - file for the targets. - properties: - configMap: - description: ConfigMap containing data to - use for the targets. - properties: - key: - description: The key to select. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap - or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use - for the targets. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - 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 - type: object - certFile: - description: Path to the client cert file in the - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the - container for the targets. - type: string - keySecret: - description: Secret containing the client key - file for the targets. + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean + proxyURL: + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ + type: string + tls_config: + description: TLS configuration for the client. + properties: + ca: + description: Struct containing the CA cert to + use for the targets. + properties: + configMap: + description: ConfigMap containing data to + use for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use + for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container + to use for the targets. + type: string + cert: + description: Struct containing the client cert + file for the targets. + properties: + configMap: + description: ConfigMap containing data to + use for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use + for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the + container for the targets. + type: string + keySecret: + description: Secret containing the client key + file for the targets. properties: key: description: The key of the secret to select @@ -17942,6 +18177,15 @@ spec: - key type: object x-kubernetes-map-type: atomic + follow_redirects: + description: FollowRedirects controls redirects for + scraping. + type: boolean + noProxy: + description: |- + NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying. + IP and domain names can contain port numbers. + type: string oauth2: description: OAuth2 client credentials used to fetch a token for the targets. @@ -18062,8 +18306,46 @@ spec: - client_id - token_url type: object + proxyConnectHeader: + additionalProperties: + items: + description: SecretKeySelector selects a key of + a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: array + description: ProxyConnectHeader optionally specifies + headers to send to proxies during CONNECT requests. + type: object + proxyFromEnvironment: + description: ProxyFromEnvironment defines whether + to use the proxy configuration defined by environment + variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). + type: boolean proxyURL: - description: Optional proxy URL. + description: ProxyUrl defines the HTTP proxy server + to use. + pattern: ^(http|https|socks5)://.+$ type: string tls_config: description: TLS configuration for the client. @@ -68424,6 +68706,101 @@ spec: - OAuth - ManagedIdentity type: string + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object clientID: description: Optional client ID. Only required with the OAuth authentication method. @@ -68456,11 +68833,230 @@ spec: environment: description: The Azure environment. type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object port: description: |- The port to scrape metrics from. If using the public IP address, this must instead be specified in the relabeling rule. + format: int32 type: integer + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string resourceGroup: description: Optional resource group name. Limits discovery to this resource group. @@ -68473,6 +69069,159 @@ spec: description: Optional tenant ID. Only required with the OAuth authentication method. type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object required: - subscriptionID type: object @@ -68687,9 +69436,8 @@ spec: See https://developer.hashicorp.com/consul/api-docs/features/filtering type: string followRedirects: - description: |- - Configure whether HTTP requests follow HTTP 3xx redirects. - If unset, use its default value. + description: Configure whether HTTP requests follow HTTP 3xx + redirects. type: boolean namespace: description: Namespaces are only supported in Consul Enterprise. @@ -69173,6 +69921,67 @@ spec: description: Type of authorization, default to bearer type: string type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object followRedirects: description: Configure whether HTTP requests follow HTTP 3xx redirects. @@ -69293,6 +70102,7 @@ spec: type: object port: description: The port to scrape metrics from. + format: int32 type: integer proxy_client_config: description: |- @@ -69394,6 +70204,11 @@ spec: description: ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. type: string + server: + description: |- + Server is an optional DigitalOcean API server to query. + By default, https://api.digitalocean.com is used. + type: string tlsConfig: description: TLS configuration to use on every scrape request properties: @@ -69568,6 +70383,7 @@ spec: description: |- The port number used if the query type is not SRV Ignored for SRV records + format: int32 type: integer type: enum: @@ -69639,6 +70455,7 @@ spec: description: |- The port to scrape metrics from. If using the public IP address, this must instead be specified in the relabeling rule. + format: int32 type: integer region: description: The AWS region @@ -69672,84 +70489,13 @@ spec: x-kubernetes-map-type: atomic type: object type: array - fileSDConfigs: - description: FileSDConfigs defines a list of file service discovery + eurekaSDConfigs: + description: EurekaSDConfigs defines a list of Eureka service discovery configurations. items: description: |- - FileSDConfig defines a file service discovery configuration. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#file_sd_configs) - properties: - files: - description: List of files to be used for file discovery. - items: - type: string - minItems: 1 - type: array - required: - - files - type: object - type: array - follow_redirects: - description: FollowRedirects controls redirects for scraping. - type: boolean - gceSDConfigs: - description: GCESDConfigs defines a list of GCE service discovery - configurations. - items: - description: |- - GCESDConfig configures scrape targets from GCP GCE instances. - The private IP address is used by default, but may be changed to - the public IP address with relabeling. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#gce_sd_configs) - - The GCE service discovery will load the Google Cloud credentials - from the file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable. - See https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform - properties: - filter: - description: |- - Filter can be used optionally to filter the instance list by other criteria - Syntax of this filter is described in the filter query parameter section: - https://cloud.google.com/compute/docs/reference/latest/instances/list - type: string - port: - description: |- - The port to scrape metrics from. If using the public IP address, this must - instead be specified in the relabeling rule. - type: integer - project: - description: The Google Cloud Project ID - minLength: 1 - type: string - tagSeparator: - description: The tag separator is used to separate the tags - on concatenation - type: string - zone: - description: The zone of the scrape targets. If you need multiple - zones use multiple GCESDConfigs. - x-kubernetes-preserve-unknown-fields: true - required: - - project - - zone - type: object - type: array - honorLabels: - description: HonorLabels chooses the metric's labels on collisions - with target labels. - type: boolean - honorTimestamps: - description: HonorTimestamps controls whether vmagent or vmsingle - respects the timestamps present in scraped data. - type: boolean - httpSDConfigs: - description: HTTPSDConfigs defines a list of HTTP service discovery - configurations. - items: - description: |- - HTTPSDConfig defines a HTTP service discovery configuration. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http_sd_configs) + EurekaSDConfig configurations allows retrieving scrape targets from Eureka REST API. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#eureka_sd_configs) properties: authorization: description: Authorization header to use on every scrape request. @@ -69846,23 +70592,23 @@ spec: type: object x-kubernetes-map-type: atomic type: object - proxy_client_config: - description: |- - ProxyClientConfig configures proxy auth settings for scraping - See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + oauth2: + description: OAuth2 defines auth configuration properties: - basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + client_id: + description: The secret or configmap containing the OAuth2 + client id properties: - password: - description: |- - Password defines reference for secret with password value - The secret needs to be in the same namespace as scrape object + configMap: + description: ConfigMap containing data to use for the + targets. properties: key: - description: The key of the secret to select from. Must - be a valid secret key. + description: The key to select. type: string name: default: "" @@ -69874,22 +70620,15 @@ spec: More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names type: string optional: - description: Specify whether the Secret or its key - must be defined + description: Specify whether the ConfigMap or its + key must be defined type: boolean required: - key type: object x-kubernetes-map-type: atomic - password_file: - description: |- - PasswordFile defines path to password file at disk - must be pre-mounted - type: string - username: - description: |- - Username defines reference for secret with username value - The secret needs to be in the same namespace as scrape object + secret: + description: Secret containing data to use for the targets. properties: key: description: The key of the secret to select from. Must @@ -69913,8 +70652,8 @@ spec: type: object x-kubernetes-map-type: atomic type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. + client_secret: + description: The secret containing the OAuth2 client secret properties: key: description: The key of the secret to select from. Must @@ -69937,48 +70676,53 @@ spec: - key type: object x-kubernetes-map-type: atomic - bearer_token_file: + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url type: object - proxyURL: - description: ProxyURL eg http://proxyserver:2195 Directs scrapes - to proxy through this endpoint. - type: string - tlsConfig: - description: TLS configuration to use on every scrape request + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: - ca: - description: Struct containing the CA cert to use for the - targets. + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. + password: + description: |- + 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 @@ -70001,41 +70745,15 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the container to use - for the targets. - type: string - cert: - description: Struct containing the client cert file for - the targets. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 @@ -70059,20 +70777,171 @@ spec: type: object x-kubernetes-map-type: atomic type: object - certFile: - description: Path to the client cert file in the container - for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the container - for the targets. - type: string - keySecret: - description: Secret containing the client key file for the - targets. + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + server: + description: |- + Server is an optional URL to connect to the Eureka server. + By default, the http://localhost:8080/eureka/v2 is used. + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. properties: key: description: The key of the secret to select from. Must @@ -70099,49 +70968,80 @@ spec: description: Used to verify the hostname for the targets. type: string type: object - url: - description: URL from which the targets are fetched. - minLength: 1 - pattern: ^http(s)?://.+$ - type: string + type: object + type: array + fileSDConfigs: + description: FileSDConfigs defines a list of file service discovery + configurations. + items: + description: |- + FileSDConfig defines a file service discovery configuration. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#file_sd_configs) + properties: + files: + description: List of files to be used for file discovery. + items: + type: string + minItems: 1 + type: array required: - - url + - files 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. + follow_redirects: + description: FollowRedirects controls redirects for scraping. + type: boolean + gceSDConfigs: + description: GCESDConfigs defines a list of GCE service discovery + configurations. items: description: |- - KubernetesSDConfig allows retrieving scrape targets from Kubernetes' REST API. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#kubernetes_sd_configs) + GCESDConfig configures scrape targets from GCP GCE instances. + The private IP address is used by default, but may be changed to + the public IP address with relabeling. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#gce_sd_configs) + + The GCE service discovery will load the Google Cloud credentials + from the file specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable. + See https://cloud.google.com/kubernetes-engine/docs/tutorials/authenticating-to-cloud-platform properties: - apiServer: + filter: description: |- - The API server address consisting of a hostname or IP address followed - by an optional port number. - If left empty, assuming process is running inside - of the cluster. It will discover API servers automatically and use the pod's - CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. + Filter can be used optionally to filter the instance list by other criteria + Syntax of this filter is described in the filter query parameter section: + https://cloud.google.com/compute/docs/reference/latest/instances/list type: string - attach_metadata: - description: AttachMetadata configures metadata attaching from - service discovery - properties: - namespace: - description: |- - Namespace instructs vmagent or vmsingle to add namespace specific metadata from service discovery - Valid for roles: pod, service, endpoints, endpointslice, ingress. - type: boolean - node: - description: |- - Node instructs vmagent or vmsingle to add node specific metadata from service discovery - Valid for roles: pod, endpoints, endpointslice. - type: boolean - type: object + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + type: integer + project: + description: The Google Cloud Project ID + minLength: 1 + type: string + tagSeparator: + description: The tag separator is used to separate the tags + on concatenation + type: string + zone: + description: The zone of the scrape targets. If you need multiple + zones use multiple GCESDConfigs. + x-kubernetes-preserve-unknown-fields: true + required: + - project + - zone + type: object + type: array + hetznerSDConfigs: + description: HetznerSDConfigs defines a list of Hetzner service discovery + configurations. + items: + description: |- + HetznerSDConfig configurations allows retrieving scrape targets from Hetzner Cloud and Hetzner Robot. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#hetzner_sd_configs) + properties: authorization: description: Authorization header to use on every scrape request. properties: @@ -70241,22 +71141,6 @@ spec: description: Configure whether HTTP requests follow HTTP 3xx redirects. type: boolean - namespaces: - description: Optional namespace discovery. If omitted, discover - targets across all namespaces. - properties: - names: - description: |- - List of namespaces where to watch for resources. - If empty and `ownNamespace` isn't true, watch for resources in all namespaces. - items: - type: string - type: array - ownNamespace: - description: Includes the namespace in which the pod exists - to the list of watched namespaces. - type: boolean - type: object oauth2: description: OAuth2 defines auth configuration properties: @@ -70371,6 +71255,10 @@ spec: - client_id - token_url type: object + port: + description: Port is an optional port to scrape metrics from + format: int32 + type: integer proxy_client_config: description: |- ProxyClientConfig configures proxy auth settings for scraping @@ -70472,41 +71360,14 @@ spec: to proxy through this endpoint. type: string role: - description: Role of the Kubernetes entities that should be - discovered. + description: Role defines mandatory Hetzner role for entity + discovery. enum: - - node - - pod - - service - - endpoints - - endpointslice - - ingress + - robot + - Robot + - hcloud + - Cloud type: string - selectors: - description: Selector to select objects. - items: - description: K8SSelectorConfig is Kubernetes Selector Config - properties: - field: - type: string - label: - type: string - role: - enum: - - node - - pod - - service - - endpoints - - endpointslice - - ingress - type: string - required: - - role - type: object - type: array - x-kubernetes-list-map-keys: - - role - x-kubernetes-list-type: map tlsConfig: description: TLS configuration to use on every scrape request properties: @@ -70664,99 +71525,22 @@ spec: - role type: object type: array - 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/victoriametrics/#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/victoriametrics/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 - nomadSDConfigs: - description: NomadSDConfigs defines a list of Nomad service discovery + honorLabels: + description: HonorLabels chooses the metric's labels on collisions + with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether vmagent or vmsingle + respects the timestamps present in scraped data. + type: boolean + httpSDConfigs: + description: HTTPSDConfigs defines a list of HTTP service discovery configurations. items: description: |- - NomadSDConfig configurations allow retrieving scrape targets from Nomad's Service API. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#nomad_sd_configs) + HTTPSDConfig defines a HTTP service discovery configuration. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http_sd_configs) properties: - allowStale: - description: |- - Allow stale Nomad results to reduce load on Nomad. - If unset, use its default value. - type: boolean authorization: description: Authorization header to use on every scrape request. properties: @@ -70856,9 +71640,6 @@ spec: description: Configure whether HTTP requests follow HTTP 3xx redirects. type: boolean - namespace: - description: Namespace to use for Nomad service discovery. - type: string oauth2: description: OAuth2 defines auth configuration properties: @@ -71073,19 +71854,6 @@ spec: description: ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. type: string - region: - description: Region to use for Nomad service discovery. - type: string - server: - description: A valid string consisting of a hostname or IP followed - by an optional port number. - minLength: 1 - type: string - tagSeparator: - description: |- - The string by which Nomad tags are joined into the tag label. - If unset, use its default value. - type: string tlsConfig: description: TLS configuration to use on every scrape request properties: @@ -71239,246 +72007,2935 @@ spec: description: Used to verify the hostname for the targets. type: string type: object + url: + description: URL from which the targets are fetched. + minLength: 1 + pattern: ^http(s)?://.+$ + type: string required: - - server + - url type: object type: array - oauth2: - description: OAuth2 defines auth configuration - properties: - client_id: - description: The secret or configmap containing the OAuth2 client - id - properties: - configMap: - description: ConfigMap containing data to use for the targets. - properties: - key: - description: The key to select. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the ConfigMap or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - 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 - type: object - client_secret: - description: The secret containing the OAuth2 client secret - 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - 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 - client_secret_file: - description: ClientSecretFile defines path for client secret file. - type: string - endpoint_params: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - proxy_url: - description: |- - The proxy URL for token_url connection - ( available from v0.55.0). - Is only supported by Scrape objects family - type: string - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tls_config: - description: |- - TLSConfig for token_url connection - ( available from v0.55.0). - Is only supported by Scrape objects family - x-kubernetes-preserve-unknown-fields: true - token_url: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - client_id - - token_url - type: object - openstackSDConfigs: - description: OpenStackSDConfigs defines a list of OpenStack service + interval: + description: Interval at which metrics should be scraped + type: string + kubernetesSDConfigs: + description: KubernetesSDConfigs defines a list of Kubernetes service discovery configurations. items: description: |- - OpenStackSDConfig allow retrieving scrape targets from OpenStack Nova instances. - See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#openstack_sd_configs) + KubernetesSDConfig allows retrieving scrape targets from Kubernetes' REST API. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#kubernetes_sd_configs) properties: - allTenants: - description: |- - Whether the service discovery should list all instances for all projects. - It is only relevant for the 'instance' role and usually requires admin permissions. - type: boolean - applicationCredentialId: - description: ApplicationCredentialID - type: string - applicationCredentialName: + apiServer: description: |- - The ApplicationCredentialID or ApplicationCredentialName fields are - required if using an application credential to authenticate. Some providers - allow you to create an application credential to authenticate rather than a - password. + The API server address consisting of a hostname or IP address followed + by an optional port number. + If left empty, assuming process is running inside + of the cluster. It will discover API servers automatically and use the pod's + CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. type: string - applicationCredentialSecret: - description: |- - The applicationCredentialSecret field is required if using an application - credential to authenticate. + attach_metadata: + description: AttachMetadata configures metadata attaching from + service discovery properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + namespace: + description: |- + Namespace instructs vmagent or vmsingle to add namespace specific metadata from service discovery + Valid for roles: pod, service, endpoints, endpointslice, ingress. + type: boolean + node: + description: |- + Node instructs vmagent or vmsingle to add node specific metadata from service discovery + Valid for roles: pod, endpoints, endpointslice. + type: boolean + type: object + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization type: string - name: - default: "" + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted type: string - optional: - description: Specify whether the Secret or its key must - be defined + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + namespaces: + description: Optional namespace discovery. If omitted, discover + targets across all namespaces. + properties: + names: + description: |- + List of namespaces where to watch for resources. + If empty and `ownNamespace` isn't true, watch for resources in all namespaces. + items: + type: string + type: array + ownNamespace: + description: Includes the namespace in which the pod exists + to the list of watched namespaces. type: boolean - required: - - key type: object - x-kubernetes-map-type: atomic - availability: - description: Availability of the endpoint to connect to. - enum: - - Public - - public - - Admin - - admin - - Internal - - internal - type: string - domainID: - description: DomainID - type: string - domainName: - description: |- - At most one of domainId and domainName must be provided if using username - with Identity V3. Otherwise, either are optional. - type: string - identityEndpoint: - description: |- - IdentityEndpoint specifies the HTTP endpoint that is required to work with - the Identity API of the appropriate version. - type: string - password: - description: |- - Password for the Identity V2 and V3 APIs. Consult with your provider's - control panel to discover your account's preferred method of authentication. + oauth2: + description: OAuth2 defines auth configuration properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - port: - description: |- - The port to scrape metrics from. If using the public IP address, this must - instead be specified in the relabeling rule. - type: integer - projectID: - description: ' ProjectID' - type: string - projectName: + proxy_client_config: description: |- - The ProjectId and ProjectName fields are optional for the Identity V2 API. - Some providers allow you to specify a ProjectName instead of the ProjectId. - Some require both. Your provider's authentication policies will determine - how these fields influence authentication. - type: string - region: - description: The OpenStack Region. - minLength: 1 - type: string - role: - description: The OpenStack role of entities that should be discovered. - enum: - - Instance - - instance - - Hypervisor - - hypervisor + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + role: + description: Role of the Kubernetes entities that should be + discovered. + enum: + - node + - pod + - service + - endpoints + - endpointslice + - ingress + type: string + selectors: + description: Selector to select objects. + items: + description: K8SSelectorConfig is Kubernetes Selector Config + properties: + field: + type: string + label: + type: string + role: + enum: + - node + - pod + - service + - endpoints + - endpointslice + - ingress + type: string + required: + - role + type: object + type: array + x-kubernetes-list-map-keys: + - role + x-kubernetes-list-type: map + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - role + type: object + type: array + kumaSDConfigs: + description: KumaSDConfigs defines a list of Kuma service discovery + configurations. + items: + description: |- + KumaSDConfig configurations allows retrieving scrape targets from Kuma control plane. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#kuma_sd_configs) + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + clientID: + description: |- + ClientID is an optional client ID to send to Kuma Control Plane. + The hostname of the server where vmagent runs is used if it isn't set. + If the hostname is empty, then "vmagent" string is used as client_id. + type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + server: + description: Server must contain the URL of Kuma Control Plane's + MADS xDS server. + minLength: 1 + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - server + type: object + type: array + 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/victoriametrics/#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/victoriametrics/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 + nomadSDConfigs: + description: NomadSDConfigs defines a list of Nomad service discovery + configurations. + items: + description: |- + NomadSDConfig configurations allow retrieving scrape targets from Nomad's Service API. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#nomad_sd_configs) + properties: + allowStale: + description: |- + Allow stale Nomad results to reduce load on Nomad. + If unset, use its default value. + type: boolean + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + namespace: + description: Namespace to use for Nomad service discovery. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + region: + description: Region to use for Nomad service discovery. + type: string + server: + description: A valid string consisting of a hostname or IP followed + by an optional port number. + minLength: 1 + type: string + tagSeparator: + description: |- + The string by which Nomad tags are joined into the tag label. + If unset, use its default value. + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - server + type: object + type: array + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 client + id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + openstackSDConfigs: + description: OpenStackSDConfigs defines a list of OpenStack service + discovery configurations. + items: + description: |- + OpenStackSDConfig allow retrieving scrape targets from OpenStack Nova instances. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#openstack_sd_configs) + properties: + allTenants: + description: |- + Whether the service discovery should list all instances for all projects. + It is only relevant for the 'instance' role and usually requires admin permissions. + type: boolean + applicationCredentialId: + description: ApplicationCredentialID + type: string + applicationCredentialName: + description: |- + The ApplicationCredentialID or ApplicationCredentialName fields are + required if using an application credential to authenticate. Some providers + allow you to create an application credential to authenticate rather than a + password. + type: string + applicationCredentialSecret: + description: |- + The applicationCredentialSecret field is required if using an application + credential to authenticate. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + availability: + description: Availability of the endpoint to connect to. + enum: + - Public + - public + - Admin + - admin + - Internal + - internal + type: string + domainID: + description: DomainID + type: string + domainName: + description: |- + At most one of domainId and domainName must be provided if using username + with Identity V3. Otherwise, either are optional. + type: string + identityEndpoint: + description: |- + IdentityEndpoint specifies the HTTP endpoint that is required to work with + the Identity API of the appropriate version. + type: string + password: + description: |- + Password for the Identity V2 and V3 APIs. Consult with your provider's + control panel to discover your account's preferred method of authentication. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + port: + description: |- + The port to scrape metrics from. If using the public IP address, this must + instead be specified in the relabeling rule. + format: int32 + type: integer + projectID: + description: ' ProjectID' + type: string + projectName: + description: |- + The ProjectId and ProjectName fields are optional for the Identity V2 API. + Some providers allow you to specify a ProjectName instead of the ProjectId. + Some require both. Your provider's authentication policies will determine + how these fields influence authentication. + type: string + region: + description: The OpenStack Region. + minLength: 1 + type: string + role: + description: The OpenStack role of entities that should be discovered. + enum: + - Instance + - instance + - Hypervisor + - hypervisor + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + userid: + description: UserID + type: string + username: + description: |- + Username is required if using Identity V2 API. Consult with your provider's + control panel to discover your account's username. + In Identity V3, either userid or a combination of username + and domainId or domainName are needed + type: string + required: + - region + - role + type: object + type: array + ovhcloudSDConfigs: + description: OVHCloudSDConfigs defines a list of OVH Cloud service + discovery configurations. + items: + description: |- + OVHCloudSDConfig configurations allows retrieving scrape targets from OVH Cloud VPS and OVH Cloud dedicated server. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#ovhcloud_sd_configs) + properties: + applicationKey: + description: ApplicationKey defines a self generated token. + minLength: 1 + type: string + applicationSecret: + description: ApplicationSecret defines a generated secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + consumerKey: + description: ConsumerKey holds user/app specific token + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + endpoint: + description: Endpoint defines OVH Cloud endpoint + type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + service: + description: Service could be either `vps` or `dedicated_server` + enum: + - vps + - VPS + - dedicated_server + - DedicatedServer + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - applicationKey + - applicationSecret + - consumerKey + - service + type: object + type: array + params: + additionalProperties: + items: + type: string + 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. + type: string + puppetDBSDConfigs: + description: PuppetDBSDConfigs defines a list of PuppetDB service + discovery configurations. + items: + description: |- + PuppetDBSDConfig configurations allows retrieving scrape targets from PuppetDB resources. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#puppetdb_sd_configs) + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + includeParameters: + description: IncludeParameters defines if parameters should + be included as meta labels. + type: boolean + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + port: + description: Port defines port to scrape metrics from + format: int32 + type: integer + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + query: + description: Query defines PQL query that allows to filter discovered + resources. type: string tlsConfig: description: TLS configuration to use on every scrape request @@ -71633,35 +75090,14 @@ spec: description: Used to verify the hostname for the targets. type: string type: object - userid: - description: UserID - type: string - username: - description: |- - Username is required if using Identity V2 API. Consult with your provider's - control panel to discover your account's username. - In Identity V3, either userid or a combination of username - and domainId or domainName are needed + url: + description: URL of the PuppetDB root query endpoint type: string required: - - region - - role + - query + - url type: object type: array - params: - additionalProperties: - items: - type: string - 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. - type: string relabelConfigs: description: RelabelConfigs to apply to samples during service discovery. items: @@ -72065,6 +75501,506 @@ spec: stream_parse: type: boolean type: object + vultrSDConfigs: + description: VultrSDConfigs defines a list of Vultr service discovery + configurations. + items: + description: |- + VultrSDConfig configurations allows retrieving scrape targets from Vultr instances. + See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#vultr_sd_configs) + properties: + authorization: + description: Authorization header to use on every scrape request. + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object + basicAuth: + description: BasicAuth information to use on every scrape request. + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + firewallGroupID: + description: FirewallGroupID is an optional query arguments + to filter instances by firewall group id. + type: string + followRedirects: + description: Configure whether HTTP requests follow HTTP 3xx + redirects. + type: boolean + hostname: + description: Hostname is an optional query arguments to filter + instances by hostname. + type: string + label: + description: Label is an optional query arguments to filter + instances by label. + type: string + mainIP: + description: MainIP is an optional query arguments to filter + instances by main ip address. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client secret + file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + port: + description: Port is an optional port to scrape metrics from. + format: int32 + type: integer + proxy_client_config: + description: |- + ProxyClientConfig configures proxy auth settings for scraping + See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) + properties: + basic_auth: + description: BasicAuth allow an endpoint to authenticate + over basic authentication + properties: + password: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: SecretKeySelector selects a key of a Secret. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + type: string + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + region: + description: Region is an optional query arguments to filter + instances by region id. + type: string + tlsConfig: + description: TLS configuration to use on every scrape request + properties: + ca: + description: Struct containing the CA cert to use for the + targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + caFile: + description: Path to the CA cert in the container to use + for the targets. + type: string + cert: + description: Struct containing the client cert file for + the targets. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + certFile: + description: Path to the client cert file in the container + for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the container + for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array type: object status: description: ScrapeObjectStatus defines the observed state of ScrapeObjects diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 56caf115a..9dfca948b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -83,6 +83,7 @@ aliases: * FEATURE: [vmprobe](https://docs.victoriametrics.com/operator/resources/vmprobe/): added `spec.targets.kubernetes` property, that allows to configure probe for `ingress`, `pod` and `service` roles. See [#1078](https://github.com/VictoriaMetrics/operator/issues/1078) and [#1716](https://github.com/VictoriaMetrics/operator/issues/1716). * FEATURE: [vmscrapeconfig](https://docs.victoriametrics.com/operator/resources/vmscrapeconfig/): added nomad_sd_config support. See [#1809](https://github.com/VictoriaMetrics/operator/issues/1809). * FEATURE: [vmoperator](https://docs.victoriametrics.com/operator/): support VPA for vmcluster, vtcluster, vlcluster and vmauth. See [#1795](https://github.com/VictoriaMetrics/operator/issues/1795). Thanks to the @dctrwatson for the pull request [#1803](https://github.com/VictoriaMetrics/operator/pull/1803). +* FEATURE: [vmscrapeconfig](https://docs.victoriametrics.com/operator/resources/vmscrapeconfig/): added kuma_sd_config, hetzner_sd_config, eureka_sd_confiig, puppetdb_sd_config and vultr_sd_config support. * BUGFIX: [vmagent](https://docs.victoriametrics.com/operator/resources/vmagent/): previously the operator requested `nodes/proxy` RBAC permissions even though vmagent did not use them; now this permission is no longer required, reducing the default privilege footprint for users running vmagent. See [#1753](https://github.com/VictoriaMetrics/operator/issues/1753). * BUGFIX: [vmalert](https://docs.victoriametrics.com/operator/resources/vmalert/): throw error if no notifiers found. See [#1757](https://github.com/VictoriaMetrics/operator/issues/1757). diff --git a/docs/api.md b/docs/api.md index f0d66ddbb..07cc19c2f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1380,7 +1380,7 @@ Appears in: [Endpoint](#endpoint), [KubernetesSDConfig](#kubernetessdconfig), [P Authorization configures generic authorization params -Appears in: [APIServerConfig](#apiserverconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [KubernetesSDConfig](#kubernetessdconfig), [NomadSDConfig](#nomadsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -1398,19 +1398,26 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | Field | Description | | --- | --- | | authenticationMethod#
_string_ | _(Optional)_
# The authentication method, either OAuth or ManagedIdentity.
See https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | | clientID#
_string_ | _(Optional)_
Optional client ID. Only required with the OAuth authentication method. | | clientSecret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
Optional client secret. Only required with the OAuth authentication method. | | environment#
_string_ | _(Optional)_
The Azure environment. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
The port to scrape metrics from. If using the public IP address, this must
instead be specified in the relabeling rule. | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | resourceGroup#
_string_ | _(Optional)_
Optional resource group name. Limits discovery to this resource group. | | subscriptionID#
_string_ | _(Required)_
The subscription ID. Always required. | | tenantID#
_string_ | _(Optional)_
Optional tenant ID. Only required with the OAuth authentication method. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | #### BasicAuth BasicAuth allow an endpoint to authenticate over basic authentication -Appears in: [APIServerConfig](#apiserverconfig), [ConsulSDConfig](#consulsdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [KubernetesSDConfig](#kubernetessdconfig), [NomadSDConfig](#nomadsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -1622,7 +1629,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | | datacenter#
_string_ | _(Optional)_
Consul Datacenter name, if not provided it will use the local Consul Agent Datacenter. | | filter#
_string_ | _(Optional)_
Filter defines filter for /v1/catalog/services requests
See https://developer.hashicorp.com/consul/api-docs/features/filtering | -| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects.
If unset, use its default value. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | namespace#
_string_ | _(Optional)_
Namespaces are only supported in Consul Enterprise. | | nodeMeta#
_object (keys:string, values:string)_ | _(Optional)_
Node metadata key/value pairs to filter nodes for a given service. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | @@ -1676,11 +1683,13 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | Field | Description | | --- | --- | | authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
The port to scrape metrics from. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | | proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| server#
_string_ | _(Optional)_
Server is an optional DigitalOcean API server to query.
By default, https://api.digitalocean.com is used. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | #### DiscordConfig @@ -1945,6 +1954,24 @@ Appears in: [Endpoint](#endpoint), [PodMetricsEndpoint](#podmetricsendpoint), [T | seriesLimit#
_integer_ | _(Optional)_
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. | | vm_scrape_params#
_[VMScrapeParams](#vmscrapeparams)_ | _(Optional)_
VMScrapeParams defines VictoriaMetrics specific scrape parameters | +#### EurekaSDConfig + +EurekaSDConfig configurations allows retrieving scrape targets from Eureka REST API. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#eureka_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| server#
_string_ | _(Optional)_
Server is an optional URL to connect to the Eureka server.
By default, the http://localhost:8080/eureka/v2 is used. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + #### ExternalConfig ExternalConfig defines external source of configuration @@ -2014,8 +2041,12 @@ Appears in: [DiscordConfig](#discordconfig), [IncidentIOConfig](#incidentioconfi | basic_auth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth for the client. | | bearer_token_file#
_string_ | _(Optional)_
BearerTokenFile defines filename for bearer token, it must be mounted to pod. | | bearer_token_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
The secret's key that contains the bearer token
It must be at them same namespace as CRD | +| follow_redirects#
_boolean_ | _(Optional)_
FollowRedirects controls redirects for scraping. | +| noProxy#
_string_ | _(Optional)_
NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying.
IP and domain names can contain port numbers. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 client credentials used to fetch a token for the targets. | -| proxyURL#
_string_ | _(Optional)_
Optional proxy URL. | +| proxyConnectHeader#
_object (keys:string, values:[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core))_ | _(Optional)_
ProxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. | +| proxyFromEnvironment#
_boolean_ | _(Optional)_
ProxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). | +| proxyURL#
_string_ | _(Optional)_
ProxyUrl defines the HTTP proxy server to use. | | tls_config#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration for the client. | #### HTTPSDConfig @@ -2029,11 +2060,49 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | --- | --- | | authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | | basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | | proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | | url#
_string_ | _(Required)_
URL from which the targets are fetched. | +#### HTTPSDOptions + +HTTPSDOptions defines HTTP API client options +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#http-api-client-options) + +Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EurekaSDConfig](#eurekasdconfig), [HTTPSDConfig](#httpsdconfig), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [VultrSDConfig](#vultrsdconfig) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + +#### HetznerSDConfig + +HetznerSDConfig configurations allows retrieving scrape targets from Hetzner Cloud and Hetzner Robot. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#hetzner_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| port#
_integer_ | _(Optional)_
Port is an optional port to scrape metrics from | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| role#
_string_ | _(Required)_
Role defines mandatory Hetzner role for entity discovery. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + #### Image Image defines docker image settings @@ -2164,6 +2233,25 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | selectors#
_[K8SSelectorConfig](#k8sselectorconfig) array_ | _(Optional)_
Selector to select objects. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | +#### KumaSDConfig + +KumaSDConfig configurations allows retrieving scrape targets from Kuma control plane. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#kuma_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| clientID#
_string_ | _(Optional)_
ClientID is an optional client ID to send to Kuma Control Plane.
The hostname of the server where vmagent runs is used if it isn't set.
If the hostname is empty, then "vmagent" string is used as client_id. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| server#
_string_ | _(Required)_
Server must contain the URL of Kuma Control Plane's MADS xDS server. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + #### License License holds license key for enterprise features. @@ -2295,7 +2383,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) OAuth2 defines OAuth2 configuration -Appears in: [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [KubernetesSDConfig](#kubernetessdconfig), [NomadSDConfig](#nomadsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec) +Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -2308,6 +2396,28 @@ Appears in: [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloc | tls_config#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLSConfig for token_url connection
( available from v0.55.0).
Is only supported by Scrape objects family | | token_url#
_string_ | _(Required)_
The URL to fetch the token from | +#### OVHCloudSDConfig + +OVHCloudSDConfig configurations allows retrieving scrape targets from OVH Cloud VPS and OVH Cloud dedicated server. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#ovhcloud_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| applicationKey#
_string_ | _(Required)_
ApplicationKey defines a self generated token. | +| applicationSecret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Required)_
ApplicationSecret defines a generated secret. | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| consumerKey#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Required)_
ConsumerKey holds user/app specific token | +| endpoint#
_string_ | _(Optional)_
Endpoint defines OVH Cloud endpoint | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| service#
_string_ | _(Required)_
Service could be either `vps` or `dedicated_server` | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + #### OpenStackSDConfig OpenStackSDConfig allow retrieving scrape targets from OpenStack Nova instances. @@ -2441,7 +2551,7 @@ ProxyAuth represent proxy auth config Only VictoriaMetrics scrapers supports it. See https://github.com/VictoriaMetrics/VictoriaMetrics/commit/a6a71ef861444eb11fe8ec6d2387f0fc0c4aea87 -Appears in: [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [HTTPSDConfig](#httpsdconfig), [KubernetesSDConfig](#kubernetessdconfig), [NomadSDConfig](#nomadsdconfig), [VMScrapeParams](#vmscrapeparams) +Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EurekaSDConfig](#eurekasdconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [VMScrapeParams](#vmscrapeparams), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -2450,6 +2560,40 @@ Appears in: [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloc | bearer_token_file#
_string_ | _(Required)_
| | tls_config#
_[TLSConfig](#tlsconfig)_ | _(Required)_
| +#### ProxyConfig + +ProxyConfig defines proxy configs + +Appears in: [HTTPConfig](#httpconfig) + +| Field | Description | +| --- | --- | +| noProxy#
_string_ | _(Optional)_
NoProxy defines a comma-separated string that can contain IPs, CIDR notation, domain names that should be excluded from proxying.
IP and domain names can contain port numbers. | +| proxyConnectHeader#
_object (keys:string, values:[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core))_ | _(Optional)_
ProxyConnectHeader optionally specifies headers to send to proxies during CONNECT requests. | +| proxyFromEnvironment#
_boolean_ | _(Optional)_
ProxyFromEnvironment defines whether to use the proxy configuration defined by environment variables (HTTP_PROXY, HTTPS_PROXY, and NO_PROXY). | +| proxyURL#
_string_ | _(Optional)_
ProxyUrl defines the HTTP proxy server to use. | + +#### PuppetDBSDConfig + +PuppetDBSDConfig configurations allows retrieving scrape targets from PuppetDB resources. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#puppetdb_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| includeParameters#
_boolean_ | _(Optional)_
IncludeParameters defines if parameters should be included as meta labels. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| port#
_integer_ | _(Optional)_
Port defines port to scrape metrics from | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| query#
_string_ | _(Required)_
Query defines PQL query that allows to filter discovered resources. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | +| url#
_string_ | _(Required)_
URL of the PuppetDB root query endpoint | + #### PushoverConfig PushoverConfig configures notifications via Pushover. @@ -2917,7 +3061,7 @@ Appears in: [VMAlertmanagerGossipConfig](#vmalertmanagergossipconfig), [VMAlertm TLSConfig specifies TLSConfig configuration parameters. -Appears in: [APIServerConfig](#apiserverconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EmailConfig](#emailconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [KubernetesSDConfig](#kubernetessdconfig), [NomadSDConfig](#nomadsdconfig), [OAuth2](#oauth2), [OpenStackSDConfig](#openstacksdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMAuthSpec](#vmauthspec), [VMAuthUnauthorizedUserAccessSpec](#vmauthunauthorizeduseraccessspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VMUserConfigOptions](#vmuserconfigoptions), [VMUserSpec](#vmuserspec) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EmailConfig](#emailconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OAuth2](#oauth2), [OVHCloudSDConfig](#ovhcloudsdconfig), [OpenStackSDConfig](#openstacksdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMAuthSpec](#vmauthspec), [VMAuthUnauthorizedUserAccessSpec](#vmauthunauthorizeduseraccessspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VMUserConfigOptions](#vmuserconfigoptions), [VMUserSpec](#vmuserspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -4252,22 +4396,27 @@ Appears in: [VMScrapeConfig](#vmscrapeconfig) | digitalOceanSDConfigs#
_[DigitalOceanSDConfig](#digitaloceansdconfig) array_ | _(Optional)_
DigitalOceanSDConfigs defines a list of DigitalOcean service discovery configurations. | | dnsSDConfigs#
_[DNSSDConfig](#dnssdconfig) array_ | _(Optional)_
DNSSDConfigs defines a list of DNS service discovery configurations. | | ec2SDConfigs#
_[EC2SDConfig](#ec2sdconfig) array_ | _(Optional)_
EC2SDConfigs defines a list of EC2 service discovery configurations. | +| eurekaSDConfigs#
_[EurekaSDConfig](#eurekasdconfig) array_ | _(Optional)_
EurekaSDConfigs defines a list of Eureka service discovery configurations. | | fileSDConfigs#
_[FileSDConfig](#filesdconfig) array_ | _(Optional)_
FileSDConfigs defines a list of file service discovery configurations. | | follow_redirects#
_boolean_ | _(Optional)_
FollowRedirects controls redirects for scraping. | | gceSDConfigs#
_[GCESDConfig](#gcesdconfig) array_ | _(Optional)_
GCESDConfigs defines a list of GCE service discovery configurations. | +| hetznerSDConfigs#
_[HetznerSDConfig](#hetznersdconfig) array_ | _(Optional)_
HetznerSDConfigs defines a list of Hetzner service discovery configurations. | | honorLabels#
_boolean_ | _(Optional)_
HonorLabels chooses the metric's labels on collisions with target labels. | | honorTimestamps#
_boolean_ | _(Optional)_
HonorTimestamps controls whether vmagent or vmsingle respects the timestamps present in scraped data. | | httpSDConfigs#
_[HTTPSDConfig](#httpsdconfig) array_ | _(Optional)_
HTTPSDConfigs defines a list of HTTP service discovery configurations. | | interval#
_string_ | _(Optional)_
Interval at which metrics should be scraped | | kubernetesSDConfigs#
_[KubernetesSDConfig](#kubernetessdconfig) array_ | _(Optional)_
KubernetesSDConfigs defines a list of Kubernetes service discovery configurations. | +| kumaSDConfigs#
_[KumaSDConfig](#kumasdconfig) array_ | _(Optional)_
KumaSDConfigs defines a list of Kuma service discovery configurations. | | max_scrape_size#
_string_ | _(Optional)_
MaxScrapeSize defines a maximum size of scraped data for a job | | metricRelabelConfigs#
_[RelabelConfig](#relabelconfig) array_ | _(Optional)_
MetricRelabelConfigs to apply to samples after scrapping. | | nomadSDConfigs#
_[NomadSDConfig](#nomadsdconfig) array_ | _(Optional)_
NomadSDConfigs defines a list of Nomad service discovery configurations. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | openstackSDConfigs#
_[OpenStackSDConfig](#openstacksdconfig) array_ | _(Optional)_
OpenStackSDConfigs defines a list of OpenStack service discovery configurations. | +| ovhcloudSDConfigs#
_[OVHCloudSDConfig](#ovhcloudsdconfig) array_ | _(Optional)_
OVHCloudSDConfigs defines a list of OVH Cloud service discovery configurations. | | params#
_object (keys:string, values:string array)_ | _(Optional)_
Optional HTTP URL parameters | | path#
_string_ | _(Optional)_
HTTP path to scrape for metrics. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| puppetDBSDConfigs#
_[PuppetDBSDConfig](#puppetdbsdconfig) array_ | _(Optional)_
PuppetDBSDConfigs defines a list of PuppetDB service discovery configurations. | | relabelConfigs#
_[RelabelConfig](#relabelconfig) array_ | _(Optional)_
RelabelConfigs to apply to samples during service discovery. | | sampleLimit#
_integer_ | _(Optional)_
SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | | scheme#
_string_ | _(Optional)_
HTTP scheme to use for scraping. | @@ -4278,6 +4427,7 @@ Appears in: [VMScrapeConfig](#vmscrapeconfig) | staticConfigs#
_[StaticConfig](#staticconfig) array_ | _(Optional)_
StaticConfigs defines a list of static targets with a common label set. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLSConfig configuration to use when scraping the endpoint | | vm_scrape_params#
_[VMScrapeParams](#vmscrapeparams)_ | _(Optional)_
VMScrapeParams defines VictoriaMetrics specific scrape parameters | +| vultrSDConfigs#
_[VultrSDConfig](#vultrsdconfig) array_ | _(Optional)_
VultrSDConfigs defines a list of Vultr service discovery configurations. | #### VMScrapeParams @@ -4729,6 +4879,29 @@ Appears in: [Receiver](#receiver) | send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | | state_message#
_string_ | _(Optional)_
Contains long explanation of the alerted problem. | +#### VultrSDConfig + +VultrSDConfig configurations allows retrieving scrape targets from Vultr instances. +See [here](https://docs.victoriametrics.com/victoriametrics/sd_configs/#vultr_sd_configs) + +Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) + +| Field | Description | +| --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization header to use on every scrape request. | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth information to use on every scrape request. | +| firewallGroupID#
_string_ | _(Optional)_
FirewallGroupID is an optional query arguments to filter instances by firewall group id. | +| followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | +| hostname#
_string_ | _(Optional)_
Hostname is an optional query arguments to filter instances by hostname. | +| label#
_string_ | _(Optional)_
Label is an optional query arguments to filter instances by label. | +| mainIP#
_string_ | _(Optional)_
MainIP is an optional query arguments to filter instances by main ip address. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| port#
_integer_ | _(Optional)_
Port is an optional port to scrape metrics from. | +| proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | +| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| region#
_string_ | _(Optional)_
Region is an optional query arguments to filter instances by region id. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | + #### WeChatConfig WeChatConfig configures notifications via WeChat. diff --git a/internal/controller/operator/factory/converter/apis.go b/internal/controller/operator/factory/converter/apis.go index fcac4a02b..cf8e24291 100644 --- a/internal/controller/operator/factory/converter/apis.go +++ b/internal/controller/operator/factory/converter/apis.go @@ -548,3 +548,12 @@ func FilterPrefixes(src map[string]string, filterPrefixes []string) map[string]s } return dst } + +func ConvertProxyConfig(prom *promv1.ProxyConfig) vmv1beta1.ProxyConfig { + return vmv1beta1.ProxyConfig{ + ProxyURL: ptr.Deref(prom.ProxyURL, ""), + NoProxy: ptr.Deref(prom.NoProxy, ""), + ProxyFromEnvironment: ptr.Deref(prom.ProxyFromEnvironment, false), + ProxyConnectHeader: prom.ProxyConnectHeader, + } +} diff --git a/internal/controller/operator/factory/converter/v1alpha1/apis.go b/internal/controller/operator/factory/converter/v1alpha1/apis.go index f74a1acd2..3b4b40ec8 100644 --- a/internal/controller/operator/factory/converter/v1alpha1/apis.go +++ b/internal/controller/operator/factory/converter/v1alpha1/apis.go @@ -534,11 +534,11 @@ func convertHTTPConfig(prom *promv1alpha1.HTTPConfig) *vmv1beta1.HTTPConfig { BasicAuth: converter.ConvertBasicAuth(prom.BasicAuth), BearerTokenSecret: prom.BearerTokenSecret, TLSConfig: converter.ConvertSafeTLSConfig(prom.TLSConfig), - ProxyURL: ptr.Deref(prom.ProxyURL, ""), Authorization: converter.ConvertAuthorization(prom.Authorization, nil), OAuth2: converter.ConvertOAuth(prom.OAuth2), + ProxyConfig: converter.ConvertProxyConfig(&prom.ProxyConfig), + FollowRedirects: prom.FollowRedirects, } - // Add fallback to proxyUrl if len(hc.ProxyURL) == 0 && prom.ProxyURLOriginal != nil { hc.ProxyURL = *prom.ProxyURLOriginal } diff --git a/internal/controller/operator/factory/converter/v1alpha1/apis_test.go b/internal/controller/operator/factory/converter/v1alpha1/apis_test.go index 2e5c67d2b..91fc0fd52 100644 --- a/internal/controller/operator/factory/converter/v1alpha1/apis_test.go +++ b/internal/controller/operator/factory/converter/v1alpha1/apis_test.go @@ -196,21 +196,25 @@ func TestConvertScrapeConfig(t *testing.T) { HTTPSDConfigs: []vmv1beta1.HTTPSDConfig{ { URL: "http://test1.com", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - Credentials: &corev1.SecretKeySelector{ - Key: "token", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + Credentials: &corev1.SecretKeySelector{ + Key: "token", + }, }, }, }, { URL: "http://test2.com", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ConfigMap: &corev1.ConfigMapKeySelector{Key: "ca.crt"}}, - Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{Key: "cert.pem"}}, - KeySecret: &corev1.SecretKeySelector{Key: "key"}, - ServerName: "test", - InsecureSkipVerify: true, + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ConfigMap: &corev1.ConfigMapKeySelector{Key: "ca.crt"}}, + Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{Key: "cert.pem"}}, + KeySecret: &corev1.SecretKeySelector{Key: "key"}, + ServerName: "test", + InsecureSkipVerify: true, + }, }, }, }, @@ -298,7 +302,7 @@ func TestConvertScrapeConfig(t *testing.T) { Name: "f1", Values: []string{"1"}, }}, - Port: ptr.To(80), + Port: ptr.To[int32](80), }}, }, }, @@ -350,7 +354,7 @@ func TestConvertScrapeConfig(t *testing.T) { Project: "eu-project", Zone: vmv1beta1.StringOrArray{"zone-1"}, TagSeparator: ptr.To(""), - Port: ptr.To(80), + Port: ptr.To[int32](80), }}, }, }, @@ -440,10 +444,12 @@ func TestConvertScrapeConfig(t *testing.T) { Server: "https://nomad.example.com:4646", Namespace: ptr.To("default"), AllowStale: ptr.To(true), - Authorization: &vmv1beta1.Authorization{ - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "nomad-secret"}, - Key: "NOMAD_TOKEN", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "nomad-secret"}, + Key: "NOMAD_TOKEN", + }, }, }, }, @@ -451,10 +457,12 @@ func TestConvertScrapeConfig(t *testing.T) { Server: "https://nomad.example.com:4646", Namespace: ptr.To("staging"), AllowStale: ptr.To(true), - Authorization: &vmv1beta1.Authorization{ - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "nomad-secret"}, - Key: "NOMAD_TOKEN", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "nomad-secret"}, + Key: "NOMAD_TOKEN", + }, }, }, }, @@ -518,18 +526,20 @@ func TestConvertScrapeConfig(t *testing.T) { want: vmv1beta1.VMScrapeConfig{ Spec: vmv1beta1.VMScrapeConfigSpec{ NomadSDConfigs: []vmv1beta1.NomadSDConfig{{ - Server: "https://nomad.example.com:4646", - Namespace: ptr.To("prod"), - Region: ptr.To("us-west-1"), - TagSeparator: ptr.To(","), - AllowStale: ptr.To(true), - FollowRedirects: ptr.To(true), - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "user"}, - Password: corev1.SecretKeySelector{Key: "pass"}, - }, - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + Server: "https://nomad.example.com:4646", + Namespace: ptr.To("prod"), + Region: ptr.To("us-west-1"), + TagSeparator: ptr.To(","), + AllowStale: ptr.To(true), + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + FollowRedirects: ptr.To(true), + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "user"}, + Password: corev1.SecretKeySelector{Key: "pass"}, + }, + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, }, }}, }, diff --git a/internal/controller/operator/factory/vmagent/scrapes_test.go b/internal/controller/operator/factory/vmagent/scrapes_test.go index f3151e244..fc7069183 100644 --- a/internal/controller/operator/factory/vmagent/scrapes_test.go +++ b/internal/controller/operator/factory/vmagent/scrapes_test.go @@ -1849,9 +1849,9 @@ scrape_configs: [] Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{ - { - Server: "some", + ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{{ + Server: "some", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ TLSConfig: &vmv1beta1.TLSConfig{ CAFile: "/some/other/path", CertFile: "/some/other/cert", @@ -1859,7 +1859,7 @@ scrape_configs: [] ServerName: "my-name", }, }, - }, + }}, }, }, &corev1.ConfigMap{ @@ -2177,15 +2177,14 @@ scrape_configs: [] }, }, }, - }, - ) + }) // missing refs f(&vmv1beta1.VMScrapeConfig{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMScrapeConfigSpec{ - ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{ - { - Server: "http://consul.example.com", + ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{{ + Server: "http://consul.example.com", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ BasicAuth: &vmv1beta1.BasicAuth{ Username: corev1.SecretKeySelector{ Key: "username", @@ -2195,10 +2194,9 @@ scrape_configs: [] }, }, }, - }, + }}, }, - }, - ) + }) commonEndpointAuthWithMissingRef := vmv1beta1.EndpointAuth{ BasicAuth: &vmv1beta1.BasicAuth{ Username: corev1.SecretKeySelector{ @@ -2219,11 +2217,9 @@ scrape_configs: [] f(&vmv1beta1.VMStaticScrape{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMStaticScrapeSpec{ - TargetEndpoints: []*vmv1beta1.TargetEndpoint{ - { - EndpointAuth: commonEndpointAuthWithMissingRef, - }, - }, + TargetEndpoints: []*vmv1beta1.TargetEndpoint{{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }}, }, }) f(&vmv1beta1.VMNodeScrape{ @@ -2236,22 +2232,18 @@ scrape_configs: [] f(&vmv1beta1.VMPodScrape{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMPodScrapeSpec{ - PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ - { - EndpointAuth: commonEndpointAuthWithMissingRef, - }, - }, + PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }}, }, }) f(&vmv1beta1.VMServiceScrape{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMServiceScrapeSpec{ - Endpoints: []vmv1beta1.Endpoint{ - { - EndpointAuth: commonEndpointAuthWithMissingRef, - }, - }, + Endpoints: []vmv1beta1.Endpoint{{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }}, }, }) @@ -2260,11 +2252,9 @@ scrape_configs: [] ObjectMeta: commonMeta, Spec: vmv1beta1.VMServiceScrapeSpec{ ScrapeClassName: ptr.To("non-exist"), - Endpoints: []vmv1beta1.Endpoint{ - { - Port: "9090", - }, - }, + Endpoints: []vmv1beta1.Endpoint{{ + Port: "9090", + }}, }, }) @@ -2273,13 +2263,9 @@ scrape_configs: [] ObjectMeta: commonMeta, Spec: vmv1beta1.VMPodScrapeSpec{ ScrapeClassName: ptr.To("non-exist"), - PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ - { - Port: ptr.To("9090"), - }, - }, + PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{{ + Port: ptr.To("9090"), + }}, }, - }, - ) - + }) } diff --git a/internal/controller/operator/factory/vmalertmanager/config.go b/internal/controller/operator/factory/vmalertmanager/config.go index a5373608e..3f4f0eff4 100644 --- a/internal/controller/operator/factory/vmalertmanager/config.go +++ b/internal/controller/operator/factory/vmalertmanager/config.go @@ -1569,7 +1569,9 @@ func (cb *configBuilder) buildHTTPConfig(httpCfg *vmv1beta1.HTTPConfig) (yaml.Ma if len(tokenAuth) > 0 { r = append(r, yaml.MapItem{Key: "authorization", Value: tokenAuth}) } - + if httpCfg.FollowRedirects != nil { + r = append(r, yaml.MapItem{Key: "follow_redirects", Value: *httpCfg.FollowRedirects}) + } if httpCfg.OAuth2 != nil { cfg, err := cb.cache.OAuth2ToYAML(cb.namespace, httpCfg.OAuth2) if err != nil { @@ -1577,9 +1579,43 @@ func (cb *configBuilder) buildHTTPConfig(httpCfg *vmv1beta1.HTTPConfig) (yaml.Ma } r = append(r, cfg...) } + cfg, err := cb.buildProxyConfig(&httpCfg.ProxyConfig) + if err != nil { + return nil, err + } + if len(cfg) > 0 { + r = append(r, cfg...) + } + return r, nil +} - if len(httpCfg.ProxyURL) > 0 { - r = append(r, yaml.MapItem{Key: "proxy_url", Value: httpCfg.ProxyURL}) +func (cb *configBuilder) buildProxyConfig(proxyCfg *vmv1beta1.ProxyConfig) (yaml.MapSlice, error) { + var r yaml.MapSlice + if len(proxyCfg.ProxyURL) > 0 { + r = append(r, yaml.MapItem{Key: "proxy_url", Value: proxyCfg.ProxyURL}) + } + if len(proxyCfg.NoProxy) > 0 { + r = append(r, yaml.MapItem{Key: "no_proxy", Value: proxyCfg.NoProxy}) + } + if proxyCfg.ProxyFromEnvironment { + r = append(r, yaml.MapItem{Key: "proxy_from_environment", Value: proxyCfg.ProxyFromEnvironment}) + } + if len(proxyCfg.ProxyConnectHeader) > 0 { + var h yaml.MapSlice + for k, vs := range proxyCfg.ProxyConnectHeader { + var secrets []string + for i, v := range vs { + secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, &v) + if err != nil { + return nil, fmt.Errorf("cannot find secret for proxy_connect_header[%q][%d]: %w", k, i, err) + } + secrets = append(secrets, secret) + } + h = append(h, yaml.MapItem{Key: k, Value: secrets}) + } + if len(h) > 0 { + r = append(r, yaml.MapItem{Key: "proxy_connect_header", Value: h}) + } } return r, nil } diff --git a/internal/controller/operator/factory/vmalertmanager/config_test.go b/internal/controller/operator/factory/vmalertmanager/config_test.go index c591a251c..82678a224 100644 --- a/internal/controller/operator/factory/vmalertmanager/config_test.go +++ b/internal/controller/operator/factory/vmalertmanager/config_test.go @@ -1086,6 +1086,16 @@ templates: [] "CLOUD_PAT": []byte(`personal-token`), }, }, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "connect-header", + Namespace: "default", + }, + Data: map[string][]byte{ + "ch-value1": []byte(`value1`), + "ch-value2": []byte(`value2`), + }, + }, &vmv1beta1.VMAlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ Name: "base", @@ -1128,6 +1138,25 @@ templates: [] { SendResolved: ptr.To(true), HTTPConfig: &vmv1beta1.HTTPConfig{ + ProxyConfig: vmv1beta1.ProxyConfig{ + ProxyURL: "http://localhost:8080", + ProxyConnectHeader: map[string][]corev1.SecretKeySelector{ + "test": { + { + Key: "ch-value1", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "connect-header", + }, + }, + { + Key: "ch-value2", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "connect-header", + }, + }, + }, + }, + }, BasicAuth: &vmv1beta1.BasicAuth{ Username: corev1.SecretKeySelector{ Key: "CLOUD_USER", @@ -1201,6 +1230,11 @@ receivers: basic_auth: username: username password: personal-token + proxy_url: http://localhost:8080 + proxy_connect_header: + test: + - value1 + - value2 send_resolved: true project: main issue_type: BUG diff --git a/internal/controller/operator/factory/vmscrapes/scrapeconfig.go b/internal/controller/operator/factory/vmscrapes/scrapeconfig.go index a98d6f1bb..d38e70623 100644 --- a/internal/controller/operator/factory/vmscrapes/scrapeconfig.go +++ b/internal/controller/operator/factory/vmscrapes/scrapeconfig.go @@ -20,12 +20,10 @@ func generateScrapeConfig( spec := &sc.Spec se := &sp.CommonScrapeSecurityEnforcements jobName := fmt.Sprintf("scrapeConfig/%s/%s", sc.Namespace, sc.Name) - cfg := yaml.MapSlice{ - { - Key: "job_name", - Value: jobName, - }, - } + cfg := yaml.MapSlice{{ + Key: "job_name", + Value: jobName, + }} scrapeClass := getScrapeClass(spec.ScrapeClassName, sp) if scrapeClass != nil { @@ -85,12 +83,10 @@ func generateScrapeConfig( if len(spec.FileSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.FileSDConfigs)) for i, config := range spec.FileSDConfigs { - configs[i] = []yaml.MapItem{ - { - Key: "files", - Value: config.Files, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "files", + Value: config.Files, + }} } cfg = append(cfg, yaml.MapItem{ Key: "file_sd_configs", @@ -102,43 +98,15 @@ func generateScrapeConfig( if len(spec.HTTPSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.HTTPSDConfigs)) for i, config := range spec.HTTPSDConfigs { - configs[i] = []yaml.MapItem{ - { - Key: "url", - Value: config.URL, - }, - } - - if config.BasicAuth != nil { - if c, err := ac.BasicAuthToYAML(sc.Namespace, config.BasicAuth); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: c}) - } - } - if config.Authorization != nil { - if c, err := ac.AuthorizationToYAML(sc.Namespace, config.Authorization); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.TLSConfig != nil { - if c, err := ac.TLSToYAML(sc.Namespace, "", config.TLSConfig); err != nil { - return nil, err - } else if len(c) > 0 { - configs[i] = append(configs[i], yaml.MapItem{Key: "tls_config", Value: c}) - } - } - if config.ProxyURL != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) - } - if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(sc.Namespace, config.ProxyClientConfig); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } + configs[i] = []yaml.MapItem{{ + Key: "url", + Value: config.URL, + }} + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } } cfg = append(cfg, yaml.MapItem{ @@ -152,67 +120,21 @@ func generateScrapeConfig( configs := make([][]yaml.MapItem, len(spec.KubernetesSDConfigs)) for i, config := range spec.KubernetesSDConfigs { if config.APIServer != nil { - configs[i] = []yaml.MapItem{ - { - Key: "api_server", - Value: config.APIServer, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "api_server", + Value: config.APIServer, + }} } configs[i] = append(configs[i], yaml.MapItem{ Key: "role", Value: config.Role, }) - if config.BasicAuth != nil { - if c, err := ac.BasicAuthToYAML(sc.Namespace, config.BasicAuth); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: c}) - } - } - if config.Authorization != nil { - if c, err := ac.AuthorizationToYAML(sc.Namespace, config.Authorization); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.TLSConfig != nil { - if c, err := ac.TLSToYAML(sc.Namespace, "", config.TLSConfig); err != nil { - return nil, err - } else if len(c) > 0 { - configs[i] = append(configs[i], yaml.MapItem{Key: "tls_config", Value: c}) - } - } - if config.OAuth2 != nil { - if c, err := ac.OAuth2ToYAML(sc.Namespace, config.OAuth2); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.ProxyURL != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) - } - if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(sc.Namespace, config.ProxyClientConfig); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - - if config.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: config.FollowRedirects}) - } if config.Namespaces != nil { - namespaces := []yaml.MapItem{ - { - Key: "names", - Value: config.Namespaces.Names, - }, - } + namespaces := []yaml.MapItem{{ + Key: "names", + Value: config.Namespaces.Names, + }} if config.Namespaces.IncludeOwnNamespace != nil { namespaces = append(namespaces, yaml.MapItem{ @@ -226,6 +148,12 @@ func generateScrapeConfig( Value: namespaces, }) } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } configs[i] = addAttachMetadata(configs[i], &config.AttachMetadata, config.Role) selectors := make([][]yaml.MapItem, len(config.Selectors)) for i, s := range config.Selectors { @@ -342,49 +270,11 @@ func generateScrapeConfig( Value: config.Filter, }) } - - if config.BasicAuth != nil { - if c, err := ac.BasicAuthToYAML(sc.Namespace, config.BasicAuth); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: c}) - } - } - if config.Authorization != nil { - if c, err := ac.AuthorizationToYAML(sc.Namespace, config.Authorization); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.OAuth2 != nil { - if c, err := ac.OAuth2ToYAML(sc.Namespace, config.OAuth2); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.ProxyURL != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) - } - if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(sc.Namespace, config.ProxyClientConfig); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - - if config.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: config.FollowRedirects}) - } - - if config.TLSConfig != nil { - if c, err := ac.TLSToYAML(sc.Namespace, "", config.TLSConfig); err != nil { - return nil, err - } else if len(c) > 0 { - configs[i] = append(configs[i], yaml.MapItem{Key: "tls_config", Value: c}) - } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } } @@ -398,12 +288,10 @@ func generateScrapeConfig( if len(spec.DNSSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.DNSSDConfigs)) for i, config := range spec.DNSSDConfigs { - configs[i] = []yaml.MapItem{ - { - Key: "names", - Value: config.Names, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "names", + Value: config.Names, + }} if config.Type != nil { configs[i] = append(configs[i], yaml.MapItem{ @@ -430,12 +318,10 @@ func generateScrapeConfig( configs := make([][]yaml.MapItem, len(spec.EC2SDConfigs)) for i, config := range spec.EC2SDConfigs { if config.Region != nil { - configs[i] = []yaml.MapItem{ - { - Key: "region", - Value: config.Region, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "region", + Value: config.Region, + }} } if config.AccessKey != nil { @@ -484,12 +370,10 @@ func generateScrapeConfig( configs := make([][]yaml.MapItem, len(spec.AzureSDConfigs)) for i, config := range spec.AzureSDConfigs { if config.Environment != nil { - configs[i] = []yaml.MapItem{ - { - Key: "environment", - Value: config.Environment, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "environment", + Value: config.Environment, + }} } if config.AuthenticationMethod != nil { @@ -540,6 +424,12 @@ func generateScrapeConfig( Value: config.Port, }) } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } } cfg = append(cfg, yaml.MapItem{ Key: "azure_sd_configs", @@ -551,12 +441,10 @@ func generateScrapeConfig( if len(spec.GCESDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.GCESDConfigs)) for i, config := range spec.GCESDConfigs { - configs[i] = []yaml.MapItem{ - { - Key: "project", - Value: config.Project, - }, - } + configs[i] = []yaml.MapItem{{ + Key: "project", + Value: config.Project, + }} configs[i] = append(configs[i], yaml.MapItem{ Key: "zone", @@ -593,12 +481,10 @@ func generateScrapeConfig( if len(spec.OpenStackSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.OpenStackSDConfigs)) for i, config := range spec.OpenStackSDConfigs { - configs[i] = []yaml.MapItem{ - { - Key: "role", - Value: strings.ToLower(config.Role), - }, - } + configs[i] = []yaml.MapItem{{ + Key: "role", + Value: strings.ToLower(config.Role), + }} configs[i] = append(configs[i], yaml.MapItem{ Key: "region", @@ -723,52 +609,234 @@ func generateScrapeConfig( if len(spec.DigitalOceanSDConfigs) > 0 { configs := make([][]yaml.MapItem, len(spec.DigitalOceanSDConfigs)) for i, config := range spec.DigitalOceanSDConfigs { - if config.Authorization != nil { - if c, err := ac.AuthorizationToYAML(sc.Namespace, config.Authorization); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } + if config.Port != nil { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "port", + Value: config.Port, + }) } - if config.OAuth2 != nil { - if c, err := ac.OAuth2ToYAML(sc.Namespace, config.OAuth2); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } - if config.ProxyURL != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) + } + cfg = append(cfg, yaml.MapItem{ + Key: "digitalocean_sd_configs", + Value: configs, + }) + } + + // build hentznerSDConfig + if len(spec.HetznerSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.HetznerSDConfigs)) + for i, config := range spec.HetznerSDConfigs { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "role", + Value: strings.ToLower(config.Role), + }) + if config.Port != nil { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "port", + Value: config.Port, + }) } - if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(sc.Namespace, config.ProxyClientConfig); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } + } + cfg = append(cfg, yaml.MapItem{ + Key: "hetzner_sd_configs", + Value: configs, + }) + } - if config.FollowRedirects != nil { - cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: config.FollowRedirects}) + // build eurekaSDConfig + if len(spec.EurekaSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.EurekaSDConfigs)) + for i, config := range spec.EurekaSDConfigs { + if len(config.Server) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "server", + Value: config.Server, + }) } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } + } + cfg = append(cfg, yaml.MapItem{ + Key: "eureka_sd_configs", + Value: configs, + }) + } - if config.TLSConfig != nil { - if c, err := ac.TLSToYAML(sc.Namespace, "", config.TLSConfig); err != nil { - return nil, err - } else if len(c) > 0 { - configs[i] = append(configs[i], yaml.MapItem{Key: "tls_config", Value: c}) - } + // build puppetDBSDConfig + if len(spec.PuppetDBSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.PuppetDBSDConfigs)) + for i, config := range spec.PuppetDBSDConfigs { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "url", + Value: config.URL, + }, yaml.MapItem{ + Key: "query", + Value: config.Query, + }) + if config.IncludeParameters { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "include_parameters", + Value: config.IncludeParameters, + }) + } + if config.Port != nil { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "port", + Value: config.Port, + }) + } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } + } + cfg = append(cfg, yaml.MapItem{ + Key: "puppetdb_sd_configs", + Value: configs, + }) + } + // build vultrSDConfig + if len(spec.VultrSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.VultrSDConfigs)) + for i, config := range spec.VultrSDConfigs { + if len(config.Label) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "label", + Value: config.Label, + }) + } + if len(config.MainIP) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "main_ip", + Value: config.MainIP, + }) + } + if len(config.Region) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "region", + Value: config.Region, + }) + } + if len(config.FirewallGroupID) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "firewall_group_id", + Value: config.FirewallGroupID, + }) + } + if len(config.Hostname) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "hostname", + Value: config.Hostname, + }) + } if config.Port != nil { configs[i] = append(configs[i], yaml.MapItem{ Key: "port", Value: config.Port, }) } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } } cfg = append(cfg, yaml.MapItem{ - Key: "digitalocean_sd_configs", + Key: "vultr_sd_configs", + Value: configs, + }) + } + + // build kumaSDConfig + if len(spec.KumaSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.KumaSDConfigs)) + for i, config := range spec.KumaSDConfigs { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "server", + Value: config.Server, + }) + if len(config.ClientID) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "client_id", + Value: config.ClientID, + }) + } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } + } + cfg = append(cfg, yaml.MapItem{ + Key: "kuma_sd_configs", + Value: configs, + }) + } + + // build ovhcloudSDConfig + if len(spec.OVHCloudSDConfigs) > 0 { + configs := make([][]yaml.MapItem, len(spec.OVHCloudSDConfigs)) + for i, config := range spec.OVHCloudSDConfigs { + svc := config.Service + switch svc { + case "VPS": + svc = "vps" + case "DedicatedServer": + svc = "dedicated_server" + } + configs[i] = append(configs[i], yaml.MapItem{ + Key: "application_key", + Value: config.ApplicationKey, + }, yaml.MapItem{ + Key: "service", + Value: svc, + }) + if secret, err := ac.LoadKeyFromSecret(sc.Namespace, config.ApplicationSecret); err != nil { + return nil, err + } else { + configs[i] = append(configs[i], yaml.MapItem{Key: "application_secret", Value: secret}) + } + if secret, err := ac.LoadKeyFromSecret(sc.Namespace, config.ConsumerKey); err != nil { + return nil, err + } else { + configs[i] = append(configs[i], yaml.MapItem{Key: "consumer_key", Value: secret}) + } + if len(config.Endpoint) > 0 { + configs[i] = append(configs[i], yaml.MapItem{ + Key: "endpoint", + Value: config.Endpoint, + }) + } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) + } + } + cfg = append(cfg, yaml.MapItem{ + Key: "ovhcloud_sd_configs", Value: configs, }) } @@ -809,49 +877,11 @@ func generateScrapeConfig( Value: config.AllowStale, }) } - - if config.BasicAuth != nil { - if c, err := ac.BasicAuthToYAML(sc.Namespace, config.BasicAuth); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], yaml.MapItem{Key: "basic_auth", Value: c}) - } - } - if config.Authorization != nil { - if c, err := ac.AuthorizationToYAML(sc.Namespace, config.Authorization); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.OAuth2 != nil { - if c, err := ac.OAuth2ToYAML(sc.Namespace, config.OAuth2); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - if config.ProxyURL != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) - } - if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(sc.Namespace, config.ProxyClientConfig); err != nil { - return nil, err - } else { - configs[i] = append(configs[i], c...) - } - } - - if config.FollowRedirects != nil { - configs[i] = append(configs[i], yaml.MapItem{Key: "follow_redirects", Value: config.FollowRedirects}) - } - - if config.TLSConfig != nil { - if c, err := ac.TLSToYAML(sc.Namespace, "", config.TLSConfig); err != nil { - return nil, err - } else if len(c) > 0 { - configs[i] = append(configs[i], yaml.MapItem{Key: "tls_config", Value: c}) - } + c, err := generateHTTPSDOptions(config.HTTPSDOptions, sc.Namespace, ac) + if err != nil { + return nil, err + } else if len(c) > 0 { + configs[i] = append(configs[i], c...) } } @@ -862,3 +892,51 @@ func generateScrapeConfig( } return cfg, nil } + +func generateHTTPSDOptions(config vmv1beta1.HTTPSDOptions, namespace string, ac *build.AssetsCache) ([]yaml.MapItem, error) { + var cfg []yaml.MapItem + if config.BasicAuth != nil { + if c, err := ac.BasicAuthToYAML(namespace, config.BasicAuth); err != nil { + return nil, err + } else { + cfg = append(cfg, yaml.MapItem{Key: "basic_auth", Value: c}) + } + } + if config.Authorization != nil { + if c, err := ac.AuthorizationToYAML(namespace, config.Authorization); err != nil { + return nil, err + } else { + cfg = append(cfg, c...) + } + } + if config.OAuth2 != nil { + if c, err := ac.OAuth2ToYAML(namespace, config.OAuth2); err != nil { + return nil, err + } else { + cfg = append(cfg, c...) + } + } + if config.ProxyURL != nil { + cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) + } + if config.ProxyClientConfig != nil { + if c, err := ac.ProxyAuthToYAML(namespace, config.ProxyClientConfig); err != nil { + return nil, err + } else { + cfg = append(cfg, c...) + } + } + + if config.FollowRedirects != nil { + cfg = append(cfg, yaml.MapItem{Key: "follow_redirects", Value: config.FollowRedirects}) + } + + if config.TLSConfig != nil { + if c, err := ac.TLSToYAML(namespace, "", config.TLSConfig); err != nil { + return nil, err + } else if len(c) > 0 { + cfg = append(cfg, yaml.MapItem{Key: "tls_config", Value: c}) + } + } + return cfg, nil +} diff --git a/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go b/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go index ab41994eb..17da8a361 100644 --- a/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go +++ b/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go @@ -195,34 +195,38 @@ file_sd_configs: Spec: vmv1beta1.VMScrapeConfigSpec{ HTTPSDConfigs: []vmv1beta1.HTTPSDConfig{ { - URL: "http://www.test1.com", - ProxyURL: ptr.To("http://www.proxy.com"), + URL: "http://www.test1.com", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + ProxyURL: ptr.To("http://www.proxy.com"), + }, }, { URL: "http://www.test2.com", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - Credentials: &corev1.SecretKeySelector{ - Key: "cred", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "auth-secret", - }, - }, - }, - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + Credentials: &corev1.SecretKeySelector{ + Key: "cred", LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + Name: "auth-secret", }, }, }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, + }, + }, + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cert", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-secret", + }, }, }, }, @@ -294,8 +298,10 @@ http_sd_configs: Field: "test", }, }, - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, }, }, { @@ -349,40 +355,32 @@ kubernetes_sd_configs: Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{ - { - Server: "localhost:8500", - TokenRef: &corev1.SecretKeySelector{Key: "consul_token"}, - Datacenter: ptr.To("dc1"), - NodeMeta: map[string]string{"worker": "1"}, - Filter: `filter=NodeMeta.os == "linux"`, - }, - }, - DNSSDConfigs: []vmv1beta1.DNSSDConfig{ - { - Names: []string{"vmagent-0.vmagent.default.svc.cluster.local"}, - Port: ptr.To(8429), - }, - }, - EC2SDConfigs: []vmv1beta1.EC2SDConfig{ - { - Region: ptr.To("us-west-2"), - Port: ptr.To(9404), - Filters: []*vmv1beta1.EC2Filter{{ - Name: "instance-id", - Values: []string{"i-98765432109876543", "i-12345678901234567"}, - }}, - }, - }, - AzureSDConfigs: []vmv1beta1.AzureSDConfig{ - { - Environment: ptr.To("AzurePublicCloud"), - SubscriptionID: "1", - TenantID: ptr.To("u1"), - ResourceGroup: ptr.To("rg1"), - Port: ptr.To(80), - }, - }, + ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{{ + Server: "localhost:8500", + TokenRef: &corev1.SecretKeySelector{Key: "consul_token"}, + Datacenter: ptr.To("dc1"), + NodeMeta: map[string]string{"worker": "1"}, + Filter: `filter=NodeMeta.os == "linux"`, + }}, + DNSSDConfigs: []vmv1beta1.DNSSDConfig{{ + Names: []string{"vmagent-0.vmagent.default.svc.cluster.local"}, + Port: ptr.To[int32](8429), + }}, + EC2SDConfigs: []vmv1beta1.EC2SDConfig{{ + Region: ptr.To("us-west-2"), + Port: ptr.To[int32](9404), + Filters: []*vmv1beta1.EC2Filter{{ + Name: "instance-id", + Values: []string{"i-98765432109876543", "i-12345678901234567"}, + }}, + }}, + AzureSDConfigs: []vmv1beta1.AzureSDConfig{{ + Environment: ptr.To("AzurePublicCloud"), + SubscriptionID: "1", + TenantID: ptr.To("u1"), + ResourceGroup: ptr.To("rg1"), + Port: ptr.To[int32](80), + }}, GCESDConfigs: []vmv1beta1.GCESDConfig{ { Project: "eu-project", @@ -395,23 +393,21 @@ kubernetes_sd_configs: TagSeparator: ptr.To("/"), }, }, - OpenStackSDConfigs: []vmv1beta1.OpenStackSDConfig{ - { - Role: "instance", - IdentityEndpoint: ptr.To("http://localhost:5000/v3"), - Username: ptr.To("user1"), - UserID: ptr.To("1"), - Password: &corev1.SecretKeySelector{ - Key: "pass", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, - }, - ProjectName: ptr.To("poc"), - AllTenants: ptr.To(true), - DomainName: ptr.To("default"), + OpenStackSDConfigs: []vmv1beta1.OpenStackSDConfig{{ + Role: "instance", + IdentityEndpoint: ptr.To("http://localhost:5000/v3"), + Username: ptr.To("user1"), + UserID: ptr.To("1"), + Password: &corev1.SecretKeySelector{ + Key: "pass", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, }, - }, - DigitalOceanSDConfigs: []vmv1beta1.DigitalOceanSDConfig{ - { + ProjectName: ptr.To("poc"), + AllTenants: ptr.To(true), + DomainName: ptr.To("default"), + }}, + DigitalOceanSDConfigs: []vmv1beta1.DigitalOceanSDConfig{{ + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ OAuth2: &vmv1beta1.OAuth2{ Scopes: []string{"scope-1"}, TokenURL: "http://some-token-url", @@ -424,7 +420,7 @@ kubernetes_sd_configs: }, }, }, - }, + }}, }, }, predefinedObjects: []runtime.Object{ @@ -527,15 +523,13 @@ digitalocean_sd_configs: Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - NomadSDConfigs: []vmv1beta1.NomadSDConfig{ - { - Server: "localhost:4646", - Namespace: ptr.To("default"), - Region: ptr.To("global"), - TagSeparator: ptr.To(","), - AllowStale: ptr.To(true), - }, - }, + NomadSDConfigs: []vmv1beta1.NomadSDConfig{{ + Server: "localhost:4646", + Namespace: ptr.To("default"), + Region: ptr.To("global"), + TagSeparator: ptr.To(","), + AllowStale: ptr.To(true), + }}, }, }, want: `job_name: scrapeConfig/default/nomadsd-1 @@ -550,6 +544,208 @@ nomad_sd_configs: `, }) + // kumaSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kumasd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + KumaSDConfigs: []vmv1beta1.KumaSDConfig{{ + Server: "localhost:8080", + ClientID: "kuma", + }}, + }, + }, + want: `job_name: scrapeConfig/default/kumasd-1 +honor_labels: false +relabel_configs: [] +kuma_sd_configs: +- server: localhost:8080 + client_id: kuma +`, + }) + + // ovhcloudSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + predefinedObjects: []runtime.Object{ + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "auth-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + "cred": []byte("auth-secret"), + }, + }, + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "auth", + Namespace: "default", + }, + Data: map[string][]byte{ + "cred": []byte("auth-secret"), + }, + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ovhsd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + OVHCloudSDConfigs: []vmv1beta1.OVHCloudSDConfig{{ + ApplicationKey: "test", + ApplicationSecret: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth"}, + Key: "cred", + }, + ConsumerKey: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, + Key: "cred", + }, + Service: "vps", + Endpoint: "http://ovhcloud", + }}, + }, + }, + want: `job_name: scrapeConfig/default/ovhsd-1 +honor_labels: false +relabel_configs: [] +ovhcloud_sd_configs: +- application_key: test + service: vps + application_secret: auth-secret + consumer_key: auth-secret + endpoint: http://ovhcloud +`, + }) + + // puppetDBSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "puppetdbsd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + PuppetDBSDConfigs: []vmv1beta1.PuppetDBSDConfig{{ + URL: "http://test", + Query: "some query", + }}, + }, + }, + want: `job_name: scrapeConfig/default/puppetdbsd-1 +honor_labels: false +relabel_configs: [] +puppetdb_sd_configs: +- url: http://test + query: some query +`, + }) + + // vultrDBSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "vultrsd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + VultrSDConfigs: []vmv1beta1.VultrSDConfig{{ + Label: "label", + MainIP: "ip", + }}, + }, + }, + want: `job_name: scrapeConfig/default/vultrsd-1 +honor_labels: false +relabel_configs: [] +vultr_sd_configs: +- label: label + main_ip: ip +`, + }) + + // hetznerSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "hetznersd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + HetznerSDConfigs: []vmv1beta1.HetznerSDConfig{{ + Role: "hcloud", + }}, + }, + }, + want: `job_name: scrapeConfig/default/hetznersd-1 +honor_labels: false +relabel_configs: [] +hetzner_sd_configs: +- role: hcloud +`, + }) + + // eurekaSDConfig + f(opts{ + cr: &vmv1beta1.VMAgent{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default-vmagent", + Namespace: "default", + }, + }, + sc: &vmv1beta1.VMScrapeConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "eurekasd-1", + Namespace: "default", + }, + Spec: vmv1beta1.VMScrapeConfigSpec{ + EurekaSDConfigs: []vmv1beta1.EurekaSDConfig{{ + Server: "http://localhost:8080", + }}, + }, + }, + want: `job_name: scrapeConfig/default/eurekasd-1 +honor_labels: false +relabel_configs: [] +eureka_sd_configs: +- server: http://localhost:8080 +`, + }) + // configs with auth and empty type f(opts{ cr: &vmv1beta1.VMAgent{ @@ -567,56 +763,68 @@ nomad_sd_configs: HTTPSDConfigs: []vmv1beta1.HTTPSDConfig{ { URL: "http://www.test1.com", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, - Key: "cred", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, + Key: "cred", + }, }, }, }, { URL: "http://www.test2.com", - Authorization: &vmv1beta1.Authorization{ - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, - Key: "cred", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, + Key: "cred", + }, }, }, }, { URL: "http://www.test3.com", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - CredentialsFile: "file", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + CredentialsFile: "file", + }, }, }, }, KubernetesSDConfigs: []vmv1beta1.KubernetesSDConfig{ { Role: "endpoints", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "auth"}, - Key: "cred", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth"}, + Key: "cred", + }, }, }, }, { Role: "endpoints", - Authorization: &vmv1beta1.Authorization{ - Credentials: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, - Key: "cred", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Credentials: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "auth-secret"}, + Key: "cred", + }, }, }, }, { Role: "endpoints", - Authorization: &vmv1beta1.Authorization{ - Type: "Bearer", - CredentialsFile: "file", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + Authorization: &vmv1beta1.Authorization{ + Type: "Bearer", + CredentialsFile: "file", + }, }, }, }, diff --git a/internal/controller/operator/factory/vmsingle/scrapes_test.go b/internal/controller/operator/factory/vmsingle/scrapes_test.go index 49d77f0f3..ec6f1c991 100644 --- a/internal/controller/operator/factory/vmsingle/scrapes_test.go +++ b/internal/controller/operator/factory/vmsingle/scrapes_test.go @@ -1717,11 +1717,13 @@ scrape_configs: [] ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{ { Server: "some", - TLSConfig: &vmv1beta1.TLSConfig{ - CAFile: "/some/other/path", - CertFile: "/some/other/cert", - KeyFile: "/some/other/key", - ServerName: "my-name", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + TLSConfig: &vmv1beta1.TLSConfig{ + CAFile: "/some/other/path", + CertFile: "/some/other/cert", + KeyFile: "/some/other/key", + ServerName: "my-name", + }, }, }, }, @@ -2050,11 +2052,13 @@ scrape_configs: [] ConsulSDConfigs: []vmv1beta1.ConsulSDConfig{ { Server: "http://consul.example.com", - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "auth", + HTTPSDOptions: vmv1beta1.HTTPSDOptions{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "auth", + }, }, }, }, From d937c094ba55a5b819c55937381c142c32160fb2 Mon Sep 17 00:00:00 2001 From: Andrii Chubatiuk Date: Tue, 24 Mar 2026 22:35:24 +0200 Subject: [PATCH 2/5] vmagent and vmalertmanager: arbitrary fs access for all params --- api/operator/v1beta1/common_scrapeparams.go | 130 +- api/operator/v1beta1/vmagent_types.go | 25 - api/operator/v1beta1/vmalertmanager_types.go | 5 + .../v1beta1/vmalertmanagerconfig_types.go | 121 + api/operator/v1beta1/vmextra_types.go | 16 + api/operator/v1beta1/vmnodescrape_types.go | 1 - api/operator/v1beta1/vmpodscrape_types.go | 1 - api/operator/v1beta1/vmprobe_types.go | 1 - api/operator/v1beta1/vmscrapeconfig_types.go | 3 +- api/operator/v1beta1/vmservicescrape_types.go | 1 - api/operator/v1beta1/vmstaticscrape_types.go | 1 - api/operator/v1beta1/zz_generated.deepcopy.go | 30 +- config/crd/overlay/crd.descriptionless.yaml | 1821 ++++++++- config/crd/overlay/crd.yaml | 3495 +++++++++++++++-- docs/CHANGELOG.md | 2 +- docs/api.md | 65 +- .../operator/factory/build/cache.go | 22 +- .../operator/factory/build/vmscrape.go | 2 - .../operator/factory/build/vmscrape_test.go | 6 +- .../operator/factory/converter/apis.go | 57 +- .../operator/factory/converter/apis_test.go | 46 +- .../factory/converter/v1alpha1/apis_test.go | 12 +- .../operator/factory/vmagent/scrapes_test.go | 496 +-- .../operator/factory/vmagent/vmagent_test.go | 28 +- .../operator/factory/vmalertmanager/config.go | 5 + .../factory/vmscrapes/nodescrape_test.go | 24 +- .../operator/factory/vmscrapes/objects.go | 12 +- .../operator/factory/vmscrapes/probe_test.go | 12 +- .../factory/vmscrapes/scrapeconfig.go | 2 +- .../factory/vmscrapes/scrapeconfig_test.go | 50 +- .../factory/vmscrapes/servicescrape_test.go | 272 +- .../factory/vmscrapes/staticscrape_test.go | 60 +- .../operator/factory/vmscrapes/vmscrapes.go | 31 +- .../operator/factory/vmsingle/scrapes_test.go | 496 +-- 34 files changed, 6164 insertions(+), 1187 deletions(-) diff --git a/api/operator/v1beta1/common_scrapeparams.go b/api/operator/v1beta1/common_scrapeparams.go index 4e65b9f74..ce285de97 100644 --- a/api/operator/v1beta1/common_scrapeparams.go +++ b/api/operator/v1beta1/common_scrapeparams.go @@ -12,6 +12,31 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +type ScrapeClass struct { + // name of the scrape class. + // + // +kubebuilder:validation:MinLength=1 + // +required + Name string `json:"name"` + + // default defines that the scrape applies to all scrape objects that + // don't configure an explicit scrape class name. + // + // Only one scrape class can be set as the default. + // + // +optional + Default *bool `json:"default,omitempty"` + + EndpointAuth `json:",inline"` + EndpointRelabelings `json:",inline"` + + // AttachMetadata defines additional metadata to the discovered targets. + // When the scrape object defines its own configuration, it takes + // precedence over the scrape class configuration. + // +optional + AttachMetadata *AttachMetadata `json:"attachMetadata,omitempty"` +} + // AttachMetadata configures metadata attachment type AttachMetadata struct { // Node instructs vmagent or vmsingle to add node specific metadata from service discovery @@ -47,7 +72,7 @@ type VMScrapeParams struct { // ProxyClientConfig configures proxy auth settings for scraping // See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` + ProxyClientConfig *ProxyClientConfig `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: @@ -57,16 +82,55 @@ type VMScrapeParams struct { 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 *corev1.SecretKeySelector `json:"bearer_token,omitempty"` - BearerTokenFile string `json:"bearer_token_file,omitempty"` +// ProxyClientConfig represent proxy client config +type ProxyClientConfig struct { + // OAuth2 defines auth configuration + // +optional + OAuth2 *OAuth2 `json:"oauth2,omitempty"` + // BasicAuth allows proxy to authenticate over basic authentication + // +optional + BasicAuth *BasicAuth `json:"basic_auth,omitempty"` + // Secret to mount to read bearer token for scraping targets proxy auth. The secret + // needs to be in the same namespace as the scrape object and accessible by + // the victoria-metrics operator. + // +optional + // +nullable + BearerToken *corev1.SecretKeySelector `json:"bearer_token,omitempty"` + // BearerTokenFile defines file to read bearer token from for proxy auth. + // +optional + BearerTokenFile string `json:"bearer_token_file,omitempty"` + // TLSConfig configuration to use when scraping the endpoint + // +optional // +kubebuilder:validation:Schemaless // +kubebuilder:pruning:PreserveUnknownFields TLSConfig *TLSConfig `json:"tls_config,omitempty"` + // Authorization with http header Authorization + // +optional + Authorization *Authorization `json:"authorization,omitempty"` +} + +func (c *ProxyClientConfig) validateArbitraryFSAccess() error { + if c == nil { + return nil + } + var props []string + if c.BearerTokenFile != "" { + props = append(props, "bearer_token_file") + } + if c.BasicAuth != nil && c.BasicAuth.PasswordFile != "" { + props = append(props, "basic_auth.passwordFile") + } + if c.OAuth2 != nil && c.OAuth2.ClientSecretFile != "" { + props = append(props, "oauth2.clientSecretFile") + } + if c.Authorization != nil && c.Authorization.CredentialsFile != "" { + props = append(props, "authorization.credentialsFile") + } + props = c.TLSConfig.appendForbiddenProperties(props) + if len(props) > 0 { + return fmt.Errorf("%s are prohibited", strings.Join(props, ", ")) + } + return nil } // OAuth2 defines OAuth2 configuration @@ -245,7 +309,7 @@ func (rc *RelabelConfig) IsEmpty() bool { return reflect.DeepEqual(*rc, RelabelConfig{}) } -// ScrapeTargetParams defines common configuration params for all scrape endpoint targets +// EndpointScrapeParams defines common configuration params for all scrape endpoint targets type EndpointScrapeParams struct { // HTTP path to scrape for metrics. // +optional @@ -292,6 +356,19 @@ type EndpointScrapeParams struct { // VMScrapeParams defines VictoriaMetrics specific scrape parameters // +optional VMScrapeParams *VMScrapeParams `json:"vm_scrape_params,omitempty"` + EndpointAuth `json:",inline"` +} + +func (p *EndpointScrapeParams) ValidateArbitraryFSAccess() error { + if err := p.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("endpoint auth contains prohibited properties for arbitrary filesystem access mode: %w", err) + } + if p.VMScrapeParams != nil { + if err := p.VMScrapeParams.ProxyClientConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("endpoint proxy auth contains prohibited properties for arbitrary filesystem access mode: %w", err) + } + } + return nil } // EndpointAuth defines target endpoint authorization options for scrapping @@ -319,6 +396,41 @@ type EndpointAuth struct { Authorization *Authorization `json:"authorization,omitempty"` } +func (a *EndpointAuth) validateArbitraryFSAccess() error { + var props []string + if a.BearerTokenFile != "" { + props = append(props, "bearerTokenFile") + } + if a.BasicAuth != nil && a.BasicAuth.PasswordFile != "" { + props = append(props, "basicAuth.passwordFile") + } + if a.OAuth2 != nil && a.OAuth2.ClientSecretFile != "" { + props = append(props, "oauth2.clientSecretFile") + } + if a.Authorization != nil && a.Authorization.CredentialsFile != "" { + props = append(props, "authorization.credentialsFile") + } + if a.TLSConfig != nil { + tls := a.TLSConfig + if err := tls.Validate(); err != nil { + return err + } + if tls.CAFile != "" { + props = append(props, "tlsConfig.caFile") + } + if tls.CertFile != "" { + props = append(props, "tlsConfig.certFile") + } + if tls.KeyFile != "" { + props = append(props, "tlsConfig.keyFile") + } + } + if len(props) > 0 { + return fmt.Errorf("%s are prohibited", strings.Join(props, ", ")) + } + return nil +} + // EndpointRelabelings defines service discovery and metrics relabeling configuration for endpoints type EndpointRelabelings struct { // MetricRelabelConfigs to apply to samples after scrapping. diff --git a/api/operator/v1beta1/vmagent_types.go b/api/operator/v1beta1/vmagent_types.go index 3f51c2c81..c50939d69 100644 --- a/api/operator/v1beta1/vmagent_types.go +++ b/api/operator/v1beta1/vmagent_types.go @@ -309,31 +309,6 @@ type VMAgentRemoteWriteSettings struct { UseMultiTenantMode bool `json:"useMultiTenantMode,omitempty"` } -type ScrapeClass struct { - // name of the scrape class. - // - // +kubebuilder:validation:MinLength=1 - // +required - Name string `json:"name"` - - // default defines that the scrape applies to all scrape objects that - // don't configure an explicit scrape class name. - // - // Only one scrape class can be set as the default. - // - // +optional - Default *bool `json:"default,omitempty"` - - EndpointAuth `json:",inline"` - EndpointRelabelings `json:",inline"` - - // AttachMetadata defines additional metadata to the discovered targets. - // When the scrape object defines its own configuration, it takes - // precedence over the scrape class configuration. - // +optional - AttachMetadata *AttachMetadata `json:"attachMetadata,omitempty"` -} - // AWS defines AWS cloud auth specific params type AWS struct { // EC2Endpoint is an optional AWS EC2 API endpoint to use for the corresponding -remoteWrite.url if -remoteWrite.aws.useSigv4 is set diff --git a/api/operator/v1beta1/vmalertmanager_types.go b/api/operator/v1beta1/vmalertmanager_types.go index 17df39483..fc60864e4 100644 --- a/api/operator/v1beta1/vmalertmanager_types.go +++ b/api/operator/v1beta1/vmalertmanager_types.go @@ -206,6 +206,11 @@ type VMAlertmanagerSpec struct { // ServiceAccountName is the name of the ServiceAccount to use to run the pods // +optional ServiceAccountName string `json:"serviceAccountName,omitempty"` + // ArbitraryFSAccessThroughSMs configures whether configuration + // can contain paths to arbitrary files on the file system + // e.g bearer token files, basic auth password files, tls certs file paths + // +optional + ArbitraryFSAccessThroughSMs ArbitraryFSAccessThroughSMsConfig `json:"arbitraryFSAccessThroughSMs,omitempty"` // ComponentVersion defines default images tag for all components. // it can be overwritten with component specific image.tag value. diff --git a/api/operator/v1beta1/vmalertmanagerconfig_types.go b/api/operator/v1beta1/vmalertmanagerconfig_types.go index 3f7dc6bb7..8899f5b9a 100644 --- a/api/operator/v1beta1/vmalertmanagerconfig_types.go +++ b/api/operator/v1beta1/vmalertmanagerconfig_types.go @@ -117,6 +117,97 @@ func (cr *VMAlertmanagerConfig) GetStatus() *VMAlertmanagerConfigStatus { // DefaultStatusFields implements reconcile.ObjectWithDeepCopyAndStatus interface func (cr *VMAlertmanagerConfig) DefaultStatusFields(vs *VMAlertmanagerConfigStatus) {} +func (cr *VMAlertmanagerConfig) ValidateArbitraryFSAccess() error { + for i, r := range cr.Spec.Receivers { + for j, rc := range r.EmailConfigs { + if err := rc.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].email_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.PagerDutyConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].pagerduty_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.PushoverConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].pushover_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.SlackConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].slack_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.OpsGenieConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].opsgenie_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.WebhookConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].webhook_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.VictorOpsConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].victorops_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.WeChatConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].wechat_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.TelegramConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].telegram_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.MSTeamsConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].msteams_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.DiscordConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].discord_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.SNSConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].sns_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.WebexConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].webex_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.JiraConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].jira_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.IncidentIOConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].incidentio_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.RocketchatConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].rocketchat_configs[%d]: %w", i, j, err) + } + } + for j, rc := range r.MSTeamsV2Configs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("found prohibited properties at spec.receivers[%d].msteamsv2_configs[%d]: %w", i, j, err) + } + } + } + return nil +} + func (r *VMAlertmanagerConfig) Validate() error { if MustSkipCRValidation(r) { return nil @@ -512,6 +603,15 @@ type EmailConfig struct { TLSConfig *TLSConfig `json:"tls_config,omitempty" yaml:"tls_config,omitempty"` } +func (c *EmailConfig) validateArbitraryFSAccess() error { + var props []string + props = c.TLSConfig.appendForbiddenProperties(props) + if len(props) > 0 { + return fmt.Errorf("%s are prohibited", strings.Join(props, ", ")) + } + return nil +} + // VictorOpsConfig configures notifications via VictorOps. // See https://prometheus.io/docs/alerting/latest/configuration/#victorops_config type VictorOpsConfig struct { @@ -1210,6 +1310,27 @@ type HTTPConfig struct { ProxyConfig `json:",inline"` } +func (c *HTTPConfig) validateArbitraryFSAccess() error { + var props []string + if c.BearerTokenFile != "" { + props = append(props, "bearerTokenFile") + } + if c.BasicAuth != nil && c.BasicAuth.PasswordFile != "" { + props = append(props, "basicAuth.passwordFile") + } + if c.OAuth2 != nil && c.OAuth2.ClientSecretFile != "" { + props = append(props, "oauth2.clientSecretFile") + } + if c.Authorization != nil && c.Authorization.CredentialsFile != "" { + props = append(props, "authorization.credentialsFile") + } + props = c.TLSConfig.appendForbiddenProperties(props) + if len(props) > 0 { + return fmt.Errorf("%s are prohibited", strings.Join(props, ", ")) + } + return nil +} + // ProxyConfig defines proxy configs type ProxyConfig struct { // ProxyUrl defines the HTTP proxy server to use. diff --git a/api/operator/v1beta1/vmextra_types.go b/api/operator/v1beta1/vmextra_types.go index 11a28989b..3fff10bbe 100644 --- a/api/operator/v1beta1/vmextra_types.go +++ b/api/operator/v1beta1/vmextra_types.go @@ -865,6 +865,22 @@ type TLSConfig struct { InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty" yaml:"-"` } +func (c *TLSConfig) appendForbiddenProperties(props []string) []string { + if c == nil { + return nil + } + if c.CAFile != "" { + props = append(props, "tlsConfig.caFile") + } + if c.CertFile != "" { + props = append(props, "tlsConfig.certFile") + } + if c.KeyFile != "" { + props = append(props, "tlsConfig.keyFile") + } + return props +} + // UnmarshalJSON implements json.Unmarshaller interface func (c *TLSConfig) UnmarshalJSON(data []byte) error { decoder := json.NewDecoder(bytes.NewReader(data)) diff --git a/api/operator/v1beta1/vmnodescrape_types.go b/api/operator/v1beta1/vmnodescrape_types.go index b76758ed1..1b5404ab7 100644 --- a/api/operator/v1beta1/vmnodescrape_types.go +++ b/api/operator/v1beta1/vmnodescrape_types.go @@ -23,7 +23,6 @@ type VMNodeScrapeSpec struct { // +optional Port string `json:"port,omitempty"` EndpointRelabelings `json:",inline"` - EndpointAuth `json:",inline"` EndpointScrapeParams `json:",inline"` // Selector to select kubernetes Nodes. diff --git a/api/operator/v1beta1/vmpodscrape_types.go b/api/operator/v1beta1/vmpodscrape_types.go index 9903bc2ff..1d6820ebd 100644 --- a/api/operator/v1beta1/vmpodscrape_types.go +++ b/api/operator/v1beta1/vmpodscrape_types.go @@ -102,7 +102,6 @@ type PodMetricsEndpoint struct { // +optional TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` EndpointRelabelings `json:",inline"` - EndpointAuth `json:",inline"` EndpointScrapeParams `json:",inline"` // AttachMetadata configures metadata attaching from service discovery // +optional diff --git a/api/operator/v1beta1/vmprobe_types.go b/api/operator/v1beta1/vmprobe_types.go index 167ce57d7..f822556c0 100644 --- a/api/operator/v1beta1/vmprobe_types.go +++ b/api/operator/v1beta1/vmprobe_types.go @@ -45,7 +45,6 @@ type VMProbeSpec struct { // +optional MetricRelabelConfigs []*RelabelConfig `json:"metricRelabelConfigs,omitempty"` - EndpointAuth `json:",inline"` EndpointScrapeParams `json:",inline"` // ScrapeClass defined scrape class to apply // +optional diff --git a/api/operator/v1beta1/vmscrapeconfig_types.go b/api/operator/v1beta1/vmscrapeconfig_types.go index d0b3b2706..58af4efcc 100644 --- a/api/operator/v1beta1/vmscrapeconfig_types.go +++ b/api/operator/v1beta1/vmscrapeconfig_types.go @@ -103,7 +103,6 @@ type VMScrapeConfigSpec struct { EurekaSDConfigs []EurekaSDConfig `json:"eurekaSDConfigs,omitempty"` EndpointScrapeParams `json:",inline"` EndpointRelabelings `json:",inline"` - EndpointAuth `json:",inline"` // ScrapeClass defined scrape class to apply // +optional ScrapeClassName *string `json:"scrapeClass,omitempty"` @@ -160,7 +159,7 @@ type HTTPSDOptions struct { // ProxyClientConfig configures proxy auth settings for scraping // See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) // +optional - ProxyClientConfig *ProxyAuth `json:"proxy_client_config,omitempty"` + ProxyClientConfig *ProxyClientConfig `json:"proxy_client_config,omitempty"` // Configure whether HTTP requests follow HTTP 3xx redirects. // +optional FollowRedirects *bool `json:"followRedirects,omitempty"` diff --git a/api/operator/v1beta1/vmservicescrape_types.go b/api/operator/v1beta1/vmservicescrape_types.go index ecc4ce6e5..35a2bbd49 100644 --- a/api/operator/v1beta1/vmservicescrape_types.go +++ b/api/operator/v1beta1/vmservicescrape_types.go @@ -140,7 +140,6 @@ type Endpoint struct { TargetPort *intstr.IntOrString `json:"targetPort,omitempty"` EndpointRelabelings `json:",inline"` - EndpointAuth `json:",inline"` EndpointScrapeParams `json:",inline"` // AttachMetadata configures metadata attaching from service discovery diff --git a/api/operator/v1beta1/vmstaticscrape_types.go b/api/operator/v1beta1/vmstaticscrape_types.go index 7030f349d..990d2d9ae 100644 --- a/api/operator/v1beta1/vmstaticscrape_types.go +++ b/api/operator/v1beta1/vmstaticscrape_types.go @@ -48,7 +48,6 @@ type TargetEndpoint struct { // +optional Labels map[string]string `json:"labels,omitempty"` EndpointRelabelings `json:",inline"` - EndpointAuth `json:",inline"` EndpointScrapeParams `json:",inline"` } diff --git a/api/operator/v1beta1/zz_generated.deepcopy.go b/api/operator/v1beta1/zz_generated.deepcopy.go index ddb397ccf..24674bf07 100644 --- a/api/operator/v1beta1/zz_generated.deepcopy.go +++ b/api/operator/v1beta1/zz_generated.deepcopy.go @@ -1371,7 +1371,6 @@ func (in *Endpoint) DeepCopyInto(out *Endpoint) { **out = **in } in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.AttachMetadata.DeepCopyInto(&out.AttachMetadata) } @@ -1502,6 +1501,7 @@ func (in *EndpointScrapeParams) DeepCopyInto(out *EndpointScrapeParams) { *out = new(VMScrapeParams) (*in).DeepCopyInto(*out) } + in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointScrapeParams. @@ -1737,7 +1737,7 @@ func (in *HTTPSDOptions) DeepCopyInto(out *HTTPSDOptions) { } if in.ProxyClientConfig != nil { in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) + *out = new(ProxyClientConfig) (*in).DeepCopyInto(*out) } if in.FollowRedirects != nil { @@ -2515,7 +2515,6 @@ func (in *PodMetricsEndpoint) DeepCopyInto(out *PodMetricsEndpoint) { **out = **in } in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.AttachMetadata.DeepCopyInto(&out.AttachMetadata) if in.FilterRunning != nil { @@ -2536,8 +2535,13 @@ func (in *PodMetricsEndpoint) DeepCopy() *PodMetricsEndpoint { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyAuth) DeepCopyInto(out *ProxyAuth) { +func (in *ProxyClientConfig) DeepCopyInto(out *ProxyClientConfig) { *out = *in + if in.OAuth2 != nil { + in, out := &in.OAuth2, &out.OAuth2 + *out = new(OAuth2) + (*in).DeepCopyInto(*out) + } if in.BasicAuth != nil { in, out := &in.BasicAuth, &out.BasicAuth *out = new(BasicAuth) @@ -2553,14 +2557,19 @@ func (in *ProxyAuth) DeepCopyInto(out *ProxyAuth) { *out = new(TLSConfig) (*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 ProxyAuth. -func (in *ProxyAuth) DeepCopy() *ProxyAuth { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyClientConfig. +func (in *ProxyClientConfig) DeepCopy() *ProxyClientConfig { if in == nil { return nil } - out := new(ProxyAuth) + out := new(ProxyClientConfig) in.DeepCopyInto(out) return out } @@ -3775,7 +3784,6 @@ func (in *TargetEndpoint) DeepCopyInto(out *TargetEndpoint) { } } in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) } @@ -5103,6 +5111,7 @@ func (in *VMAlertmanagerSpec) DeepCopyInto(out *VMAlertmanagerSpec) { *out = new(VMAlertmanagerTracingConfig) (*in).DeepCopyInto(*out) } + out.ArbitraryFSAccessThroughSMs = in.ArbitraryFSAccessThroughSMs in.CommonConfigReloaderParams.DeepCopyInto(&out.CommonConfigReloaderParams) in.CommonAppsParams.DeepCopyInto(&out.CommonAppsParams) } @@ -5854,7 +5863,6 @@ func (in *VMNodeScrapeSpec) DeepCopyInto(out *VMNodeScrapeSpec) { copy(*out, *in) } in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.Selector.DeepCopyInto(&out.Selector) if in.ScrapeClassName != nil { @@ -6043,7 +6051,6 @@ func (in *VMProbeSpec) DeepCopyInto(out *VMProbeSpec) { } } } - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) if in.ScrapeClassName != nil { in, out := &in.ScrapeClassName, &out.ScrapeClassName @@ -6506,7 +6513,6 @@ func (in *VMScrapeConfigSpec) DeepCopyInto(out *VMScrapeConfigSpec) { } in.EndpointScrapeParams.DeepCopyInto(&out.EndpointScrapeParams) in.EndpointRelabelings.DeepCopyInto(&out.EndpointRelabelings) - in.EndpointAuth.DeepCopyInto(&out.EndpointAuth) if in.ScrapeClassName != nil { in, out := &in.ScrapeClassName, &out.ScrapeClassName *out = new(string) @@ -6559,7 +6565,7 @@ func (in *VMScrapeParams) DeepCopyInto(out *VMScrapeParams) { } if in.ProxyClientConfig != nil { in, out := &in.ProxyClientConfig, &out.ProxyClientConfig - *out = new(ProxyAuth) + *out = new(ProxyClientConfig) (*in).DeepCopyInto(*out) } if in.Headers != nil { diff --git a/config/crd/overlay/crd.descriptionless.yaml b/config/crd/overlay/crd.descriptionless.yaml index c69138fbd..d9d50eaa6 100644 --- a/config/crd/overlay/crd.descriptionless.yaml +++ b/config/crd/overlay/crd.descriptionless.yaml @@ -9708,6 +9708,11 @@ spec: affinity: type: object x-kubernetes-preserve-unknown-fields: true + arbitraryFSAccessThroughSMs: + properties: + deny: + type: boolean + type: object claimTemplates: items: properties: @@ -21360,6 +21365,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -21392,6 +21417,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -21406,6 +21432,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -32041,6 +32132,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -32073,6 +32184,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -32087,6 +32199,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -32570,6 +32747,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -32602,6 +32799,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -32616,6 +32814,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -33332,6 +33595,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -33364,6 +33647,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -33378,41 +33662,106 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string - tls_config: - x-kubernetes-preserve-unknown-fields: true - type: object - scrape_align_interval: - type: string - scrape_offset: - type: string - stream_parse: - type: boolean - type: object - vmProberSpec: - properties: - path: - type: string - scheme: - enum: - - http - - https - type: string - url: - type: string - required: - - url - type: object - required: - - vmProberSpec - type: object - status: - properties: - conditions: - items: - properties: - lastTransitionTime: - format: date-time - type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + scrape_align_interval: + type: string + scrape_offset: + type: string + stream_parse: + type: boolean + type: object + vmProberSpec: + properties: + path: + type: string + scheme: + enum: + - http + - https + type: string + url: + type: string + required: + - url + type: object + required: + - vmProberSpec + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string lastUpdateTime: format: date-time type: string @@ -33837,6 +34186,26 @@ spec: type: integer proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -33869,6 +34238,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -33883,6 +34253,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -34168,6 +34603,26 @@ spec: type: string proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -34200,6 +34655,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -34214,6 +34670,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -34466,6 +34987,26 @@ spec: type: integer proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -34498,6 +35039,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -34512,12 +35054,77 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string - tls_config: - x-kubernetes-preserve-unknown-fields: true - type: object - proxyURL: - type: string - server: + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object + tls_config: + x-kubernetes-preserve-unknown-fields: true + type: object + proxyURL: + type: string + server: type: string tlsConfig: properties: @@ -34802,6 +35409,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -34834,6 +35461,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -34848,6 +35476,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -35101,6 +35794,26 @@ spec: type: integer proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -35133,6 +35846,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -35147,6 +35861,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -35374,6 +36153,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -35406,6 +36205,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -35420,6 +36220,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -35660,6 +36525,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -35692,6 +36577,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -35706,6 +36592,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -35956,6 +36907,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -35988,6 +36959,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -36002,6 +36974,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -36263,6 +37300,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -36278,37 +37335,103 @@ spec: - key type: object x-kubernetes-map-type: atomic - password_file: + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + nullable: true + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: type: string - username: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key + endpoint_params: + additionalProperties: + type: string type: object - x-kubernetes-map-type: atomic - type: object - bearer_token: - properties: - key: + proxy_url: type: string - name: - default: "" + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 type: string - optional: - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -36788,6 +37911,26 @@ spec: type: object proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -36820,6 +37963,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -36834,6 +37978,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -37075,6 +38284,26 @@ spec: type: integer proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -37107,6 +38336,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -37121,6 +38351,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -37384,6 +38679,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -37399,37 +38714,103 @@ spec: - key type: object x-kubernetes-map-type: atomic - password_file: + password_file: + type: string + username: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearer_token: + nullable: true + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + bearer_token_file: + type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: type: string - username: - properties: - key: - type: string - name: - default: "" - type: string - optional: - type: boolean - required: - - key + endpoint_params: + additionalProperties: + type: string type: object - x-kubernetes-map-type: atomic - type: object - bearer_token: - properties: - key: + proxy_url: type: string - name: - default: "" + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 type: string - optional: - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -37574,6 +38955,26 @@ spec: type: integer proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -37606,6 +39007,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -37620,6 +39022,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -38175,6 +39642,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -38207,6 +39694,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -38221,6 +39709,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object @@ -40931,6 +42484,26 @@ spec: type: boolean proxy_client_config: properties: + authorization: + properties: + credentials: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + type: string + type: + type: string + type: object basic_auth: properties: password: @@ -40963,6 +42536,7 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: + nullable: true properties: key: type: string @@ -40977,6 +42551,71 @@ spec: x-kubernetes-map-type: atomic bearer_token_file: type: string + oauth2: + properties: + client_id: + properties: + configMap: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + client_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + client_secret_file: + type: string + endpoint_params: + additionalProperties: + type: string + type: object + proxy_url: + type: string + scopes: + items: + type: string + type: array + tls_config: + x-kubernetes-preserve-unknown-fields: true + token_url: + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: x-kubernetes-preserve-unknown-fields: true type: object diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml index 17a1f1610..e618da0f8 100644 --- a/config/crd/overlay/crd.yaml +++ b/config/crd/overlay/crd.yaml @@ -18813,6 +18813,15 @@ spec: description: Affinity If specified, the pod's scheduling constraints. type: object x-kubernetes-preserve-unknown-fields: true + arbitraryFSAccessThroughSMs: + description: |- + ArbitraryFSAccessThroughSMs configures whether configuration + can contain paths to arbitrary files on the file system + e.g bearer token files, basic auth password files, tls certs file paths + properties: + deny: + type: boolean + type: object claimTemplates: description: ClaimTemplates allows adding additional VolumeClaimTemplates for StatefulSet @@ -42205,9 +42214,47 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header + Authorization + properties: + credentials: + description: Reference to the secret + with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, + default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint - to authenticate over basic authentication + description: BasicAuth allows proxy to authenticate + over basic authentication properties: password: description: |- @@ -42270,8 +42317,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a - key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -42296,8 +42346,135 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file + to read bearer token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap + containing the OAuth2 client id + properties: + configMap: + description: ConfigMap containing + data to use for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether + the ConfigMap or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data + to use for the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the + OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines + path for client secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to + the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for + the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token + from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to + use when scraping the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -65792,9 +65969,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate over - basic authentication + description: BasicAuth allows proxy to authenticate over basic + authentication properties: password: description: |- @@ -65855,7 +66066,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -65879,8 +66094,127 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer token + from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -66744,8 +67078,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value + for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate + description: BasicAuth allows proxy to authenticate over basic authentication properties: password: @@ -66805,34 +67174,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing + the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use + for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for + the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -68112,9 +68605,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate over - basic authentication + description: BasicAuth allows proxy to authenticate over basic + authentication properties: password: description: |- @@ -68175,7 +68702,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -68199,8 +68730,127 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer token + from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -68962,9 +69612,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -69023,34 +69708,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -69571,9 +70380,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -69634,7 +70478,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -69658,8 +70506,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -70109,9 +71077,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -70170,34 +71173,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -70715,9 +71842,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -70778,7 +71940,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -70802,8 +71968,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -71264,9 +72550,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -71325,34 +72646,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -71759,9 +73204,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -71822,7 +73302,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -71846,8 +73330,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -72284,9 +73888,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -72345,34 +73984,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -72804,9 +74567,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -72867,7 +74665,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -72891,8 +74693,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -73375,9 +75297,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -73436,34 +75393,158 @@ spec: - key type: object x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - name: - default: "" + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -74327,9 +76408,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -74390,7 +76506,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -74414,8 +76534,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -74838,9 +77078,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -74901,7 +77176,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -74925,8 +77204,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -75403,9 +77802,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate over - basic authentication + description: BasicAuth allows proxy to authenticate over basic + authentication properties: password: description: |- @@ -75466,7 +77899,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -75490,8 +77927,127 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer token + from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -75747,9 +78303,44 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value for + authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate - over basic authentication + description: BasicAuth allows proxy to authenticate over + basic authentication properties: password: description: |- @@ -75777,65 +78368,189 @@ spec: - key type: object x-kubernetes-map-type: atomic - password_file: - description: |- - PasswordFile defines path to password file at disk - must be pre-mounted + password_file: + description: |- + PasswordFile defines path to password file at disk + must be pre-mounted + type: string + username: + description: |- + 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 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + bearer_token: + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. + type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. type: string - username: - description: |- - 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 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL type: object - x-kubernetes-map-type: atomic - type: object - bearer_token: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family type: string - name: - default: "" + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: 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. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean required: - - key + - client_id + - token_url type: object - x-kubernetes-map-type: atomic - bearer_token_file: - type: string tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object proxyURL: @@ -76837,8 +79552,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value + for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate + description: BasicAuth allows proxy to authenticate over basic authentication properties: password: @@ -76900,7 +79650,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -76924,8 +79678,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing + the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use + for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for + the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: @@ -82211,8 +85085,43 @@ spec: ProxyClientConfig configures proxy auth settings for scraping See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy properties: + authorization: + description: Authorization with http header Authorization + properties: + credentials: + description: Reference to the secret with value + for authorization + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + credentialsFile: + description: File with value for authorization + type: string + type: + description: Type of authorization, default to bearer + type: string + type: object basic_auth: - description: BasicAuth allow an endpoint to authenticate + description: BasicAuth allows proxy to authenticate over basic authentication properties: password: @@ -82274,7 +85183,11 @@ spec: x-kubernetes-map-type: atomic type: object bearer_token: - description: SecretKeySelector selects a key of a Secret. + description: |- + Secret to mount to read bearer token for scraping targets proxy auth. 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 @@ -82298,8 +85211,128 @@ spec: type: object x-kubernetes-map-type: atomic bearer_token_file: + description: BearerTokenFile defines file to read bearer + token from for proxy auth. type: string + oauth2: + description: OAuth2 defines auth configuration + properties: + client_id: + description: The secret or configmap containing + the OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use + for the targets. + properties: + key: + description: The key to select. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + optional: + description: Specify whether the ConfigMap + or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for + the targets. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + type: object + client_secret: + description: The secret containing the OAuth2 client + secret + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + client_secret_file: + description: ClientSecretFile defines path for client + secret file. + type: string + endpoint_params: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + proxy_url: + description: |- + The proxy URL for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + type: string + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tls_config: + description: |- + TLSConfig for token_url connection + ( available from v0.55.0). + Is only supported by Scrape objects family + x-kubernetes-preserve-unknown-fields: true + token_url: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - client_id + - token_url + type: object tls_config: + description: TLSConfig configuration to use when scraping + the endpoint x-kubernetes-preserve-unknown-fields: true type: object scrape_align_interval: diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9dfca948b..beeeb0f5c 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -37,7 +37,7 @@ aliases: * FEATURE: [vmagent](https://docs.victoriametrics.com/operator/resources/vmagent/): VMAgent CRs running in DaemonSet mode now support configuring rolling update strategy behavior. * FEATURE: [vmoperator](https://docs.victoriametrics.com/operator/): Dry-run mode. See [#1832](https://github.com/VictoriaMetrics/operator/issues/1832). * FEATURE: [vmanomaly](https://docs.victoriametrics.com/operator/resources/vmanomaly/): introduce `VMAnomalyConfig` CRD to enable dynamic configuration and hot-reload support starting from VMAnomaly version `1.25.0`. - +* FEATURE: [vmalertmanager](https://docs.victoriametrics.com/operator/resources/vmalertmanager): introduce arbitrary fs access feature for VMAlertmanager. See [#899](https://github.com/VictoriaMetrics/operator/issues/899) * FEATURE: [vmalertmanagerconfig](https://docs.victoriametrics.com/operator/resources/vmalertmanagerconfig/): add `update_message` field to `SlackConfig`. This allows alertmanager to edit the original Slack message in-place when alert status changes instead of sending a new one. Requires alertmanager v0.32.0+. See [#2064](https://github.com/VictoriaMetrics/operator/issues/2064). * BUGFIX: [vmbackupmanager](https://docs.victoriametrics.com/operator/): remove deprecated `-eula` flag from vmbackupmanager and vmrestore container args. See [#1319](https://github.com/VictoriaMetrics/operator/issues/1319). diff --git a/docs/api.md b/docs/api.md index 07cc19c2f..982090dbd 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1359,7 +1359,7 @@ in the vmagent container. Those secrets would then be sent with a scrape request by vmagent to a malicious target. Denying the above would prevent the attack, users can instead use the BearerTokenSecret field. -Appears in: [CommonScrapeParams](#commonscrapeparams), [CommonScrapeSecurityEnforcements](#commonscrapesecurityenforcements), [VMAgentSpec](#vmagentspec), [VMSingleSpec](#vmsinglespec) +Appears in: [CommonScrapeParams](#commonscrapeparams), [CommonScrapeSecurityEnforcements](#commonscrapesecurityenforcements), [VMAgentSpec](#vmagentspec), [VMAlertmanagerSpec](#vmalertmanagerspec), [VMSingleSpec](#vmsinglespec) | Field | Description | | --- | --- | @@ -1380,7 +1380,7 @@ Appears in: [Endpoint](#endpoint), [KubernetesSDConfig](#kubernetessdconfig), [P Authorization configures generic authorization params -Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EndpointScrapeParams](#endpointscrapeparams), [EurekaSDConfig](#eurekasdconfig), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyClientConfig](#proxyclientconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -1407,7 +1407,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
The port to scrape metrics from. If using the public IP address, this must
instead be specified in the relabeling rule. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | resourceGroup#
_string_ | _(Optional)_
Optional resource group name. Limits discovery to this resource group. | | subscriptionID#
_string_ | _(Required)_
The subscription ID. Always required. | | tenantID#
_string_ | _(Optional)_
Optional tenant ID. Only required with the OAuth authentication method. | @@ -1417,7 +1417,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) BasicAuth allow an endpoint to authenticate over basic authentication -Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EndpointScrapeParams](#endpointscrapeparams), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyClientConfig](#proxyclientconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -1635,7 +1635,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | partition#
_string_ | _(Optional)_
Admin Partitions are only supported in Consul Enterprise. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | scheme#
_string_ | _(Optional)_
HTTP Scheme default "http" | | server#
_string_ | _(Required)_
A valid string consisting of a hostname or IP followed by an optional port number. | | services#
_string array_ | _(Optional)_
A list of services for which targets are retrieved. If omitted, all services are scraped. | @@ -1688,7 +1688,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
The port to scrape metrics from. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | server#
_string_ | _(Optional)_
Server is an optional DigitalOcean API server to query.
By default, https://api.digitalocean.com is used. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -1909,7 +1909,7 @@ Appears in: [VMServiceScrapeSpec](#vmservicescrapespec) EndpointAuth defines target endpoint authorization options for scrapping -Appears in: [Endpoint](#endpoint), [PodMetricsEndpoint](#podmetricsendpoint), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec) +Appears in: [Endpoint](#endpoint), [EndpointScrapeParams](#endpointscrapeparams), [PodMetricsEndpoint](#podmetricsendpoint), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec) | Field | Description | | --- | --- | @@ -1933,17 +1933,22 @@ Appears in: [Endpoint](#endpoint), [PodMetricsEndpoint](#podmetricsendpoint), [S #### EndpointScrapeParams -ScrapeTargetParams defines common configuration params for all scrape endpoint targets +EndpointScrapeParams 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 | | --- | --- | +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization with http header Authorization | +| basicAuth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth allow an endpoint to authenticate over basic authentication | +| bearerTokenFile#
_string_ | _(Optional)_
File to read bearer token for scraping targets. | +| bearerTokenSecret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
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. | | follow_redirects#
_boolean_ | _(Optional)_
FollowRedirects controls redirects for scraping. | | honorLabels#
_boolean_ | _(Optional)_
HonorLabels chooses the metric's labels on collisions with target labels. | | honorTimestamps#
_boolean_ | _(Optional)_
HonorTimestamps controls whether vmagent or vmsingle respects the timestamps present in scraped data. | | interval#
_string_ | _(Optional)_
Interval at which metrics should be scraped | | max_scrape_size#
_string_ | _(Optional)_
MaxScrapeSize defines a maximum size of scraped data for a job | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | params#
_object (keys:string, values:string array)_ | _(Optional)_
Optional HTTP URL parameters | | path#
_string_ | _(Optional)_
HTTP path to scrape for metrics. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | @@ -1952,6 +1957,7 @@ Appears in: [Endpoint](#endpoint), [PodMetricsEndpoint](#podmetricsendpoint), [T | scrapeTimeout#
_string_ | _(Optional)_
Timeout after which the scrape is ended | | scrape_interval#
_string_ | _(Optional)_
ScrapeInterval is the same as Interval and has priority over it.
one of scrape_interval or interval can be used | | seriesLimit#
_integer_ | _(Optional)_
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. | +| tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLSConfig configuration to use when scraping the endpoint | | vm_scrape_params#
_[VMScrapeParams](#vmscrapeparams)_ | _(Optional)_
VMScrapeParams defines VictoriaMetrics specific scrape parameters | #### EurekaSDConfig @@ -1968,7 +1974,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | server#
_string_ | _(Optional)_
Server is an optional URL to connect to the Eureka server.
By default, the http://localhost:8080/eureka/v2 is used. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -2063,7 +2069,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | | url#
_string_ | _(Required)_
URL from which the targets are fetched. | @@ -2081,7 +2087,7 @@ Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | #### HetznerSDConfig @@ -2099,7 +2105,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
Port is an optional port to scrape metrics from | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | role#
_string_ | _(Required)_
Role defines mandatory Hetzner role for entity discovery. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -2228,7 +2234,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | namespaces#
_[NamespaceDiscovery](#namespacediscovery)_ | _(Optional)_
Optional namespace discovery. If omitted, discover targets across all namespaces. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | role#
_string_ | _(Required)_
Role of the Kubernetes entities that should be discovered. | | selectors#
_[K8SSelectorConfig](#k8sselectorconfig) array_ | _(Optional)_
Selector to select objects. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -2248,7 +2254,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | server#
_string_ | _(Required)_
Server must contain the URL of Kuma Control Plane's MADS xDS server. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -2373,7 +2379,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | namespace#
_string_ | _(Optional)_
Namespace to use for Nomad service discovery. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | region#
_string_ | _(Optional)_
Region to use for Nomad service discovery. | | server#
_string_ | _(Required)_
A valid string consisting of a hostname or IP followed by an optional port number. | | tagSeparator#
_string_ | _(Optional)_
The string by which Nomad tags are joined into the tag label.
If unset, use its default value. | @@ -2383,7 +2389,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) OAuth2 defines OAuth2 configuration -Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) +Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EndpointScrapeParams](#endpointscrapeparams), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyClientConfig](#proxyclientconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -2414,7 +2420,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | followRedirects#
_boolean_ | _(Optional)_
Configure whether HTTP requests follow HTTP 3xx redirects. | | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | service#
_string_ | _(Required)_
Service could be either `vps` or `dedicated_server` | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | @@ -2545,20 +2551,20 @@ Appears in: [VMPodScrapeSpec](#vmpodscrapespec) | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLSConfig configuration to use when scraping the endpoint | | vm_scrape_params#
_[VMScrapeParams](#vmscrapeparams)_ | _(Optional)_
VMScrapeParams defines VictoriaMetrics specific scrape parameters | -#### ProxyAuth +#### ProxyClientConfig -ProxyAuth represent proxy auth config -Only VictoriaMetrics scrapers supports it. -See https://github.com/VictoriaMetrics/VictoriaMetrics/commit/a6a71ef861444eb11fe8ec6d2387f0fc0c4aea87 +ProxyClientConfig represent proxy client config Appears in: [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EurekaSDConfig](#eurekasdconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OVHCloudSDConfig](#ovhcloudsdconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [VMScrapeParams](#vmscrapeparams), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | -| basic_auth#
_[BasicAuth](#basicauth)_ | _(Required)_
| -| bearer_token#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Required)_
| -| bearer_token_file#
_string_ | _(Required)_
| -| tls_config#
_[TLSConfig](#tlsconfig)_ | _(Required)_
| +| authorization#
_[Authorization](#authorization)_ | _(Optional)_
Authorization with http header Authorization | +| basic_auth#
_[BasicAuth](#basicauth)_ | _(Optional)_
BasicAuth allows proxy to authenticate over basic authentication | +| bearer_token#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
Secret to mount to read bearer token for scraping targets proxy auth. The secret
needs to be in the same namespace as the scrape object and accessible by
the victoria-metrics operator. | +| bearer_token_file#
_string_ | _(Optional)_
BearerTokenFile defines file to read bearer token from for proxy auth. | +| oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | +| tls_config#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLSConfig configuration to use when scraping the endpoint | #### ProxyConfig @@ -2589,7 +2595,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
Port defines port to scrape metrics from | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | query#
_string_ | _(Required)_
Query defines PQL query that allows to filter discovered resources. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | | url#
_string_ | _(Required)_
URL of the PuppetDB root query endpoint | @@ -3061,7 +3067,7 @@ Appears in: [VMAlertmanagerGossipConfig](#vmalertmanagergossipconfig), [VMAlertm TLSConfig specifies TLSConfig configuration parameters. -Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EmailConfig](#emailconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OAuth2](#oauth2), [OVHCloudSDConfig](#ovhcloudsdconfig), [OpenStackSDConfig](#openstacksdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyAuth](#proxyauth), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMAuthSpec](#vmauthspec), [VMAuthUnauthorizedUserAccessSpec](#vmauthunauthorizeduseraccessspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VMUserConfigOptions](#vmuserconfigoptions), [VMUserSpec](#vmuserspec), [VultrSDConfig](#vultrsdconfig) +Appears in: [APIServerConfig](#apiserverconfig), [AzureSDConfig](#azuresdconfig), [ConsulSDConfig](#consulsdconfig), [DigitalOceanSDConfig](#digitaloceansdconfig), [EmailConfig](#emailconfig), [Endpoint](#endpoint), [EndpointAuth](#endpointauth), [EndpointScrapeParams](#endpointscrapeparams), [EurekaSDConfig](#eurekasdconfig), [HTTPAuth](#httpauth), [HTTPConfig](#httpconfig), [HTTPSDConfig](#httpsdconfig), [HTTPSDOptions](#httpsdoptions), [HetznerSDConfig](#hetznersdconfig), [KubernetesSDConfig](#kubernetessdconfig), [KumaSDConfig](#kumasdconfig), [NomadSDConfig](#nomadsdconfig), [OAuth2](#oauth2), [OVHCloudSDConfig](#ovhcloudsdconfig), [OpenStackSDConfig](#openstacksdconfig), [PodMetricsEndpoint](#podmetricsendpoint), [ProxyClientConfig](#proxyclientconfig), [PuppetDBSDConfig](#puppetdbsdconfig), [ScrapeClass](#scrapeclass), [TargetEndpoint](#targetendpoint), [VMAgentRemoteWriteSpec](#vmagentremotewritespec), [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpec](#vmalertnotifierspec), [VMAlertRemoteReadSpec](#vmalertremotereadspec), [VMAlertRemoteWriteSpec](#vmalertremotewritespec), [VMAnomalyHTTPClientSpec](#vmanomalyhttpclientspec), [VMAnomalyMonitoringPushSpec](#vmanomalymonitoringpushspec), [VMAnomalyReadersSpec](#vmanomalyreadersspec), [VMAnomalyWritersSpec](#vmanomalywritersspec), [VMAuthSpec](#vmauthspec), [VMAuthUnauthorizedUserAccessSpec](#vmauthunauthorizeduseraccessspec), [VMDistributedZoneRemoteWriteSpec](#vmdistributedzoneremotewritespec), [VMNodeScrapeSpec](#vmnodescrapespec), [VMProbeSpec](#vmprobespec), [VMScrapeConfigSpec](#vmscrapeconfigspec), [VMUserConfigOptions](#vmuserconfigoptions), [VMUserSpec](#vmuserspec), [VultrSDConfig](#vultrsdconfig) | Field | Description | | --- | --- | @@ -3720,6 +3726,7 @@ Appears in: [VMAlertmanager](#vmalertmanager) | --- | --- | | additionalPeers#
_string array_ | _(Required)_
AdditionalPeers allows injecting a set of additional Alertmanagers to peer with to form a highly available cluster. | | affinity#
_[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#affinity-v1-core)_ | _(Optional)_
Affinity If specified, the pod's scheduling constraints. | +| arbitraryFSAccessThroughSMs#
_[ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig)_ | _(Optional)_
ArbitraryFSAccessThroughSMs configures whether configuration
can contain paths to arbitrary files on the file system
e.g bearer token files, basic auth password files, tls certs file paths | | claimTemplates#
_[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#persistentvolumeclaim-v1-core) array_ | _(Required)_
ClaimTemplates allows adding additional VolumeClaimTemplates for StatefulSet | | clusterAdvertiseAddress#
_string_ | _(Optional)_
ClusterAdvertiseAddress is the explicit address to advertise in cluster.
Needs to be provided for non RFC1918 [1] (public) addresses.
[1] RFC1918: https://tools.ietf.org/html/rfc1918 | | clusterDomainName#
_string_ | _(Optional)_
ClusterDomainName defines domain name suffix for in-cluster dns addresses
aka .cluster.local
used to build pod peer addresses for in-cluster communication | @@ -4442,7 +4449,7 @@ Appears in: [Endpoint](#endpoint), [EndpointScrapeParams](#endpointscrapeparams) | disable_keep_alive#
_boolean_ | _(Optional)_
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 reused.
See https://docs.victoriametrics.com/victoriametrics/vmagent/#scrape_config-enhancements | | headers#
_string array_ | _(Optional)_
Headers allows sending custom headers to scrape targets
must be in of semicolon separated header with it's value
eg:
headerName: headerValue
vmagent and vmsingle support since 1.79.0 version | | no_stale_markers#
_boolean_ | _(Optional)_
| -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See feature description https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy | | scrape_align_interval#
_string_ | _(Optional)_
| | scrape_offset#
_string_ | _(Optional)_
| | stream_parse#
_boolean_ | _(Optional)_
| @@ -4898,7 +4905,7 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | oauth2#
_[OAuth2](#oauth2)_ | _(Optional)_
OAuth2 defines auth configuration | | port#
_integer_ | _(Optional)_
Port is an optional port to scrape metrics from. | | proxyURL#
_string_ | _(Optional)_
ProxyURL eg http://proxyserver:2195 Directs scrapes to proxy through this endpoint. | -| proxy_client_config#
_[ProxyAuth](#proxyauth)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | +| proxy_client_config#
_[ProxyClientConfig](#proxyclientconfig)_ | _(Optional)_
ProxyClientConfig configures proxy auth settings for scraping
See [feature description](https://docs.victoriametrics.com/victoriametrics/vmagent/#scraping-targets-via-a-proxy) | | region#
_string_ | _(Optional)_
Region is an optional query arguments to filter instances by region id. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | diff --git a/internal/controller/operator/factory/build/cache.go b/internal/controller/operator/factory/build/cache.go index 26af02419..9786865df 100644 --- a/internal/controller/operator/factory/build/cache.go +++ b/internal/controller/operator/factory/build/cache.go @@ -213,9 +213,9 @@ func (ac *AssetsCache) TLSToYAML(ns, prefix string, cfg *vmv1beta1.TLSConfig) (y return r, nil } -// ProxyAuthToYAML returns yaml representation of provided ProxyAuth config +// ProxyClientConfigToYAML returns yaml representation of provided ProxyClientConfig config // Please note all secret values will be added as a plain text to it. -func (ac *AssetsCache) ProxyAuthToYAML(ns string, cfg *vmv1beta1.ProxyAuth) (yaml.MapSlice, error) { +func (ac *AssetsCache) ProxyClientConfigToYAML(ns string, cfg *vmv1beta1.ProxyClientConfig) (yaml.MapSlice, error) { if cfg == nil { return nil, nil } @@ -238,6 +238,24 @@ func (ac *AssetsCache) ProxyAuthToYAML(ns string, cfg *vmv1beta1.ProxyAuth) (yam r = append(r, yaml.MapItem{Key: "proxy_tls_config", Value: authYaml}) } } + if cfg.Authorization != nil { + authYaml, err := ac.AuthorizationToYAML(ns, cfg.Authorization) + if err != nil { + return nil, err + } + if len(authYaml) > 0 { + r = append(r, yaml.MapItem{Key: "proxy_authorization", Value: authYaml}) + } + } + if cfg.OAuth2 != nil { + authYaml, err := ac.OAuth2ToYAML(ns, cfg.OAuth2) + if err != nil { + return nil, err + } + if len(authYaml) > 0 { + r = append(r, yaml.MapItem{Key: "proxy_oauth2", Value: authYaml}) + } + } if cfg.BearerToken != nil { if bearerToken, err := ac.LoadKeyFromSecret(ns, cfg.BearerToken); err != nil { return nil, err diff --git a/internal/controller/operator/factory/build/vmscrape.go b/internal/controller/operator/factory/build/vmscrape.go index b9ef3aac7..56a6762c5 100644 --- a/internal/controller/operator/factory/build/vmscrape.go +++ b/internal/controller/operator/factory/build/vmscrape.go @@ -175,14 +175,12 @@ func VMPodScrape(b podScrapeBuilder, portName string) *vmv1beta1.VMPodScrape { if serviceScrapeSpec != nil { for _, e := range serviceScrapeSpec.Endpoints { if e.Port == *endpoint.Port { - endpoint.EndpointAuth = e.EndpointAuth endpoint.EndpointScrapeParams = e.EndpointScrapeParams endpoint.EndpointRelabelings = e.EndpointRelabelings continue } scrape.Spec.PodMetricsEndpoints = append(scrape.Spec.PodMetricsEndpoints, vmv1beta1.PodMetricsEndpoint{ Port: ptr.To(e.Port), - EndpointAuth: e.EndpointAuth, EndpointRelabelings: e.EndpointRelabelings, EndpointScrapeParams: e.EndpointScrapeParams, }) diff --git a/internal/controller/operator/factory/build/vmscrape_test.go b/internal/controller/operator/factory/build/vmscrape_test.go index 092f8777c..08ceac08b 100644 --- a/internal/controller/operator/factory/build/vmscrape_test.go +++ b/internal/controller/operator/factory/build/vmscrape_test.go @@ -299,9 +299,9 @@ func TestVMServiceScrapeForServiceWithSpec(t *testing.T) { Path: "/metrics", Params: map[string][]string{"authKey": {"some-access-key"}}, Scheme: "https", - }, - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{InsecureSkipVerify: true}, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{InsecureSkipVerify: true}, + }, }, Port: "http", }}, diff --git a/internal/controller/operator/factory/converter/apis.go b/internal/controller/operator/factory/converter/apis.go index cf8e24291..483b292b2 100644 --- a/internal/controller/operator/factory/converter/apis.go +++ b/internal/controller/operator/factory/converter/apis.go @@ -216,18 +216,18 @@ func convertEndpoint(ctx context.Context, promEndpoint []promv1.Endpoint) []vmv1 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), + 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(ctx, endpoint.MetricRelabelConfigs), @@ -361,20 +361,19 @@ func convertPodEndpoints(ctx context.Context, promPodEnpoints []promv1.PodMetric HonorTimestamps: promEndPoint.HonorTimestamps, ProxyURL: promEndPoint.ProxyURL, FollowRedirects: promEndPoint.FollowRedirects, + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: ConvertBasicAuth(promEndPoint.BasicAuth), + //nolint:staticcheck + BearerTokenSecret: convertBearerToken(promEndPoint.BearerTokenSecret), + TLSConfig: ConvertSafeTLSConfig(safeTLS), + OAuth2: ConvertOAuth(promEndPoint.OAuth2), + Authorization: ConvertAuthorization(promEndPoint.Authorization, nil), + }, }, EndpointRelabelings: vmv1beta1.EndpointRelabelings{ RelabelConfigs: ConvertRelabelConfig(ctx, promEndPoint.RelabelConfigs), MetricRelabelConfigs: ConvertRelabelConfig(ctx, promEndPoint.MetricRelabelConfigs), }, - - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: ConvertBasicAuth(promEndPoint.BasicAuth), - //nolint:staticcheck - BearerTokenSecret: convertBearerToken(promEndPoint.BearerTokenSecret), - TLSConfig: ConvertSafeTLSConfig(safeTLS), - OAuth2: ConvertOAuth(promEndPoint.OAuth2), - Authorization: ConvertAuthorization(promEndPoint.Authorization, nil), - }, FilterRunning: promEndPoint.FilterRunning, } endPoints = append(endPoints, ep) @@ -477,16 +476,16 @@ func Probe(ctx context.Context, probe *promv1.Probe, conf *config.BaseOperatorCo EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Interval: string(probe.Spec.Interval), ScrapeTimeout: string(probe.Spec.ScrapeTimeout), + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: ConvertBasicAuth(probe.Spec.BasicAuth), + BearerTokenSecret: convertBearerToken(probe.Spec.BearerTokenSecret), //nolint:staticcheck + TLSConfig: ConvertSafeTLSConfig(safeTLS), + OAuth2: ConvertOAuth(probe.Spec.OAuth2), + Authorization: ConvertAuthorization(probe.Spec.Authorization, nil), + }, }, MetricRelabelConfigs: ConvertRelabelConfig(ctx, probe.Spec.MetricRelabelConfigs), - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: ConvertBasicAuth(probe.Spec.BasicAuth), - BearerTokenSecret: convertBearerToken(probe.Spec.BearerTokenSecret), //nolint:staticcheck - TLSConfig: ConvertSafeTLSConfig(safeTLS), - OAuth2: ConvertOAuth(probe.Spec.OAuth2), - Authorization: ConvertAuthorization(probe.Spec.Authorization, nil), - }, - ScrapeClassName: probe.Spec.ScrapeClassName, + ScrapeClassName: probe.Spec.ScrapeClassName, }, } if probe.Spec.ProberSpec.ProxyURL != nil { diff --git a/internal/controller/operator/factory/converter/apis_test.go b/internal/controller/operator/factory/converter/apis_test.go index 5353402f4..ae29eb192 100644 --- a/internal/controller/operator/factory/converter/apis_test.go +++ b/internal/controller/operator/factory/converter/apis_test.go @@ -254,11 +254,13 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + }, }, }, }, @@ -287,13 +289,15 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - ServerName: "some-srv", - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + ServerName: "some-srv", + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + }, }, }, }, @@ -317,15 +321,17 @@ func TestConvertPodEndpoints(t *testing.T) { }, }}, want: []vmv1beta1.PodMetricsEndpoint{{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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"}, }, }, }}, diff --git a/internal/controller/operator/factory/converter/v1alpha1/apis_test.go b/internal/controller/operator/factory/converter/v1alpha1/apis_test.go index 91fc0fd52..ce47e29a4 100644 --- a/internal/controller/operator/factory/converter/v1alpha1/apis_test.go +++ b/internal/controller/operator/factory/converter/v1alpha1/apis_test.go @@ -138,16 +138,16 @@ func TestConvertScrapeConfig(t *testing.T) { VMScrapeParams: &vmv1beta1.VMScrapeParams{DisableCompression: ptr.To(false)}, Path: "/test", ScrapeInterval: "5m", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{Key: "username"}, + Password: corev1.SecretKeySelector{Key: "password"}, + }, + }, }, StaticConfigs: []vmv1beta1.StaticConfig{{ Targets: []string{"target-1", "target-2"}, }}, - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{Key: "username"}, - Password: corev1.SecretKeySelector{Key: "password"}, - }, - }, EndpointRelabelings: vmv1beta1.EndpointRelabelings{ RelabelConfigs: []*vmv1beta1.RelabelConfig{{ Action: "LabelMap", diff --git a/internal/controller/operator/factory/vmagent/scrapes_test.go b/internal/controller/operator/factory/vmagent/scrapes_test.go index fc7069183..093733a21 100644 --- a/internal/controller/operator/factory/vmagent/scrapes_test.go +++ b/internal/controller/operator/factory/vmagent/scrapes_test.go @@ -93,15 +93,15 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - 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", + }, }, }, }, @@ -155,7 +155,7 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ TLSConfig: &vmv1beta1.TLSConfig{ InsecureSkipVerify: true, KeySecret: &corev1.SecretKeySelector{ @@ -187,28 +187,28 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { Port: ptr.To("801"), 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", - }, - }, - Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + 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", + }, + }, }, }, }, @@ -223,18 +223,20 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { Name: "test-vms", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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", + }, }, }, }, @@ -253,23 +255,23 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { 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", + 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", + }, + }, + }, }, }, }, @@ -569,18 +571,20 @@ scrape_configs: Name: "test-bad-0", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -602,11 +606,13 @@ scrape_configs: Name: "bad-1", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -637,7 +643,7 @@ scrape_configs: Path: "/metrics-3", VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ BearerToken: &corev1.SecretKeySelector{ Key: "username", LocalObjectReference: corev1.LocalObjectReference{ @@ -652,19 +658,19 @@ scrape_configs: Port: ptr.To("801"), EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics-5", - }, - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -718,23 +724,23 @@ scrape_configs: 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-credentials", - }, - }, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cid", + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "https://some-tr", + ClientSecret: &corev1.SecretKeySelector{ + Key: "cs", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-credentials", }, }, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cid", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, + }, + }, }, }, }, @@ -754,14 +760,14 @@ scrape_configs: 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-credentials", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cert", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-credentials", + }, }, }, }, @@ -886,15 +892,15 @@ scrape_configs: NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - 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", + }, }, }, }, @@ -1081,57 +1087,57 @@ scrape_configs: NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, - }, - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -1148,47 +1154,49 @@ scrape_configs: PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { Port: ptr.To("8081"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, }, }, @@ -1203,47 +1211,49 @@ scrape_configs: }, Spec: vmv1beta1.VMNodeScrapeSpec{ Port: "9093", - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, }, }, @@ -1585,9 +1595,11 @@ scrape_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CAFile: "/etc/passwd", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CAFile: "/etc/passwd", + }, }, }, }, @@ -1660,13 +1672,15 @@ scrape_configs: [] Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, }, }, }, @@ -1691,13 +1705,15 @@ scrape_configs: [] }, { Port: ptr.To("8080"), - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, }, }, }, @@ -2018,18 +2034,22 @@ scrape_configs: PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { Port: ptr.To("8085"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "http://some-url", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "http://some-url", + }, }, }, }, { Port: ptr.To("8085"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "http://some-other", - ClientSecretFile: "/path/to/file", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "http://some-other", + ClientSecretFile: "/path/to/file", + }, }, }, }, @@ -2210,7 +2230,9 @@ scrape_configs: [] f(&vmv1beta1.VMProbe{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMProbeSpec{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }) @@ -2218,14 +2240,18 @@ scrape_configs: [] ObjectMeta: commonMeta, Spec: vmv1beta1.VMStaticScrapeSpec{ TargetEndpoints: []*vmv1beta1.TargetEndpoint{{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }}, }, }) f(&vmv1beta1.VMNodeScrape{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }) @@ -2233,7 +2259,9 @@ scrape_configs: [] ObjectMeta: commonMeta, Spec: vmv1beta1.VMPodScrapeSpec{ PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }}, }, }) @@ -2242,7 +2270,9 @@ scrape_configs: [] ObjectMeta: commonMeta, Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }}, }, }) diff --git a/internal/controller/operator/factory/vmagent/vmagent_test.go b/internal/controller/operator/factory/vmagent/vmagent_test.go index 5b3e20b95..0a17cc33f 100644 --- a/internal/controller/operator/factory/vmagent/vmagent_test.go +++ b/internal/controller/operator/factory/vmagent/vmagent_test.go @@ -197,11 +197,11 @@ func TestCreateOrUpdate(t *testing.T) { 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"}, + 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"}, + }, }, }, }, @@ -341,16 +341,16 @@ func TestCreateOrUpdate(t *testing.T) { 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"}, + 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"}, }, }, }, diff --git a/internal/controller/operator/factory/vmalertmanager/config.go b/internal/controller/operator/factory/vmalertmanager/config.go index 3f4f0eff4..bb158c358 100644 --- a/internal/controller/operator/factory/vmalertmanager/config.go +++ b/internal/controller/operator/factory/vmalertmanager/config.go @@ -73,6 +73,11 @@ func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []by return err } } + if cr.Spec.ArbitraryFSAccessThroughSMs.Deny { + if err := cfg.ValidateArbitraryFSAccess(); err != nil { + return err + } + } var receiverCfgs []yaml.MapSlice for _, receiver := range cfg.Spec.Receivers { receiverCfg, err := buildReceiver(cfg, receiver, &globalConfigOpts, ac) diff --git a/internal/controller/operator/factory/vmscrapes/nodescrape_test.go b/internal/controller/operator/factory/vmscrapes/nodescrape_test.go index 2f8af5fad..fd2d89aac 100644 --- a/internal/controller/operator/factory/vmscrapes/nodescrape_test.go +++ b/internal/controller/operator/factory/vmscrapes/nodescrape_test.go @@ -117,26 +117,26 @@ relabel_configs: HonorTimestamps: ptr.To(true), VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ TLSConfig: &vmv1beta1.TLSConfig{ InsecureSkipVerify: true, }, BearerTokenFile: "/tmp/proxy-token", }, }, - }, - EndpointAuth: vmv1beta1.EndpointAuth{ - BearerTokenFile: "/tmp/bearer", - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "ba-secret", + 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, + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, }, }, JobLabel: "env", diff --git a/internal/controller/operator/factory/vmscrapes/objects.go b/internal/controller/operator/factory/vmscrapes/objects.go index 9ec86ca93..b2cb94748 100644 --- a/internal/controller/operator/factory/vmscrapes/objects.go +++ b/internal/controller/operator/factory/vmscrapes/objects.go @@ -234,7 +234,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { pos.serviceScrapes.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMServiceScrape) error { if sp.ArbitraryFSAccessThroughSMs.Deny { for _, ep := range sc.Spec.Endpoints { - if err := testForArbitraryFSAccess(ep.EndpointAuth); err != nil { + if err := ep.ValidateArbitraryFSAccess(); err != nil { return err } } @@ -250,7 +250,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { pos.podScrapes.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMPodScrape) error { if sp.ArbitraryFSAccessThroughSMs.Deny { for _, ep := range sc.Spec.PodMetricsEndpoints { - if err := testForArbitraryFSAccess(ep.EndpointAuth); err != nil { + if err := ep.ValidateArbitraryFSAccess(); err != nil { return err } } @@ -266,7 +266,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { pos.staticScrapes.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMStaticScrape) error { if sp.ArbitraryFSAccessThroughSMs.Deny { for _, ep := range sc.Spec.TargetEndpoints { - if err := testForArbitraryFSAccess(ep.EndpointAuth); err != nil { + if err := ep.ValidateArbitraryFSAccess(); err != nil { return err } } @@ -281,7 +281,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { }) pos.nodeScrapes.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMNodeScrape) error { if sp.ArbitraryFSAccessThroughSMs.Deny { - if err := testForArbitraryFSAccess(sc.Spec.EndpointAuth); err != nil { + if err := sc.Spec.ValidateArbitraryFSAccess(); err != nil { return err } } @@ -295,7 +295,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { }) pos.probes.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMProbe) error { if sp.ArbitraryFSAccessThroughSMs.Deny { - if err := testForArbitraryFSAccess(sc.Spec.EndpointAuth); err != nil { + if err := sc.Spec.ValidateArbitraryFSAccess(); err != nil { return err } } @@ -310,7 +310,7 @@ func (pos *ParsedObjects) ValidateObjects(sp *vmv1beta1.CommonScrapeParams) { pos.scrapeConfigs.ForEachCollectSkipInvalid(func(sc *vmv1beta1.VMScrapeConfig) error { // TODO: @f41gh7 validate per configuration FS access if sp.ArbitraryFSAccessThroughSMs.Deny { - if err := testForArbitraryFSAccess(sc.Spec.EndpointAuth); err != nil { + if err := sc.Spec.ValidateArbitraryFSAccess(); err != nil { return err } } diff --git a/internal/controller/operator/factory/vmscrapes/probe_test.go b/internal/controller/operator/factory/vmscrapes/probe_test.go index f806fc093..0602172a2 100644 --- a/internal/controller/operator/factory/vmscrapes/probe_test.go +++ b/internal/controller/operator/factory/vmscrapes/probe_test.go @@ -522,7 +522,7 @@ relabel_configs: ScrapeTimeout: "15s", VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(false), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ TLSConfig: &vmv1beta1.TLSConfig{ CA: vmv1beta1.SecretOrConfigMap{ ConfigMap: &corev1.ConfigMapKeySelector{ @@ -544,11 +544,11 @@ relabel_configs: }, }, }, - }, - EndpointAuth: vmv1beta1.EndpointAuth{ - BearerTokenFile: "/tmp/some_path", - BasicAuth: &vmv1beta1.BasicAuth{ - PasswordFile: "/tmp/some-file-ba", + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenFile: "/tmp/some_path", + BasicAuth: &vmv1beta1.BasicAuth{ + PasswordFile: "/tmp/some-file-ba", + }, }, }, VMProberSpec: vmv1beta1.VMProberSpec{URL: "blackbox-monitor:9115"}, diff --git a/internal/controller/operator/factory/vmscrapes/scrapeconfig.go b/internal/controller/operator/factory/vmscrapes/scrapeconfig.go index d38e70623..979e84ca4 100644 --- a/internal/controller/operator/factory/vmscrapes/scrapeconfig.go +++ b/internal/controller/operator/factory/vmscrapes/scrapeconfig.go @@ -920,7 +920,7 @@ func generateHTTPSDOptions(config vmv1beta1.HTTPSDOptions, namespace string, ac cfg = append(cfg, yaml.MapItem{Key: "proxy_url", Value: config.ProxyURL}) } if config.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(namespace, config.ProxyClientConfig); err != nil { + if c, err := ac.ProxyClientConfigToYAML(namespace, config.ProxyClientConfig); err != nil { return nil, err } else { cfg = append(cfg, c...) diff --git a/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go b/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go index 17da8a361..8554d6faf 100644 --- a/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go +++ b/internal/controller/operator/factory/vmscrapes/scrapeconfig_test.go @@ -56,29 +56,29 @@ func TestGenerateScrapeConfig(t *testing.T) { Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ - MaxScrapeSize: "60KB", - ScrapeInterval: "10s", - }, StaticConfigs: []vmv1beta1.StaticConfig{ { Targets: []string{"http://test1.com", "http://test2.com"}, Labels: map[string]string{"bar": "baz"}, }, }, - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "ba-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + MaxScrapeSize: "60KB", + ScrapeInterval: "10s", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "ba-secret", + }, + Key: "username", }, - Key: "username", - }, - Password: corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "ba-secret", + Password: corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "ba-secret", + }, + Key: "password", }, - Key: "password", }, }, }, @@ -133,20 +133,20 @@ static_configs: Namespace: "default", }, Spec: vmv1beta1.VMScrapeConfigSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "ba-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ScrapeInterval: "10m", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "ba-secret", + }, }, + PasswordFile: "/var/run/secrets/password", }, - PasswordFile: "/var/run/secrets/password", }, }, - EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ - ScrapeInterval: "10m", - }, FileSDConfigs: []vmv1beta1.FileSDConfig{ { Files: []string{"test1.json", "test2.json"}, diff --git a/internal/controller/operator/factory/vmscrapes/servicescrape_test.go b/internal/controller/operator/factory/vmscrapes/servicescrape_test.go index 83a59e02a..c87ec024c 100644 --- a/internal/controller/operator/factory/vmscrapes/servicescrape_test.go +++ b/internal/controller/operator/factory/vmscrapes/servicescrape_test.go @@ -73,18 +73,20 @@ func Test_generateServiceScrapeConfig(t *testing.T) { Node: ptr.To(true), }, Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -175,22 +177,22 @@ bearer_token_file: /var/run/token Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + ScrapeInterval: "60m", + 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/token", }, - BearerTokenFile: "/var/run/token", - }, - EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ - ScrapeInterval: "60m", }, }, }, @@ -282,20 +284,20 @@ bearer_token_file: /var/run/token Port: "8080", 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", + 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/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -381,19 +383,21 @@ bearer_token_file: /var/run/token Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -482,19 +486,21 @@ bearer_token_file: /var/run/token Namespace: ptr.To(true), }, Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -607,11 +613,13 @@ relabel_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + BearerTokenFile: "/var/run/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -665,67 +673,6 @@ bearer_token_file: /var/run/token Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, - }, - }, - BearerTokenFile: "/var/run/token", - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, - }, - 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: "id", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, - }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "secret", - LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, - }, - ProxyURL: "http://oauth2-access-proxy", - TLSConfig: &vmv1beta1.TLSConfig{ - InsecureSkipVerify: true, - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-cm", - }, - }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "key", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls", - }, - }, - }, - KeySecret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls", - }, - }, - }, - }, - }, EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Params: map[string][]string{"module": {"base"}}, ScrapeInterval: "10s", @@ -739,11 +686,72 @@ bearer_token_file: /var/run/token VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ TLSConfig: &vmv1beta1.TLSConfig{InsecureSkipVerify: true}, BearerTokenFile: "/tmp/some-file", }, }, + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + }, + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + }, + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + }, + }, + BearerTokenFile: "/var/run/token", + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, + 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: "id", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "secret", + LocalObjectReference: corev1.LocalObjectReference{Name: "access-secret"}, + }, + ProxyURL: "http://oauth2-access-proxy", + TLSConfig: &vmv1beta1.TLSConfig{ + InsecureSkipVerify: true, + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-cm", + }, + }, + }, + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "key", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "cert", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls", + }, + }, + }, + }, + }, }, EndpointRelabelings: vmv1beta1.EndpointRelabelings{ MetricRelabelConfigs: []*vmv1beta1.RelabelConfig{}, @@ -884,19 +892,21 @@ oauth2: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - Cert: vmv1beta1.SecretOrConfigMap{}, - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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/token", }, - BearerTokenFile: "/var/run/token", }, }, }, @@ -1860,13 +1870,15 @@ relabel_configs: Node: ptr.To(true), }, Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ProxyURL: "http://expected", - ClientID: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "some", - LocalObjectReference: corev1.LocalObjectReference{Name: "cm"}, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ProxyURL: "http://expected", + ClientID: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "some", + LocalObjectReference: corev1.LocalObjectReference{Name: "cm"}, + }, }, }, }, diff --git a/internal/controller/operator/factory/vmscrapes/staticscrape_test.go b/internal/controller/operator/factory/vmscrapes/staticscrape_test.go index 6cd62e342..ef73b3740 100644 --- a/internal/controller/operator/factory/vmscrapes/staticscrape_test.go +++ b/internal/controller/operator/factory/vmscrapes/staticscrape_test.go @@ -181,7 +181,7 @@ relabel_configs: ScrapeAlignInterval: ptr.To("5s"), StreamParse: ptr.To(true), Headers: []string{"customer-header: with-value"}, - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ BasicAuth: &vmv1beta1.BasicAuth{ Username: corev1.SecretKeySelector{ Key: "username", @@ -194,38 +194,38 @@ relabel_configs: }, }, }, - }, - 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"}, + 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, }, - InsecureSkipVerify: true, - }, - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{Name: "ba-secret"}, + }, + Password: corev1.SecretKeySelector{ + Key: "password", + 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"}, }, - }, - 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"}}, + 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"}}, + }, }, }, }, diff --git a/internal/controller/operator/factory/vmscrapes/vmscrapes.go b/internal/controller/operator/factory/vmscrapes/vmscrapes.go index bba37bbb4..e7241a250 100644 --- a/internal/controller/operator/factory/vmscrapes/vmscrapes.go +++ b/internal/controller/operator/factory/vmscrapes/vmscrapes.go @@ -22,35 +22,6 @@ const ( kubeNodeEnvTemplate = "%{" + vmv1beta1.KubeNodeEnvName + "}" ) -// TODO: @f41gh7 validate VMScrapeParams -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 { - return nil - } - - if err := e.TLSConfig.Validate(); err != nil { - return err - } - - if tlsConf.CAFile != "" || tlsConf.CertFile != "" || tlsConf.KeyFile != "" { - return fmt.Errorf("it accesses file system via tls config which VMAgent specification prohibits") - } - - return nil -} - func setScrapeIntervalToWithLimit(ctx context.Context, dst *vmv1beta1.EndpointScrapeParams, sp *vmv1beta1.CommonScrapeParams) { if dst.ScrapeInterval == "" { dst.ScrapeInterval = dst.Interval @@ -443,7 +414,7 @@ func buildVMScrapeParams(namespace string, cfg *vmv1beta1.VMScrapeParams, ac *bu r = append(r, yaml.MapItem{Key: "headers", Value: cfg.Headers}) } if cfg.ProxyClientConfig != nil { - if c, err := ac.ProxyAuthToYAML(namespace, cfg.ProxyClientConfig); err != nil { + if c, err := ac.ProxyClientConfigToYAML(namespace, cfg.ProxyClientConfig); err != nil { return nil, err } else if len(c) > 0 { r = append(r, c...) diff --git a/internal/controller/operator/factory/vmsingle/scrapes_test.go b/internal/controller/operator/factory/vmsingle/scrapes_test.go index ec6f1c991..58284c378 100644 --- a/internal/controller/operator/factory/vmsingle/scrapes_test.go +++ b/internal/controller/operator/factory/vmsingle/scrapes_test.go @@ -95,15 +95,15 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - 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", + }, }, }, }, @@ -157,7 +157,7 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ TLSConfig: &vmv1beta1.TLSConfig{ InsecureSkipVerify: true, KeySecret: &corev1.SecretKeySelector{ @@ -189,28 +189,28 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { Port: ptr.To("801"), 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", - }, - }, - Cert: vmv1beta1.SecretOrConfigMap{Secret: &corev1.SecretKeySelector{ - Key: "cert", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + 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", + }, + }, }, }, }, @@ -225,18 +225,20 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { Name: "test-vms", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + 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", + }, }, }, }, @@ -255,23 +257,23 @@ func TestCreateOrUpdateScrapeConfig(t *testing.T) { 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", + 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", + }, + }, + }, }, }, }, @@ -572,18 +574,20 @@ scrape_configs: Name: "test-bad-0", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -605,11 +609,13 @@ scrape_configs: Name: "bad-1", }, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: vmv1beta1.EndpointAuth{ - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -640,7 +646,7 @@ scrape_configs: Path: "/metrics-3", VMScrapeParams: &vmv1beta1.VMScrapeParams{ StreamParse: ptr.To(true), - ProxyClientConfig: &vmv1beta1.ProxyAuth{ + ProxyClientConfig: &vmv1beta1.ProxyClientConfig{ BearerToken: &corev1.SecretKeySelector{ Key: "username", LocalObjectReference: corev1.LocalObjectReference{ @@ -655,19 +661,19 @@ scrape_configs: Port: ptr.To("801"), EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics-5", - }, - EndpointAuth: vmv1beta1.EndpointAuth{ - BasicAuth: &vmv1beta1.BasicAuth{ - Username: corev1.SecretKeySelector{ - Key: "username", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + EndpointAuth: vmv1beta1.EndpointAuth{ + BasicAuth: &vmv1beta1.BasicAuth{ + Username: corev1.SecretKeySelector{ + Key: "username", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, - }, - Password: corev1.SecretKeySelector{ - Key: "password", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-credentials", + Password: corev1.SecretKeySelector{ + Key: "password", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, }, }, }, @@ -721,23 +727,23 @@ scrape_configs: 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-credentials", - }, - }, - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "cid", + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "https://some-tr", + ClientSecret: &corev1.SecretKeySelector{ + Key: "cs", LocalObjectReference: corev1.LocalObjectReference{ Name: "access-credentials", }, }, + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cid", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-credentials", + }, + }, + }, }, }, }, @@ -757,14 +763,14 @@ scrape_configs: 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-credentials", + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "cert", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-credentials", + }, }, }, }, @@ -890,15 +896,15 @@ scrape_configs: NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - 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", + }, }, }, }, @@ -1086,57 +1092,57 @@ scrape_configs: NamespaceSelector: vmv1beta1.NamespaceSelector{}, Endpoints: []vmv1beta1.Endpoint{ { + Port: "8085", EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ Path: "/metrics", - }, - Port: "8085", - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, - }, - BearerTokenSecret: &corev1.SecretKeySelector{ - Key: "bearer", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "access-creds", + BearerTokenSecret: &corev1.SecretKeySelector{ + Key: "bearer", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "access-creds", + }, }, }, }, @@ -1153,47 +1159,49 @@ scrape_configs: PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { Port: ptr.To("8081"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, }, }, @@ -1208,47 +1216,49 @@ scrape_configs: }, Spec: vmv1beta1.VMNodeScrapeSpec{ Port: "9093", - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - ClientID: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CLIENT_ID", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + ClientID: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CLIENT_ID", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "oauth2-access", + }, + }, + }, + ClientSecret: &corev1.SecretKeySelector{ + Key: "CLIENT_SECRET", LocalObjectReference: corev1.LocalObjectReference{ Name: "oauth2-access", }, }, - }, - ClientSecret: &corev1.SecretKeySelector{ - Key: "CLIENT_SECRET", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "oauth2-access", - }, - }, - TokenURL: "http://some-url", - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - ConfigMap: &corev1.ConfigMapKeySelector{ - Key: "CA", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-default", + TokenURL: "http://some-url", + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + ConfigMap: &corev1.ConfigMapKeySelector{ + Key: "CA", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-default", + }, }, }, - }, - Cert: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "CERT", + Cert: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "CERT", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, + }, + }, + KeySecret: &corev1.SecretKeySelector{ + Key: "SECRET_KEY", LocalObjectReference: corev1.LocalObjectReference{ Name: "tls-auth", }, }, + InsecureSkipVerify: false, }, - KeySecret: &corev1.SecretKeySelector{ - Key: "SECRET_KEY", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", - }, - }, - InsecureSkipVerify: false, }, }, }, @@ -1456,9 +1466,11 @@ scrape_configs: Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CAFile: "/etc/passwd", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CAFile: "/etc/passwd", + }, }, }, }, @@ -1527,13 +1539,15 @@ scrape_configs: [] Endpoints: []vmv1beta1.Endpoint{ { Port: "8080", - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, }, }, }, @@ -1558,13 +1572,15 @@ scrape_configs: [] }, { Port: ptr.To("8080"), - EndpointAuth: vmv1beta1.EndpointAuth{ - TLSConfig: &vmv1beta1.TLSConfig{ - CA: vmv1beta1.SecretOrConfigMap{ - Secret: &corev1.SecretKeySelector{ - Key: "ca", - LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-auth", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + TLSConfig: &vmv1beta1.TLSConfig{ + CA: vmv1beta1.SecretOrConfigMap{ + Secret: &corev1.SecretKeySelector{ + Key: "ca", + LocalObjectReference: corev1.LocalObjectReference{ + Name: "tls-auth", + }, }, }, }, @@ -1886,18 +1902,22 @@ scrape_configs: PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { Port: ptr.To("8085"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "http://some-url", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "http://some-url", + }, }, }, }, { Port: ptr.To("8085"), - EndpointAuth: vmv1beta1.EndpointAuth{ - OAuth2: &vmv1beta1.OAuth2{ - TokenURL: "http://some-other", - ClientSecretFile: "/path/to/file", + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: vmv1beta1.EndpointAuth{ + OAuth2: &vmv1beta1.OAuth2{ + TokenURL: "http://some-other", + ClientSecretFile: "/path/to/file", + }, }, }, }, @@ -2080,7 +2100,9 @@ scrape_configs: [] f(&vmv1beta1.VMProbe{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMProbeSpec{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }) @@ -2089,7 +2111,9 @@ scrape_configs: [] Spec: vmv1beta1.VMStaticScrapeSpec{ TargetEndpoints: []*vmv1beta1.TargetEndpoint{ { - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }, }, @@ -2097,7 +2121,9 @@ scrape_configs: [] f(&vmv1beta1.VMNodeScrape{ ObjectMeta: commonMeta, Spec: vmv1beta1.VMNodeScrapeSpec{ - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }) @@ -2106,7 +2132,9 @@ scrape_configs: [] Spec: vmv1beta1.VMPodScrapeSpec{ PodMetricsEndpoints: []vmv1beta1.PodMetricsEndpoint{ { - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }, }, @@ -2117,7 +2145,9 @@ scrape_configs: [] Spec: vmv1beta1.VMServiceScrapeSpec{ Endpoints: []vmv1beta1.Endpoint{ { - EndpointAuth: commonEndpointAuthWithMissingRef, + EndpointScrapeParams: vmv1beta1.EndpointScrapeParams{ + EndpointAuth: commonEndpointAuthWithMissingRef, + }, }, }, }, From 59784ba7eb7467892237de185a6e4bab2db0a75a Mon Sep 17 00:00:00 2001 From: Andrii Chubatiuk Date: Wed, 1 Apr 2026 09:11:28 +0300 Subject: [PATCH 3/5] added mattermost support --- api/operator/v1beta1/vmalertmanager_types.go | 4 +- .../v1beta1/vmalertmanagerconfig_types.go | 852 ++++--- .../vmalertmanagerconfig_types_test.go | 6 +- api/operator/v1beta1/vmextra_types.go | 2 +- api/operator/v1beta1/zz_generated.deepcopy.go | 294 ++- config/crd/overlay/crd.descriptionless.yaml | 94 +- config/crd/overlay/crd.yaml | 136 +- docs/api.md | 165 +- .../factory/converter/v1alpha1/apis.go | 11 +- .../operator/factory/vmalertmanager/config.go | 2131 ++++++++--------- .../factory/vmalertmanager/config_test.go | 118 +- .../factory/vmalertmanager/statefulset.go | 13 - 12 files changed, 2114 insertions(+), 1712 deletions(-) diff --git a/api/operator/v1beta1/vmalertmanager_types.go b/api/operator/v1beta1/vmalertmanager_types.go index fc60864e4..bf474cf8d 100644 --- a/api/operator/v1beta1/vmalertmanager_types.go +++ b/api/operator/v1beta1/vmalertmanager_types.go @@ -596,9 +596,9 @@ type VMAlertmanagerTracingConfig struct { // TLSConfig defines tracing TLS config // +optional TLSConfig *TLSClientConfig `json:"tls_config,omitempty"` - // HTTPHeaders defines custom HTTP headers for tracing + // Headers defines custom HTTP headers for tracing // +optional - HTTPHeaders map[string]string `json:"http_headers,omitempty"` + Headers map[string]string `json:"headers,omitempty"` // Compression defines compression algorithm for tracing // +optional Compression string `json:"compression,omitempty"` diff --git a/api/operator/v1beta1/vmalertmanagerconfig_types.go b/api/operator/v1beta1/vmalertmanagerconfig_types.go index 8899f5b9a..26282edd8 100644 --- a/api/operator/v1beta1/vmalertmanagerconfig_types.go +++ b/api/operator/v1beta1/vmalertmanagerconfig_types.go @@ -121,87 +121,92 @@ func (cr *VMAlertmanagerConfig) ValidateArbitraryFSAccess() error { for i, r := range cr.Spec.Receivers { for j, rc := range r.EmailConfigs { if err := rc.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].email_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].email_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.PagerDutyConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].pagerduty_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].pagerduty_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.PushoverConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].pushover_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].pushover_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.SlackConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].slack_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].slack_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.OpsGenieConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].opsgenie_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].opsgenie_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.WebhookConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].webhook_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].webhook_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.VictorOpsConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].victorops_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].victorops_configs[%d]: found prohibited properties: %w", i, j, err) } } - for j, rc := range r.WeChatConfigs { + for j, rc := range r.WechatConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].wechat_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].wechat_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.TelegramConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].telegram_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].telegram_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.MSTeamsConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].msteams_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].msteams_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.DiscordConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].discord_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].discord_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.SNSConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].sns_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].sns_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.WebexConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].webex_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].webex_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.JiraConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].jira_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].jira_configs[%d]: found prohibited properties: %w", i, j, err) } } - for j, rc := range r.IncidentIOConfigs { + for j, rc := range r.IncidentioConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].incidentio_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].incidentio_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.RocketchatConfigs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].rocketchat_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].rocketchat_configs[%d]: found prohibited properties: %w", i, j, err) } } for j, rc := range r.MSTeamsV2Configs { if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { - return fmt.Errorf("found prohibited properties at spec.receivers[%d].msteamsv2_configs[%d]: %w", i, j, err) + return fmt.Errorf("spec.receivers[%d].msteamsv2_configs[%d]: found prohibited properties: %w", i, j, err) + } + } + for j, rc := range r.MattermostConfigs { + if err := rc.HTTPConfig.validateArbitraryFSAccess(); err != nil { + return fmt.Errorf("spec.receivers[%d].mattermost_configs[%d]: found prohibited properties: %w", i, j, err) } } } @@ -219,7 +224,7 @@ func (r *VMAlertmanagerConfig) Validate() error { } receivers[recv.Name] = struct{}{} if err := validateReceiver(recv); err != nil { - return fmt.Errorf("receiver at idx=%d is invalid: %w", idx, err) + return fmt.Errorf("receivers[%d]: %w", idx, err) } } tiNames, err := validateTimeIntervals(r.Spec.TimeIntervals) @@ -430,12 +435,15 @@ type Receiver struct { // +optional WebhookConfigs []WebhookConfig `json:"webhook_configs,omitempty" yaml:"webhook_configs,omitempty"` + // MattermostConfigs defines Mattermost notification configurations. + // +optional + MattermostConfigs []MattermostConfig `json:"mattermost_configs,omitempty" yaml:"mattermost_configs,omitempty"` // VictorOpsConfigs defines victor ops notification configurations. // +optional VictorOpsConfigs []VictorOpsConfig `json:"victorops_configs,omitempty" yaml:"victorops_configs,omitempty"` - // WeChatConfigs defines wechat notification configurations. + // WechatConfigs defines wechat notification configurations. // +optional - WeChatConfigs []WeChatConfig `json:"wechat_configs,omitempty" yaml:"wechat_configs,omitempty"` + WechatConfigs []WechatConfig `json:"wechat_configs,omitempty" yaml:"wechat_configs,omitempty"` // +optional TelegramConfigs []TelegramConfig `json:"telegram_configs,omitempty" yaml:"telegram_configs,omitempty"` // +optional @@ -443,13 +451,13 @@ type Receiver struct { // +optional DiscordConfigs []DiscordConfig `json:"discord_configs,omitempty" yaml:"discord_configs,omitempty"` // +optional - SNSConfigs []SnsConfig `json:"sns_configs,omitempty" yaml:"sns_configs,omitempty"` + SNSConfigs []SNSConfig `json:"sns_configs,omitempty" yaml:"sns_configs,omitempty"` // +optional WebexConfigs []WebexConfig `json:"webex_configs,omitempty" yaml:"webex_configs,omitempty"` // +optional JiraConfigs []JiraConfig `json:"jira_configs,omitempty" yaml:"jira_configs,omitempty"` // +optional - IncidentIOConfigs []IncidentIOConfig `json:"incidentio_configs,omitempty" yaml:"incidentio_configs,omitempty"` + IncidentioConfigs []IncidentioConfig `json:"incidentio_configs,omitempty" yaml:"incidentio_configs,omitempty"` // +optional RocketchatConfigs []RocketchatConfig `json:"rocketchat_configs,omitempty" yaml:"rocketchat_configs,omitempty"` // +optional @@ -488,6 +496,25 @@ type TelegramConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *TelegramConfig) validate() error { + if c.BotToken == nil { + return fmt.Errorf("required field 'bot_token' must be set") + } + if c.ChatID == 0 { + return fmt.Errorf("required field 'chat_id' must be set") + } + if c.ParseMode != "" && + c.ParseMode != "Markdown" && + c.ParseMode != "MarkdownV2" && + c.ParseMode != "HTML" { + return fmt.Errorf("unknown parse_mode=%q: must be Markdown, MarkdownV2, HTML or empty string", c.ParseMode) + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // WebhookConfig configures notifications via a generic receiver supporting the webhook payload. // See https://prometheus.io/docs/alerting/latest/configuration/#webhook_config type WebhookConfig struct { @@ -517,9 +544,27 @@ type WebhookConfig struct { Timeout string `json:"timeout,omitempty"` } -// WeChatConfig configures notifications via WeChat. +func (c *WebhookConfig) validate() error { + if c.URL == nil && c.URLSecret == nil { + return fmt.Errorf("one of 'url' or 'url_secret' must be specified") + } + if c.URL != nil && c.URLSecret != nil { + return fmt.Errorf("at most one of 'url' or 'url_secret' must be specified") + } + if c.URL != nil { + if _, err := url.Parse(*c.URL); err != nil { + return fmt.Errorf("invalid 'url': %w", err) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + +// WechatConfig configures notifications via Wechat. // See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config -type WeChatConfig struct { +type WechatConfig struct { // SendResolved controls notify about resolved alerts. // +optional SendResolved *bool `json:"send_resolved,omitempty" yaml:"send_resolved,omitempty"` @@ -553,6 +598,18 @@ type WeChatConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *WechatConfig) validate() error { + if c.APIURL != "" { + if _, err := url.Parse(c.APIURL); err != nil { + return fmt.Errorf("incorrect api_url=%q: %w", c.APIURL, err) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // EmailConfig configures notifications via Email. type EmailConfig struct { // SendResolved controls notify about resolved alerts. @@ -603,6 +660,38 @@ type EmailConfig struct { TLSConfig *TLSConfig `json:"tls_config,omitempty" yaml:"tls_config,omitempty"` } +func (c *EmailConfig) validate() error { + if c.To == "" { + return fmt.Errorf("required field `to` must be set") + } + if c.Smarthost != "" { + _, port, err := net.SplitHostPort(c.Smarthost) + if err != nil { + return fmt.Errorf("failed to parse `smarthost`: %w", err) + } + if port == "" { + return fmt.Errorf("smarthost=%q: port cannot be empty", c.Smarthost) + } + } + + if len(c.Headers) > 0 { + normalizedHeaders := map[string]struct{}{} + for key := range c.Headers { + normalized := strings.ToLower(key) + if _, ok := normalizedHeaders[normalized]; ok { + return fmt.Errorf("duplicate header %q", normalized) + } + normalizedHeaders[normalized] = struct{}{} + } + } + if c.TLSConfig != nil { + if err := c.TLSConfig.Validate(); err != nil { + return fmt.Errorf("invalid tls_config: %w", err) + } + } + return nil +} + func (c *EmailConfig) validateArbitraryFSAccess() error { var props []string props = c.TLSConfig.appendForbiddenProperties(props) @@ -649,6 +738,36 @@ type VictorOpsConfig struct { CustomFields map[string]string `json:"custom_fields,omitempty" yaml:"custom_fields,omitempty"` } +func (c *VictorOpsConfig) validate() error { + // from https://github.com/prometheus/alertmanager/blob/a7f9fdadbecbb7e692d2cd8d3334e3d6de1602e1/config/notifiers.go#L497 + reservedFields := map[string]struct{}{ + "routing_key": {}, + "message_type": {}, + "state_message": {}, + "entity_display_name": {}, + "monitoring_tool": {}, + "entity_id": {}, + "entity_state": {}, + } + for key := range c.CustomFields { + if _, ok := reservedFields[key]; ok { + return fmt.Errorf("encoundered usage of reserved word %q in custom fields", key) + } + } + if c.RoutingKey == "" { + return fmt.Errorf("missing 'routing_key' key") + } + if c.APIURL != "" { + if _, err := url.Parse(c.APIURL); err != nil { + return fmt.Errorf("incorrect api_url=%q: %w", c.APIURL, err) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // PushoverConfig configures notifications via Pushover. // See https://prometheus.io/docs/alerting/latest/configuration/#pushover_config type PushoverConfig struct { @@ -695,6 +814,19 @@ type PushoverConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *PushoverConfig) validate() error { + if c.UserKey == nil { + return fmt.Errorf("required field 'user_key' must be set") + } + if c.Token == nil { + return fmt.Errorf("required field 'token' must be set") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // SlackConfig configures notifications via Slack. // See https://prometheus.io/docs/alerting/latest/configuration/#slack_config type SlackConfig struct { @@ -757,6 +889,35 @@ type SlackConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *SlackConfig) validate() error { + for idx, a := range c.Actions { + if a.Type == "" { + return fmt.Errorf("actions[%d].type is required", idx) + } + if a.Text == "" { + return fmt.Errorf("actions[%d].text is required", idx) + } + if a.URL == "" && a.Name == "" { + return fmt.Errorf("actions[%d]: url or name should be set", idx) + } + if a.ConfirmField != nil && a.ConfirmField.Text == "" { + return fmt.Errorf("actions[%d].confirm_field.text must be set", idx) + } + } + for idx, field := range c.Fields { + if field.Value == "" { + return fmt.Errorf("fields[%d].value must be set", idx) + } + if field.Title == "" { + return fmt.Errorf("fields[%d].title must be set", idx) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // SlackField configures a single Slack field that is sent with each notification. // See https://api.slack.com/docs/message-attachments#fields for more information. type SlackField struct { @@ -860,6 +1021,28 @@ type OpsGenieConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *OpsGenieConfig) validate() error { + for idx, responder := range c.Responders { + if responder.ID == "" && responder.Name == "" && responder.Username == "" { + return fmt.Errorf("responders[%d]: one of id, name or username is required", idx) + } + switch { + case strings.Contains(responder.Type, "{{"): + _, err := template.New("").Parse(responder.Type) + if err != nil { + return fmt.Errorf("responders[%d].type is not a valid template: %w", idx, err) + } + case opsgenieTypeMatcher.MatchString(responder.Type): + default: + return fmt.Errorf("responders[%d].type=%q doesn't match requirements, want either template or %s", idx, responder.Type, opsgenieTypeMatcher.String()) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // OpsGenieConfigResponder defines a responder to an incident. // One of `id`, `name` or `username` has to be defined. type OpsGenieConfigResponder struct { @@ -933,6 +1116,24 @@ type PagerDutyConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *PagerDutyConfig) validate() error { + if c.URL != "" { + if _, err := url.Parse(c.URL); err != nil { + return fmt.Errorf("invalid url=%q: %w", c.URL, err) + } + } + if c.RoutingKey == nil && c.ServiceKey == nil { + return fmt.Errorf("one of 'routing_key' or 'service_key' must be configured") + } + if c.RoutingKey != nil && c.ServiceKey != nil { + return fmt.Errorf("at most one of 'routing_key' or 'service_key' must be configured") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // ImageConfig is used to attach images to the incident. // See https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTgx-send-an-alert-event#the-images-property // for more information. @@ -976,6 +1177,24 @@ type MSTeamsConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *MSTeamsConfig) validate() error { + if c.URL == nil && c.URLSecret == nil { + return fmt.Errorf("webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil && c.URLSecret != nil { + return fmt.Errorf("at most one of webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil { + if _, err := url.Parse(*c.URL); err != nil { + return fmt.Errorf("invalid webhook_url=%q", *c.URL) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + type DiscordConfig struct { // SendResolved controls notify about resolved alerts. // +optional @@ -1013,7 +1232,25 @@ type DiscordConfig struct { AvatarURL string `json:"avatar_url,omitempty" yaml:"avatar_url,omitempty"` } -type SnsConfig struct { +func (c *DiscordConfig) validate() error { + if c.URL == nil && c.URLSecret == nil { + return fmt.Errorf("webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil && c.URLSecret != nil { + return fmt.Errorf("at most one of webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil { + if _, err := url.Parse(*c.URL); err != nil { + return fmt.Errorf("invalid webhook_url=%q", *c.URL) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + +type SNSConfig struct { // SendResolved controls notify about resolved alerts. // +optional SendResolved *bool `json:"send_resolved,omitempty" yaml:"send_resolved,omitempty"` @@ -1046,6 +1283,16 @@ type SnsConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *SNSConfig) validate() error { + if c.TargetArn == "" && c.TopicArn == "" && c.PhoneNumber == "" { + return fmt.Errorf("one of target_arn, topic_arn or phone_number fields must be set") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + type Sigv4Config struct { // AWS region, if blank the region from the default credentials chain is used // +optional @@ -1086,6 +1333,24 @@ type WebexConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *WebexConfig) validate() error { + if c.URL != nil && *c.URL != "" { + if _, err := url.Parse(*c.URL); err != nil { + return fmt.Errorf("incorrect url=%q: %w", *c.URL, err) + } + } + if c.RoomId == "" { + return fmt.Errorf("missing required field 'room_id'") + } + if c.HTTPConfig == nil || c.HTTPConfig.Authorization == nil { + return fmt.Errorf("missing required http_config.authorization") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // JiraConfig represent alertmanager's jira_config entry // https://prometheus.io/docs/alerting/latest/configuration/#jira_config // available from v0.55.0 operator version @@ -1147,11 +1412,29 @@ type JiraConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } -// IncidentIOConfig configures notifications via incident.io. +func (c *JiraConfig) validate() error { + if c.APIURL != nil && *c.APIURL != "" { + if _, err := url.Parse(*c.APIURL); err != nil { + return fmt.Errorf("incorrect url=%q: %w", *c.APIURL, err) + } + } + if c.Project == "" { + return fmt.Errorf("missing required field 'project'") + } + if c.IssueType == "" { + return fmt.Errorf("missing required field 'issue_type'") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + +// IncidentioConfig configures notifications via incident.io. // https://prometheus.io/docs/alerting/latest/configuration/#incidentio_config // available from v0.66.0 operator version // and v0.29.0 alertmanager version -type IncidentIOConfig struct { +type IncidentioConfig struct { // SendResolved controls notify about resolved alerts. // +optional SendResolved *bool `json:"send_resolved,omitempty" yaml:"send_resolved,omitempty"` @@ -1173,6 +1456,18 @@ type IncidentIOConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *IncidentioConfig) validate() error { + if len(c.URL) != 0 { + if _, err := url.Parse(c.URL); err != nil { + return fmt.Errorf("incorrect url=%q: %w", c.URL, err) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // RocketchatConfig configures notifications via Rocketchat. // https://prometheus.io/docs/alerting/latest/configuration/#rocketchat_config // available from v0.55.0 operator version @@ -1224,6 +1519,18 @@ type RocketchatConfig struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *RocketchatConfig) validate() error { + if c.APIURL != nil && *c.APIURL != "" { + if _, err := url.Parse(*c.APIURL); err != nil { + return fmt.Errorf("incorrect url=%q: %w", *c.APIURL, err) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + // RocketchatAttachmentField defines API fields // https://developer.rocket.chat/reference/api/rest-api/endpoints/messaging/chat-endpoints/postmessage#attachment-field-objects type RocketchatAttachmentField struct { @@ -1280,6 +1587,111 @@ type MSTeamsV2Config struct { HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` } +func (c *MSTeamsV2Config) validate() error { + if c.URL == nil && c.URLSecret == nil { + return fmt.Errorf("webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil && c.URLSecret != nil { + return fmt.Errorf("at most one of webhook_url or webhook_url_secret must be configured") + } + if c.URL != nil { + if _, err := url.Parse(*c.URL); err != nil { + return fmt.Errorf("invalid webhook_url=%q", *c.URL) + } + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + +// MattermostConfig configures notifications via Mattermost. +type MattermostConfig struct { + // SendResolved controls notify about resolved alerts. + // +optional + SendResolved *bool `json:"send_resolved,omitempty" yaml:"send_resolved,omitempty"` + // Username overrides the username the message posts as + // +optional + Username string `json:"username,omitempty" yaml:"username,omitempty"` + // Channel overrides the channel the message posts in. + // +optional + Channel string `json:"channel,omitempty" yaml:"channel,omitempty"` + // Text defines markdown-formatted message to display in the post. + Text string `json:"text"` + // IconURL overrides the profile picture the message posts with. + // +optional + IconURL string `json:"icon_url,omitempty" yaml:"icon_url,omitempty"` + // IconEmoji overrides the profile picture and icon_url parameter. + // +optional + IconEmoji string `json:"icon_emoji,omitempty" yaml:"icon_emoji,omitempty"` + // URL to send requests to, + // one of `urlSecret` and `url` must be defined. + // +optional + URL *string `json:"url,omitempty"` + // URLSecret defines secret name and key at the CRD namespace. + // It must contain the Mattermost URL. + // one of `urlSecret` and `url` must be defined. + // +optional + URLSecret *corev1.SecretKeySelector `json:"url_secret,omitempty" yaml:"url_secret,omitempty"` + // Attachments defines richer formatting options + // +optional + Attachments []*MattermostAttachment `json:"attachments,omitempty" yaml:"attachments,omitempty"` + // +optional + Props *MattermostProps `json:"props,omitempty" yaml:"props,omitempty"` + // +optional + Priority *MattermostPriority `json:"priority,omitempty" yaml:"priority,omitempty"` + // +optional + // +kubebuilder:validation:Schemaless + // +kubebuilder:pruning:PreserveUnknownFields + HTTPConfig *HTTPConfig `json:"http_config,omitempty" yaml:"http_config,omitempty"` +} + +func (c *MattermostConfig) validate() error { + if c.URLSecret == nil && c.URL == nil { + return fmt.Errorf("url_secret or url must be configured") + } + if c.URLSecret != nil && c.URL != nil { + return fmt.Errorf("at most one of url_secret or url must be configured") + } + if err := c.HTTPConfig.validate(); err != nil { + return fmt.Errorf("incorrect http_config: %w", err) + } + return nil +} + +type MattermostAttachment struct { + Fallback string `json:"fallback,omitempty" yaml:"fallback,omitempty"` + Color string `json:"color,omitempty" yaml:"color,omitempty"` + Pretext string `json:"pretext,omitempty" yaml:"pretext,omitempty"` + Text string `json:"text,omitempty" yaml:"text,omitempty"` + AuthorName string `json:"author_name,omitempty" yaml:"author_name,omitempty"` + AuthorLink string `json:"author_link,omitempty" yaml:"author_link,omitempty"` + AuthorIcon string `json:"author_icon,omitempty" yaml:"author_icon,omitempty"` + Title string `json:"title,omitempty" yaml:"title,omitempty"` + TitleLink string `json:"title_link,omitempty" yaml:"title_link,omitempty"` + Fields []MattermostField `json:"fields,omitempty" yaml:"fields,omitempty"` + ThumbURL string `json:"thumb_url,omitempty" yaml:"thumb_url,omitempty"` + Footer string `json:"footer,omitempty" yaml:"footer,omitempty"` + FooterIcon string `json:"footer_icon,omitempty" yaml:"footer_icon,omitempty"` + ImageURL string `json:"image_url,omitempty" yaml:"image_url,omitempty"` +} + +type MattermostField struct { + Title string `json:"title,omitempty" yaml:"title,omitempty"` + Value string `json:"value,omitempty" yaml:"value,omitempty"` + Short bool `json:"short,omitempty" yaml:"short,omitempty"` +} + +type MattermostProps struct { + Card *string `json:"card,omitempty" yaml:"card,omitempty"` +} + +type MattermostPriority struct { + Priority string `json:"priority,omitempty" yaml:"priority,omitempty"` + RequestedAck *bool `json:"requested_ack,omitempty" yaml:"requested_ack,omitempty"` + PersistentNotifications *bool `json:"persistent_notifications,omitempty" yaml:"persistent_notifications,omitempty"` +} + // HTTPConfig defines a client HTTP configuration for VMAlertmanagerConfig objects // See https://prometheus.io/docs/alerting/latest/configuration/#http_config type HTTPConfig struct { @@ -1350,57 +1762,49 @@ type ProxyConfig struct { } // UnmarshalJSON implements json.Unmarshaller interface -func (hc *HTTPConfig) UnmarshalJSON(data []byte) error { +func (c *HTTPConfig) UnmarshalJSON(data []byte) error { decoder := json.NewDecoder(bytes.NewReader(data)) decoder.DisallowUnknownFields() - type phc HTTPConfig - if err := decoder.Decode((*phc)(hc)); err != nil { + type pc HTTPConfig + if err := decoder.Decode((*pc)(c)); err != nil { return err } return nil } -func (hc *HTTPConfig) validate() error { - if hc == nil { +func (c *HTTPConfig) validate() error { + if c == nil { return nil } - - if (hc.BasicAuth != nil || hc.OAuth2 != nil) && (hc.BearerTokenSecret != nil) { + if (c.BasicAuth != nil || c.OAuth2 != nil) && (c.BearerTokenSecret != nil) { return fmt.Errorf("at most one of basicAuth, oauth2, bearerTokenSecret must be configured") } - - if hc.Authorization != nil { - if hc.BearerTokenSecret != nil || len(hc.BearerTokenFile) > 0 { + if c.Authorization != nil { + if c.BearerTokenSecret != nil || len(c.BearerTokenFile) > 0 { return fmt.Errorf("authorization is not compatible with bearer_token_secret and Bearer_token_file") } - - if hc.BasicAuth != nil || hc.OAuth2 != nil { + if c.BasicAuth != nil || c.OAuth2 != nil { return fmt.Errorf("at most one of basicAuth, oauth2 & authorization must be configured") } - - if err := hc.Authorization.validate(); err != nil { + if err := c.Authorization.validate(); err != nil { return err } } - - if hc.OAuth2 != nil { - if hc.BasicAuth != nil { + if c.OAuth2 != nil { + if c.BasicAuth != nil { return fmt.Errorf("at most one of basicAuth, oauth2 & authorization must be configured") } - - if err := hc.OAuth2.validate(); err != nil { + if err := c.OAuth2.validate(); err != nil { return err } } - - if hc.TLSConfig != nil { - if err := hc.TLSConfig.Validate(); err != nil { + if c.TLSConfig != nil { + if err := c.TLSConfig.Validate(); err != nil { return err } } - return nil } @@ -1657,10 +2061,10 @@ func validateTimeIntervals(timeIntervals []TimeIntervals) (map[string]struct{}, for idx, ti := range timeIntervals { if err := validateTimeIntervalsEntry(&ti); err != nil { - return nil, fmt.Errorf("time interval at idx=%d is invalid: %w", idx, err) + return nil, fmt.Errorf("time_intervals[%d]: %w", idx, err) } if _, ok := timeIntervalNames[ti.Name]; ok { - return nil, fmt.Errorf("time interval at idx=%d is not unique with name=%q", idx, ti.Name) + return nil, fmt.Errorf("time_intervals[%d].name=%q is not unique", idx, ti.Name) } timeIntervalNames[ti.Name] = struct{}{} } @@ -1705,29 +2109,29 @@ func validateTimeIntervalsEntry(ti *TimeIntervals) error { } for i, ti := range ti.TimeIntervals { - for _, time := range ti.Times { + for j, time := range ti.Times { if err := validateTimeRangeForInterval(time); err != nil { - return fmt.Errorf("time range=%q at idx=%d is invalid: %w", time, i, err) + return fmt.Errorf("time_intervals[%d].times[%d]: %w", i, j, err) } } - for _, weekday := range ti.Weekdays { + for j, weekday := range ti.Weekdays { if err := validateWeekDays(weekday); err != nil { - return fmt.Errorf("weekday range=%q at idx=%d is invalid: %w", weekday, i, err) + return fmt.Errorf("time_intervals[%d].weekdays[%d]: %w", i, j, err) } } - for _, dom := range ti.DaysOfMonth { + for j, dom := range ti.DaysOfMonth { if err := validateDoM(dom); err != nil { - return fmt.Errorf("day of month range=%q at idx=%d is invalid: %w", dom, i, err) + return fmt.Errorf("time_intervals[%d].days_of_month[%d]: %w", i, j, err) } } - for _, month := range ti.Months { + for j, month := range ti.Months { if err := validateMonths(month); err != nil { - return fmt.Errorf("month range=%q at idx=%d is invalid: %w", month, i, err) + return fmt.Errorf("time_intervals[%d].months[%d]: %w", i, j, err) } } - for _, year := range ti.Years { + for j, year := range ti.Years { if err := validateYears(year); err != nil { - return fmt.Errorf("year range=%q at idx=%d is invalid: %w", year, i, err) + return fmt.Errorf("time_intervals[%d].years[%d]: %w", i, j, err) } } } @@ -1738,306 +2142,96 @@ func validateReceiver(recv Receiver) error { if recv.Name == "" { return fmt.Errorf("name field cannot be empty") } - - for idx, cfg := range recv.EmailConfigs { - if cfg.To == "" { - return fmt.Errorf("at idx=%d for email_configs required field `to` must be set", idx) - } - - if cfg.Smarthost != "" { - _, port, err := net.SplitHostPort(cfg.Smarthost) - if err != nil { - return err - } - if port == "" { - return fmt.Errorf("at idx=%d for email_configs smarthost=%q: port cannot be empty", idx, cfg.Smarthost) - } - } - - if len(cfg.Headers) > 0 { - normalizedHeaders := map[string]struct{}{} - for key := range cfg.Headers { - normalized := strings.ToLower(key) - if _, ok := normalizedHeaders[normalized]; ok { - return fmt.Errorf("at idx=%d for email_configs duplicate header %q", idx, normalized) - } - normalizedHeaders[normalized] = struct{}{} - } - } - if cfg.TLSConfig != nil { - if err := cfg.TLSConfig.Validate(); err != nil { - return fmt.Errorf("at idx=%d for email_configs invalid tls_config: %w", idx, err) - } + for i, c := range recv.EmailConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("email_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.PagerDutyConfigs { - if cfg.URL != "" { - if _, err := url.Parse(cfg.URL); err != nil { - return fmt.Errorf("at idx=%d pagerduty_configs invalid url=%q: %w", idx, cfg.URL, err) - } - } - if cfg.RoutingKey == nil && cfg.ServiceKey == nil { - return fmt.Errorf("at idx=%d pagerduty_configs one of 'routing_key' or 'service_key' must be configured", idx) - } - if cfg.RoutingKey != nil && cfg.ServiceKey != nil { - return fmt.Errorf("at idx=%d pagerduty_configs at most one of 'routing_key' or 'service_key' must be configured", idx) - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for pagerduty_configs incorrect http_config: %w", idx, err) + for i, c := range recv.PagerDutyConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("pagerduty_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.PushoverConfigs { - if cfg.UserKey == nil { - return fmt.Errorf("at idx=%d pushover_configs required field 'user_key' must be set", idx) - } - - if cfg.Token == nil { - return fmt.Errorf("at idx=%d pushover_configs required field 'token' must be set", idx) - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for pushover_configs incorrect http_config: %w", idx, err) + for i, c := range recv.PushoverConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("pushover_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.SlackConfigs { - for _, sa := range cfg.Actions { - if sa.Type == "" { - return fmt.Errorf("at idx=%d required field 'action.type' for slack actions must be set", idx) - } - if sa.Text == "" { - return fmt.Errorf("at idx=%d required field 'action.text' for slack actions must be set", idx) - } - - if sa.URL == "" && sa.Name == "" { - return fmt.Errorf("at idx=%d required field 'action.url' or 'action.name' for slack actions must be set", idx) - } - - if sa.ConfirmField != nil && sa.ConfirmField.Text == "" { - return fmt.Errorf("at idx=%d required field 'confirm_field.text' for slack actions must be set", idx) - } - - } - - for _, field := range cfg.Fields { - if field.Value == "" { - return fmt.Errorf("at idx=%d required field 'value' for slack fields must be set", idx) - } - if field.Title == "" { - return fmt.Errorf("at idx=%d required field 'title' for slack fields must be set", idx) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for slack_configs incorrect http_config: %w", idx, err) + for i, c := range recv.SlackConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("slack_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.OpsGenieConfigs { - for _, responder := range cfg.Responders { - if responder.ID == "" && responder.Name == "" && responder.Username == "" { - return fmt.Errorf("at idx=%d opsgenie responder must have at least an id, a name or an username defined", idx) - } - - switch { - case strings.Contains(responder.Type, "{{"): - _, err := template.New("").Parse(responder.Type) - if err != nil { - return fmt.Errorf("responder %v type is not a valid template: %w", responder, err) - } - case opsgenieTypeMatcher.MatchString(responder.Type): - default: - return fmt.Errorf("at idx=%d opsgenie_configs responder type=%q doesn't match requirements, want either template or %s", idx, responder.Type, opsgenieTypeMatcher.String()) - } - - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for opsgenie_configs incorrect http_config: %w", idx, err) + for i, c := range recv.OpsGenieConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("opsgenie_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.WebhookConfigs { - if cfg.URL == nil && cfg.URLSecret == nil { - return fmt.Errorf("at idx=%d of webhook_configs one of 'url' or 'url_secret' must be specified", idx) - } - if cfg.URL != nil && cfg.URLSecret != nil { - return fmt.Errorf("at idx=%d of webhook_configs at most one of 'url' or 'url_secret' must be specified", idx) - } - if cfg.URL != nil { - if _, err := url.Parse(*cfg.URL); err != nil { - return fmt.Errorf("invalid 'url': %w", err) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for webhook_configs incorrect http_config: %w", idx, err) + for i, c := range recv.WebhookConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("webhook_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.VictorOpsConfigs { - // from https://github.com/prometheus/alertmanager/blob/a7f9fdadbecbb7e692d2cd8d3334e3d6de1602e1/config/notifiers.go#L497 - reservedFields := map[string]struct{}{ - "routing_key": {}, - "message_type": {}, - "state_message": {}, - "entity_display_name": {}, - "monitoring_tool": {}, - "entity_id": {}, - "entity_state": {}, - } - - if len(cfg.CustomFields) > 0 { - for key := range cfg.CustomFields { - if _, ok := reservedFields[key]; ok { - return fmt.Errorf("at idx=%d of victorops_configs usage of reserved word %q in custom fields", idx, key) - } - } - } - if cfg.RoutingKey == "" { - return fmt.Errorf("at idx=%d of victorops_configs missing 'routing_key' key", idx) - } - - if cfg.APIURL != "" { - if _, err := url.Parse(cfg.APIURL); err != nil { - return fmt.Errorf("at idx=%d of victorops_configs incorrect api_url=%q: %w", idx, cfg.APIURL, err) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for victorops_configs incorrect http_config: %w", idx, err) + for i, c := range recv.VictorOpsConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("victorops_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.WeChatConfigs { - if cfg.APIURL != "" { - if _, err := url.Parse(cfg.APIURL); err != nil { - return fmt.Errorf("at idx=%d for wechat_configs incorrect api_url=%q: %w", idx, cfg.APIURL, err) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for wechat_configs incorrect http_config: %w", idx, err) + for i, c := range recv.WechatConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("wechat_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.TelegramConfigs { - if cfg.BotToken == nil { - return fmt.Errorf("at idx=%d for telegram_configs required field 'bot_token' must be set", idx) - } - if cfg.ChatID == 0 { - return fmt.Errorf("at idx=%d for telegram_configs required field 'chat_id' must be set", idx) - } - - if cfg.ParseMode != "" && - cfg.ParseMode != "Markdown" && - cfg.ParseMode != "MarkdownV2" && - cfg.ParseMode != "HTML" { - return fmt.Errorf("at idx=%d unknown parse_mode=%q on telegram_config, must be Markdown, MarkdownV2, HTML or empty string", idx, cfg.ParseMode) - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for telegram_configs incorrect http_config: %w", idx, err) + for i, c := range recv.TelegramConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("telegram_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.MSTeamsConfigs { - if cfg.URL == nil && cfg.URLSecret == nil { - return fmt.Errorf("at idx=%d for msteams_configs of webhook_url or webhook_url_secret must be configured", idx) - } - - if cfg.URL != nil && cfg.URLSecret != nil { - return fmt.Errorf("at idx=%d for msteams_configs at most one of webhook_url or webhook_url_secret must be configured", idx) - } - if cfg.URL != nil { - if _, err := url.Parse(*cfg.URL); err != nil { - return fmt.Errorf("at idx=%d for msteams_configs has invalid webhook_url=%q", idx, *cfg.URL) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for msteams_configs incorrect http_config: %w", idx, err) + for i, c := range recv.MattermostConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("mattermost_configs[%d]: %w", i, err) } } - for idx, cfg := range recv.DiscordConfigs { - if cfg.URL == nil && cfg.URLSecret == nil { - return fmt.Errorf("at idx=%d for discord_configs of webhook_url or webhook_url_secret must be configured", idx) - } - - if cfg.URL != nil && cfg.URLSecret != nil { - return fmt.Errorf("at idx=%d for discord_configs at most one of webhook_url or webhook_url_secret must be configured", idx) - } - if cfg.URL != nil { - if _, err := url.Parse(*cfg.URL); err != nil { - return fmt.Errorf("at idx=%d for discord_configs has invalid webhook_url=%q", idx, *cfg.URL) - } - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for discord_configs incorrect http_config: %w", idx, err) + for idx, c := range recv.MSTeamsConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("msteams_configs[%d]: %w", idx, err) } } - for idx, cfg := range recv.SNSConfigs { - if cfg.TargetArn == "" && cfg.TopicArn == "" && cfg.PhoneNumber == "" { - return fmt.Errorf("at idx=%d for sns_configs one of target_arn, topic_arn or phone_number fields must be set", idx) - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for sns_configs incorrect http_config: %w", idx, err) + for idx, c := range recv.DiscordConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("discord_configs[%d]: %w", idx, err) } } - for idx, cfg := range recv.WebexConfigs { - if cfg.URL != nil && *cfg.URL != "" { - if _, err := url.Parse(*cfg.URL); err != nil { - return fmt.Errorf("at idx=%d for webex_configs incorrect url=%q: %w", idx, *cfg.URL, err) - } - } - if cfg.RoomId == "" { - return fmt.Errorf("at idx=%d for webex_configs missing required field 'room_id'", idx) - } - if cfg.HTTPConfig == nil || cfg.HTTPConfig.Authorization == nil { - return fmt.Errorf("at idx=%d for webex_configs missing http_config.authorization configuration", idx) - } - if err := cfg.HTTPConfig.Authorization.validate(); err != nil { - return fmt.Errorf("at idx=%d for webex_configs incorrect http_config.authorization: %w", idx, err) - } - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for webex_configs incorrect http_config: %w", idx, err) + for idx, c := range recv.SNSConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("sns_configs[%d]: %w", idx, err) } } - - for idx, cfg := range recv.JiraConfigs { - if cfg.APIURL != nil && *cfg.APIURL != "" { - if _, err := url.Parse(*cfg.APIURL); err != nil { - return fmt.Errorf("at idx=%d for jira_configs incorrect url=%q: %w", idx, *cfg.APIURL, err) - } - } - if cfg.Project == "" { - return fmt.Errorf("at idx=%d for jira_configs missing required field 'project'", idx) - } - if cfg.IssueType == "" { - return fmt.Errorf("at idx=%d for jira_configs missing required field 'issue_type'", idx) + for idx, c := range recv.WebexConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("webex_configs[%d]: %w", idx, err) } } - - for idx, cfg := range recv.IncidentIOConfigs { - if len(cfg.URL) != 0 { - if _, err := url.Parse(cfg.URL); err != nil { - return fmt.Errorf("at idx=%d for incidentio_configs incorrect url=%q: %w", idx, cfg.URL, err) - } + for idx, c := range recv.JiraConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("jira_configs[%d]: %w", idx, err) } } - - for idx, cfg := range recv.RocketchatConfigs { - if cfg.APIURL != nil && *cfg.APIURL != "" { - if _, err := url.Parse(*cfg.APIURL); err != nil { - return fmt.Errorf("at idx=%d for rocketchat_configs incorrect url=%q: %w", idx, *cfg.APIURL, err) - } + for idx, c := range recv.IncidentioConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("incidentio_configs[%d]: %w", idx, err) } } - - for idx, cfg := range recv.MSTeamsV2Configs { - if cfg.URL == nil && cfg.URLSecret == nil { - return fmt.Errorf("at idx=%d for msteamsv2_configs of webhook_url or webhook_url_secret must be configured", idx) - } - - if cfg.URL != nil && cfg.URLSecret != nil { - return fmt.Errorf("at idx=%d for msteamsv2_configs at most one of webhook_url or webhook_url_secret must be configured", idx) - } - if cfg.URL != nil { - if _, err := url.Parse(*cfg.URL); err != nil { - return fmt.Errorf("at idx=%d for msteamsv2_configs has invalid webhook_url=%q", idx, *cfg.URL) - } + for idx, c := range recv.RocketchatConfigs { + if err := c.validate(); err != nil { + return fmt.Errorf("rocketchat_configs[%d]: %w", idx, err) } - - if err := cfg.HTTPConfig.validate(); err != nil { - return fmt.Errorf("at idx=%d for msteamsv2_configs incorrect http_config: %w", idx, err) + } + for idx, c := range recv.MSTeamsV2Configs { + if err := c.validate(); err != nil { + return fmt.Errorf("msteamsv2_configs[%d]: %w", idx, err) } } - return nil } diff --git a/api/operator/v1beta1/vmalertmanagerconfig_types_test.go b/api/operator/v1beta1/vmalertmanagerconfig_types_test.go index 75062f3eb..9275c90ee 100644 --- a/api/operator/v1beta1/vmalertmanagerconfig_types_test.go +++ b/api/operator/v1beta1/vmalertmanagerconfig_types_test.go @@ -290,7 +290,7 @@ func TestValidateVMAlertmanagerConfigFail(t *testing.T) { "receiver": "jira" } } -}`, `receiver at idx=0 is invalid: at idx=0 for jira_configs missing required field 'issue_type'`) +}`, `receivers[0]: jira_configs[0]: missing required field 'issue_type'`) f(`{ "apiVersion": "v1", @@ -327,7 +327,7 @@ func TestValidateVMAlertmanagerConfigFail(t *testing.T) { "receiver": "teams" } } -}`, `receiver at idx=0 is invalid: at idx=0 for msteamsv2_configs at most one of webhook_url or webhook_url_secret must be configured`) +}`, `receivers[0]: msteamsv2_configs[0]: at most one of webhook_url or webhook_url_secret must be configured`) f(`{ "apiVersion": "v1", @@ -359,7 +359,7 @@ func TestValidateVMAlertmanagerConfigFail(t *testing.T) { "receiver": "teams" } } -}`, `receiver at idx=0 is invalid: at idx=0 for msteamsv2_configs of webhook_url or webhook_url_secret must be configured`) +}`, `receivers[0]: msteamsv2_configs[0]: webhook_url or webhook_url_secret must be configured`) f(`{ "apiVersion": "v1", diff --git a/api/operator/v1beta1/vmextra_types.go b/api/operator/v1beta1/vmextra_types.go index 3fff10bbe..a7313d967 100644 --- a/api/operator/v1beta1/vmextra_types.go +++ b/api/operator/v1beta1/vmextra_types.go @@ -1040,7 +1040,7 @@ type TLSServerConfig struct { // PreferServerCipherSuites controls whether the server selects the // client's most preferred ciphersuite // +optional - PreferServerCipherSuites bool `json:"prefer_server_cipher_suites,omitempty"` + PreferServerCipherSuites *bool `json:"prefer_server_cipher_suites,omitempty"` // Certs defines cert, CA and key for TLS auth Certs `json:",inline"` } diff --git a/api/operator/v1beta1/zz_generated.deepcopy.go b/api/operator/v1beta1/zz_generated.deepcopy.go index 24674bf07..2cd083540 100644 --- a/api/operator/v1beta1/zz_generated.deepcopy.go +++ b/api/operator/v1beta1/zz_generated.deepcopy.go @@ -1809,7 +1809,7 @@ func (in *ImageConfig) DeepCopy() *ImageConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IncidentIOConfig) DeepCopyInto(out *IncidentIOConfig) { +func (in *IncidentioConfig) DeepCopyInto(out *IncidentioConfig) { *out = *in if in.SendResolved != nil { in, out := &in.SendResolved, &out.SendResolved @@ -1828,12 +1828,12 @@ func (in *IncidentIOConfig) DeepCopyInto(out *IncidentIOConfig) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IncidentIOConfig. -func (in *IncidentIOConfig) DeepCopy() *IncidentIOConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IncidentioConfig. +func (in *IncidentioConfig) DeepCopy() *IncidentioConfig { if in == nil { return nil } - out := new(IncidentIOConfig) + out := new(IncidentioConfig) in.DeepCopyInto(out) return out } @@ -2137,6 +2137,142 @@ func (in *ManagedObjectsMetadata) DeepCopy() *ManagedObjectsMetadata { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MattermostAttachment) DeepCopyInto(out *MattermostAttachment) { + *out = *in + if in.Fields != nil { + in, out := &in.Fields, &out.Fields + *out = make([]MattermostField, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MattermostAttachment. +func (in *MattermostAttachment) DeepCopy() *MattermostAttachment { + if in == nil { + return nil + } + out := new(MattermostAttachment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MattermostConfig) DeepCopyInto(out *MattermostConfig) { + *out = *in + if in.SendResolved != nil { + in, out := &in.SendResolved, &out.SendResolved + *out = new(bool) + **out = **in + } + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(string) + **out = **in + } + if in.URLSecret != nil { + in, out := &in.URLSecret, &out.URLSecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.Attachments != nil { + in, out := &in.Attachments, &out.Attachments + *out = make([]*MattermostAttachment, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(MattermostAttachment) + (*in).DeepCopyInto(*out) + } + } + } + if in.Props != nil { + in, out := &in.Props, &out.Props + *out = new(MattermostProps) + (*in).DeepCopyInto(*out) + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(MattermostPriority) + (*in).DeepCopyInto(*out) + } + if in.HTTPConfig != nil { + in, out := &in.HTTPConfig, &out.HTTPConfig + *out = new(HTTPConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MattermostConfig. +func (in *MattermostConfig) DeepCopy() *MattermostConfig { + if in == nil { + return nil + } + out := new(MattermostConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MattermostField) DeepCopyInto(out *MattermostField) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MattermostField. +func (in *MattermostField) DeepCopy() *MattermostField { + if in == nil { + return nil + } + out := new(MattermostField) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MattermostPriority) DeepCopyInto(out *MattermostPriority) { + *out = *in + if in.RequestedAck != nil { + in, out := &in.RequestedAck, &out.RequestedAck + *out = new(bool) + **out = **in + } + if in.PersistentNotifications != nil { + in, out := &in.PersistentNotifications, &out.PersistentNotifications + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MattermostPriority. +func (in *MattermostPriority) DeepCopy() *MattermostPriority { + if in == nil { + return nil + } + out := new(MattermostPriority) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MattermostProps) DeepCopyInto(out *MattermostProps) { + *out = *in + if in.Card != nil { + in, out := &in.Card, &out.Card + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MattermostProps. +func (in *MattermostProps) DeepCopy() *MattermostProps { + if in == nil { + return nil + } + out := new(MattermostProps) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NamespaceDiscovery) DeepCopyInto(out *NamespaceDiscovery) { *out = *in @@ -2728,6 +2864,13 @@ func (in *Receiver) DeepCopyInto(out *Receiver) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.MattermostConfigs != nil { + in, out := &in.MattermostConfigs, &out.MattermostConfigs + *out = make([]MattermostConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.VictorOpsConfigs != nil { in, out := &in.VictorOpsConfigs, &out.VictorOpsConfigs *out = make([]VictorOpsConfig, len(*in)) @@ -2735,9 +2878,9 @@ func (in *Receiver) DeepCopyInto(out *Receiver) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.WeChatConfigs != nil { - in, out := &in.WeChatConfigs, &out.WeChatConfigs - *out = make([]WeChatConfig, len(*in)) + if in.WechatConfigs != nil { + in, out := &in.WechatConfigs, &out.WechatConfigs + *out = make([]WechatConfig, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -2765,7 +2908,7 @@ func (in *Receiver) DeepCopyInto(out *Receiver) { } if in.SNSConfigs != nil { in, out := &in.SNSConfigs, &out.SNSConfigs - *out = make([]SnsConfig, len(*in)) + *out = make([]SNSConfig, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -2784,9 +2927,9 @@ func (in *Receiver) DeepCopyInto(out *Receiver) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.IncidentIOConfigs != nil { - in, out := &in.IncidentIOConfigs, &out.IncidentIOConfigs - *out = make([]IncidentIOConfig, len(*in)) + if in.IncidentioConfigs != nil { + in, out := &in.IncidentioConfigs, &out.IncidentioConfigs + *out = make([]IncidentioConfig, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -3108,6 +3251,43 @@ func (in *RuleGroup) DeepCopy() *RuleGroup { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SNSConfig) DeepCopyInto(out *SNSConfig) { + *out = *in + if in.SendResolved != nil { + in, out := &in.SendResolved, &out.SendResolved + *out = new(bool) + **out = **in + } + if in.Sigv4 != nil { + in, out := &in.Sigv4, &out.Sigv4 + *out = new(Sigv4Config) + (*in).DeepCopyInto(*out) + } + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.HTTPConfig != nil { + in, out := &in.HTTPConfig, &out.HTTPConfig + *out = new(HTTPConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SNSConfig. +func (in *SNSConfig) DeepCopy() *SNSConfig { + if in == nil { + return nil + } + out := new(SNSConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ScrapeClass) DeepCopyInto(out *ScrapeClass) { *out = *in @@ -3350,43 +3530,6 @@ func (in *SlackField) DeepCopy() *SlackField { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SnsConfig) DeepCopyInto(out *SnsConfig) { - *out = *in - if in.SendResolved != nil { - in, out := &in.SendResolved, &out.SendResolved - *out = new(bool) - **out = **in - } - if in.Sigv4 != nil { - in, out := &in.Sigv4, &out.Sigv4 - *out = new(Sigv4Config) - (*in).DeepCopyInto(*out) - } - if in.Attributes != nil { - in, out := &in.Attributes, &out.Attributes - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.HTTPConfig != nil { - in, out := &in.HTTPConfig, &out.HTTPConfig - *out = new(HTTPConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SnsConfig. -func (in *SnsConfig) DeepCopy() *SnsConfig { - if in == nil { - return nil - } - out := new(SnsConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StatefulSetUpdateStrategyBehavior) DeepCopyInto(out *StatefulSetUpdateStrategyBehavior) { *out = *in @@ -3755,6 +3898,11 @@ func (in *TLSServerConfig) DeepCopyInto(out *TLSServerConfig) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.PreferServerCipherSuites != nil { + in, out := &in.PreferServerCipherSuites, &out.PreferServerCipherSuites + *out = new(bool) + **out = **in + } in.Certs.DeepCopyInto(&out.Certs) } @@ -5155,8 +5303,8 @@ func (in *VMAlertmanagerTracingConfig) DeepCopyInto(out *VMAlertmanagerTracingCo *out = new(TLSClientConfig) (*in).DeepCopyInto(*out) } - if in.HTTPHeaders != nil { - in, out := &in.HTTPHeaders, &out.HTTPHeaders + if in.Headers != nil { + in, out := &in.Headers, &out.Headers *out = make(map[string]string, len(*in)) for key, val := range *in { (*out)[key] = val @@ -7424,17 +7572,17 @@ func (in *VultrSDConfig) DeepCopy() *VultrSDConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WeChatConfig) DeepCopyInto(out *WeChatConfig) { +func (in *WebexConfig) DeepCopyInto(out *WebexConfig) { *out = *in if in.SendResolved != nil { in, out := &in.SendResolved, &out.SendResolved *out = new(bool) **out = **in } - if in.APISecret != nil { - in, out := &in.APISecret, &out.APISecret - *out = new(v1.SecretKeySelector) - (*in).DeepCopyInto(*out) + if in.URL != nil { + in, out := &in.URL, &out.URL + *out = new(string) + **out = **in } if in.HTTPConfig != nil { in, out := &in.HTTPConfig, &out.HTTPConfig @@ -7443,18 +7591,18 @@ func (in *WeChatConfig) DeepCopyInto(out *WeChatConfig) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WeChatConfig. -func (in *WeChatConfig) DeepCopy() *WeChatConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebexConfig. +func (in *WebexConfig) DeepCopy() *WebexConfig { if in == nil { return nil } - out := new(WeChatConfig) + out := new(WebexConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WebexConfig) DeepCopyInto(out *WebexConfig) { +func (in *WebhookConfig) DeepCopyInto(out *WebhookConfig) { *out = *in if in.SendResolved != nil { in, out := &in.SendResolved, &out.SendResolved @@ -7466,6 +7614,11 @@ func (in *WebexConfig) DeepCopyInto(out *WebexConfig) { *out = new(string) **out = **in } + if in.URLSecret != nil { + in, out := &in.URLSecret, &out.URLSecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } if in.HTTPConfig != nil { in, out := &in.HTTPConfig, &out.HTTPConfig *out = new(HTTPConfig) @@ -7473,31 +7626,26 @@ func (in *WebexConfig) DeepCopyInto(out *WebexConfig) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebexConfig. -func (in *WebexConfig) DeepCopy() *WebexConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfig. +func (in *WebhookConfig) DeepCopy() *WebhookConfig { if in == nil { return nil } - out := new(WebexConfig) + out := new(WebhookConfig) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WebhookConfig) DeepCopyInto(out *WebhookConfig) { +func (in *WechatConfig) DeepCopyInto(out *WechatConfig) { *out = *in if in.SendResolved != nil { in, out := &in.SendResolved, &out.SendResolved *out = new(bool) **out = **in } - if in.URL != nil { - in, out := &in.URL, &out.URL - *out = new(string) - **out = **in - } - if in.URLSecret != nil { - in, out := &in.URLSecret, &out.URLSecret + if in.APISecret != nil { + in, out := &in.APISecret, &out.APISecret *out = new(v1.SecretKeySelector) (*in).DeepCopyInto(*out) } @@ -7508,12 +7656,12 @@ func (in *WebhookConfig) DeepCopyInto(out *WebhookConfig) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebhookConfig. -func (in *WebhookConfig) DeepCopy() *WebhookConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WechatConfig. +func (in *WechatConfig) DeepCopy() *WechatConfig { if in == nil { return nil } - out := new(WebhookConfig) + out := new(WechatConfig) in.DeepCopyInto(out) return out } diff --git a/config/crd/overlay/crd.descriptionless.yaml b/config/crd/overlay/crd.descriptionless.yaml index d9d50eaa6..ad9a32d9e 100644 --- a/config/crd/overlay/crd.descriptionless.yaml +++ b/config/crd/overlay/crd.descriptionless.yaml @@ -7625,6 +7625,98 @@ spec: - project type: object type: array + mattermost_configs: + items: + properties: + attachments: + items: + properties: + author_icon: + type: string + author_link: + type: string + author_name: + type: string + color: + type: string + fallback: + type: string + fields: + items: + properties: + short: + type: boolean + title: + type: string + value: + type: string + type: object + type: array + footer: + type: string + footer_icon: + type: string + image_url: + type: string + pretext: + type: string + text: + type: string + thumb_url: + type: string + title: + type: string + title_link: + type: string + type: object + type: array + channel: + type: string + http_config: + x-kubernetes-preserve-unknown-fields: true + icon_emoji: + type: string + icon_url: + type: string + priority: + properties: + persistent_notifications: + type: boolean + priority: + type: string + requested_ack: + type: boolean + type: object + props: + properties: + card: + type: string + type: object + send_resolved: + type: boolean + text: + type: string + url: + type: string + url_secret: + properties: + key: + type: string + name: + default: "" + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + type: string + required: + - text + type: object + type: array msteams_configs: items: properties: @@ -10712,7 +10804,7 @@ spec: type: string endpoint: type: string - http_headers: + headers: additionalProperties: type: string type: object diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml index e618da0f8..d573903c0 100644 --- a/config/crd/overlay/crd.yaml +++ b/config/crd/overlay/crd.yaml @@ -14956,7 +14956,7 @@ spec: incidentio_configs: items: description: |- - IncidentIOConfig configures notifications via incident.io. + IncidentioConfig configures notifications via incident.io. https://prometheus.io/docs/alerting/latest/configuration/#incidentio_config available from v0.66.0 operator version and v0.29.0 alertmanager version @@ -15084,6 +15084,132 @@ spec: - project type: object type: array + mattermost_configs: + description: MattermostConfigs defines Mattermost notification + configurations. + items: + description: MattermostConfig configures notifications via + Mattermost. + properties: + attachments: + description: Attachments defines richer formatting options + items: + properties: + author_icon: + type: string + author_link: + type: string + author_name: + type: string + color: + type: string + fallback: + type: string + fields: + items: + properties: + short: + type: boolean + title: + type: string + value: + type: string + type: object + type: array + footer: + type: string + footer_icon: + type: string + image_url: + type: string + pretext: + type: string + text: + type: string + thumb_url: + type: string + title: + type: string + title_link: + type: string + type: object + type: array + channel: + description: Channel overrides the channel the message + posts in. + type: string + http_config: + x-kubernetes-preserve-unknown-fields: true + icon_emoji: + description: IconEmoji overrides the profile picture and + icon_url parameter. + type: string + icon_url: + description: IconURL overrides the profile picture the + message posts with. + type: string + priority: + properties: + persistent_notifications: + type: boolean + priority: + type: string + requested_ack: + type: boolean + type: object + props: + properties: + card: + type: string + type: object + send_resolved: + description: SendResolved controls notify about resolved + alerts. + type: boolean + text: + description: Text defines markdown-formatted message to + display in the post. + type: string + url: + description: |- + URL to send requests to, + one of `urlSecret` and `url` must be defined. + type: string + url_secret: + description: |- + URLSecret defines secret name and key at the CRD namespace. + It must contain the Mattermost URL. + one of `urlSecret` and `url` must be defined. + 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. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + 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 + username: + description: Username overrides the username the message + posts as + type: string + required: + - text + type: object + type: array msteams_configs: items: properties: @@ -18000,10 +18126,10 @@ spec: type: object type: array wechat_configs: - description: WeChatConfigs defines wechat notification configurations. + description: WechatConfigs defines wechat notification configurations. items: description: |- - WeChatConfig configures notifications via WeChat. + WechatConfig configures notifications via Wechat. See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config properties: agent_id: @@ -20960,10 +21086,10 @@ spec: description: Endpoint defines tracing URL where traces will be sent type: string - http_headers: + headers: additionalProperties: type: string - description: HTTPHeaders defines custom HTTP headers for tracing + description: Headers defines custom HTTP headers for tracing type: object insecure: description: Insecure allows TLS configuration to be omitted diff --git a/docs/api.md b/docs/api.md index 982090dbd..70af564c9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2039,7 +2039,7 @@ Appears in: [VMAlertDatasourceSpec](#vmalertdatasourcespec), [VMAlertNotifierSpe HTTPConfig defines a client HTTP configuration for VMAlertmanagerConfig objects See https://prometheus.io/docs/alerting/latest/configuration/#http_config -Appears in: [DiscordConfig](#discordconfig), [IncidentIOConfig](#incidentioconfig), [JiraConfig](#jiraconfig), [MSTeamsConfig](#msteamsconfig), [MSTeamsV2Config](#msteamsv2config), [OpsGenieConfig](#opsgenieconfig), [PagerDutyConfig](#pagerdutyconfig), [PushoverConfig](#pushoverconfig), [RocketchatConfig](#rocketchatconfig), [SlackConfig](#slackconfig), [SnsConfig](#snsconfig), [TelegramConfig](#telegramconfig), [VictorOpsConfig](#victoropsconfig), [WeChatConfig](#wechatconfig), [WebexConfig](#webexconfig), [WebhookConfig](#webhookconfig) +Appears in: [DiscordConfig](#discordconfig), [IncidentioConfig](#incidentioconfig), [JiraConfig](#jiraconfig), [MSTeamsConfig](#msteamsconfig), [MSTeamsV2Config](#msteamsv2config), [MattermostConfig](#mattermostconfig), [OpsGenieConfig](#opsgenieconfig), [PagerDutyConfig](#pagerdutyconfig), [PushoverConfig](#pushoverconfig), [RocketchatConfig](#rocketchatconfig), [SNSConfig](#snsconfig), [SlackConfig](#slackconfig), [TelegramConfig](#telegramconfig), [VictorOpsConfig](#victoropsconfig), [WebexConfig](#webexconfig), [WebhookConfig](#webhookconfig), [WechatConfig](#wechatconfig) | Field | Description | | --- | --- | @@ -2135,9 +2135,9 @@ Appears in: [PagerDutyConfig](#pagerdutyconfig) | href#
_string_ | _(Optional)_
| | source#
_string_ | _(Required)_
| -#### IncidentIOConfig +#### IncidentioConfig -IncidentIOConfig configures notifications via incident.io. +IncidentioConfig configures notifications via incident.io. https://prometheus.io/docs/alerting/latest/configuration/#incidentio_config available from v0.66.0 operator version and v0.29.0 alertmanager version @@ -2328,6 +2328,76 @@ Appears in: [VLAgentSpec](#vlagentspec), [VLClusterSpec](#vlclusterspec), [VLSin | annotations#
_object (keys:string, values:string)_ | _(Required)_
Annotations is an unstructured key value map stored with a resource that may be
set by external tools to store and retrieve arbitrary metadata. They are not
queryable and should be preserved when modifying objects.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations | | labels#
_object (keys:string, values:string)_ | _(Required)_
Labels Map of string keys and values that can be used to organize and categorize
(scope and select) objects.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels | +#### MattermostAttachment + +Appears in: [MattermostConfig](#mattermostconfig) + +| Field | Description | +| --- | --- | +| author_icon#
_string_ | _(Required)_
| +| author_link#
_string_ | _(Required)_
| +| author_name#
_string_ | _(Required)_
| +| color#
_string_ | _(Required)_
| +| fallback#
_string_ | _(Required)_
| +| fields#
_[MattermostField](#mattermostfield) array_ | _(Required)_
| +| footer#
_string_ | _(Required)_
| +| footer_icon#
_string_ | _(Required)_
| +| image_url#
_string_ | _(Required)_
| +| pretext#
_string_ | _(Required)_
| +| text#
_string_ | _(Required)_
| +| thumb_url#
_string_ | _(Required)_
| +| title#
_string_ | _(Required)_
| +| title_link#
_string_ | _(Required)_
| + +#### MattermostConfig + +MattermostConfig configures notifications via Mattermost. + +Appears in: [Receiver](#receiver) + +| Field | Description | +| --- | --- | +| attachments#
_[MattermostAttachment](#mattermostattachment) array_ | _(Optional)_
Attachments defines richer formatting options | +| channel#
_string_ | _(Optional)_
Channel overrides the channel the message posts in. | +| http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
| +| icon_emoji#
_string_ | _(Optional)_
IconEmoji overrides the profile picture and icon_url parameter. | +| icon_url#
_string_ | _(Optional)_
IconURL overrides the profile picture the message posts with. | +| priority#
_[MattermostPriority](#mattermostpriority)_ | _(Optional)_
| +| props#
_[MattermostProps](#mattermostprops)_ | _(Optional)_
| +| send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | +| text#
_string_ | _(Required)_
Text defines markdown-formatted message to display in the post. | +| url#
_string_ | _(Optional)_
URL to send requests to,
one of `urlSecret` and `url` must be defined. | +| url_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
URLSecret defines secret name and key at the CRD namespace.
It must contain the Mattermost URL.
one of `urlSecret` and `url` must be defined. | +| username#
_string_ | _(Optional)_
Username overrides the username the message posts as | + +#### MattermostField + +Appears in: [MattermostAttachment](#mattermostattachment) + +| Field | Description | +| --- | --- | +| short#
_boolean_ | _(Required)_
| +| title#
_string_ | _(Required)_
| +| value#
_string_ | _(Required)_
| + +#### MattermostPriority + +Appears in: [MattermostConfig](#mattermostconfig) + +| Field | Description | +| --- | --- | +| persistent_notifications#
_boolean_ | _(Required)_
| +| priority#
_string_ | _(Required)_
| +| requested_ack#
_boolean_ | _(Required)_
| + +#### MattermostProps + +Appears in: [MattermostConfig](#mattermostconfig) + +| Field | Description | +| --- | --- | +| card#
_string_ | _(Required)_
| + #### NamespaceDiscovery NamespaceDiscovery is the configuration for discovering @@ -2644,8 +2714,9 @@ Appears in: [VMAlertmanagerConfigSpec](#vmalertmanagerconfigspec) | --- | --- | | discord_configs#
_[DiscordConfig](#discordconfig) array_ | _(Optional)_
| | email_configs#
_[EmailConfig](#emailconfig) array_ | _(Optional)_
EmailConfigs defines email notification configurations. | -| incidentio_configs#
_[IncidentIOConfig](#incidentioconfig) array_ | _(Optional)_
| +| incidentio_configs#
_[IncidentioConfig](#incidentioconfig) array_ | _(Optional)_
| | jira_configs#
_[JiraConfig](#jiraconfig) array_ | _(Optional)_
| +| mattermost_configs#
_[MattermostConfig](#mattermostconfig) array_ | _(Optional)_
MattermostConfigs defines Mattermost notification configurations. | | msteams_configs#
_[MSTeamsConfig](#msteamsconfig) array_ | _(Optional)_
| | msteamsv2_configs#
_[MSTeamsV2Config](#msteamsv2config) array_ | _(Optional)_
| | name#
_string_ | _(Required)_
Name of the receiver. Must be unique across all items from the list. | @@ -2654,12 +2725,12 @@ Appears in: [VMAlertmanagerConfigSpec](#vmalertmanagerconfigspec) | pushover_configs#
_[PushoverConfig](#pushoverconfig) array_ | _(Optional)_
PushoverConfigs defines push over notification configurations. | | rocketchat_configs#
_[RocketchatConfig](#rocketchatconfig) array_ | _(Optional)_
| | slack_configs#
_[SlackConfig](#slackconfig) array_ | _(Optional)_
SlackConfigs defines slack notification configurations. | -| sns_configs#
_[SnsConfig](#snsconfig) array_ | _(Optional)_
| +| sns_configs#
_[SNSConfig](#snsconfig) array_ | _(Optional)_
| | telegram_configs#
_[TelegramConfig](#telegramconfig) array_ | _(Optional)_
| | victorops_configs#
_[VictorOpsConfig](#victoropsconfig) array_ | _(Optional)_
VictorOpsConfigs defines victor ops notification configurations. | | webex_configs#
_[WebexConfig](#webexconfig) array_ | _(Optional)_
| | webhook_configs#
_[WebhookConfig](#webhookconfig) array_ | _(Optional)_
WebhookConfigs defines webhook notification configurations. | -| wechat_configs#
_[WeChatConfig](#wechatconfig) array_ | _(Optional)_
WeChatConfigs defines wechat notification configurations. | +| wechat_configs#
_[WechatConfig](#wechatconfig) array_ | _(Optional)_
WechatConfigs defines wechat notification configurations. | #### RelabelConfig @@ -2800,6 +2871,23 @@ Appears in: [VMRuleSpec](#vmrulespec) | tenant#
_string_ | _(Optional)_
Tenant id for group, can be used only with enterprise version of vmalert.
See more details [here](https://docs.victoriametrics.com/victoriametrics/vmalert/#multitenancy). | | type#
_string_ | _(Optional)_
Type defines datasource type for enterprise version of vmalert
possible values - prometheus,graphite,vlogs | +#### SNSConfig + +Appears in: [Receiver](#receiver) + +| Field | Description | +| --- | --- | +| api_url#
_string_ | _(Optional)_
The api URL | +| attributes#
_object (keys:string, values:string)_ | _(Optional)_
SNS message attributes | +| http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
HTTP client configuration. | +| message#
_string_ | _(Optional)_
The message content of the SNS notification. | +| phone_number#
_string_ | _(Required)_
Phone number if message is delivered via SMS
Specify this, topic_arn or target_arn | +| send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | +| sigv4#
_[Sigv4Config](#sigv4config)_ | _(Required)_
Configure the AWS Signature Verification 4 signing process | +| subject#
_string_ | _(Optional)_
The subject line if message is delivered to an email endpoint. | +| target_arn#
_string_ | _(Optional)_
Mobile platform endpoint ARN if message is delivered via mobile notifications
Specify this, topic_arn or phone_number | +| topic_arn#
_string_ | _(Optional)_
SNS topic ARN, either specify this, phone_number or target_arn | + #### ScrapeClass Appears in: [CommonScrapeParams](#commonscrapeparams), [VMAgentSpec](#vmagentspec), [VMSingleSpec](#vmsinglespec) @@ -2838,7 +2926,7 @@ Appears in: [CommonAppsParams](#commonappsparams), [VLAgentSpec](#vlagentspec), #### Sigv4Config -Appears in: [SnsConfig](#snsconfig) +Appears in: [SNSConfig](#snsconfig) | Field | Description | | --- | --- | @@ -2931,23 +3019,6 @@ Appears in: [SlackConfig](#slackconfig) | title#
_string_ | _(Required)_
| | value#
_string_ | _(Required)_
| -#### SnsConfig - -Appears in: [Receiver](#receiver) - -| Field | Description | -| --- | --- | -| api_url#
_string_ | _(Optional)_
The api URL | -| attributes#
_object (keys:string, values:string)_ | _(Optional)_
SNS message attributes | -| http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
HTTP client configuration. | -| message#
_string_ | _(Optional)_
The message content of the SNS notification. | -| phone_number#
_string_ | _(Required)_
Phone number if message is delivered via SMS
Specify this, topic_arn or target_arn | -| send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | -| sigv4#
_[Sigv4Config](#sigv4config)_ | _(Required)_
Configure the AWS Signature Verification 4 signing process | -| subject#
_string_ | _(Optional)_
The subject line if message is delivered to an email endpoint. | -| target_arn#
_string_ | _(Optional)_
Mobile platform endpoint ARN if message is delivered via mobile notifications
Specify this, topic_arn or phone_number | -| topic_arn#
_string_ | _(Optional)_
SNS topic ARN, either specify this, phone_number or target_arn | - #### StatefulSetUpdateStrategyBehavior StatefulSetUpdateStrategyBehavior customizes behavior for StatefulSet updates. @@ -3816,7 +3887,7 @@ Appears in: [VMAlertmanagerSpec](#vmalertmanagerspec) | client_type#
_string_ | _(Optional)_
ClientType defines tracing client protocol | | compression#
_string_ | _(Optional)_
Compression defines compression algorithm for tracing | | endpoint#
_string_ | _(Required)_
Endpoint defines tracing URL where traces will be sent | -| http_headers#
_object (keys:string, values:string)_ | _(Optional)_
HTTPHeaders defines custom HTTP headers for tracing | +| headers#
_object (keys:string, values:string)_ | _(Optional)_
Headers defines custom HTTP headers for tracing | | insecure#
_boolean_ | _(Optional)_
Insecure allows TLS configuration to be omitted | | sampling_fraction#
_string_ | _(Optional)_
SamplingFraction defines fraction of the requests that should be sampled | | timeout#
_string_ | _(Optional)_
Timeout defines tracing connection timeout | @@ -4909,27 +4980,6 @@ Appears in: [VMScrapeConfigSpec](#vmscrapeconfigspec) | region#
_string_ | _(Optional)_
Region is an optional query arguments to filter instances by region id. | | tlsConfig#
_[TLSConfig](#tlsconfig)_ | _(Optional)_
TLS configuration to use on every scrape request | -#### WeChatConfig - -WeChatConfig configures notifications via WeChat. -See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config - -Appears in: [Receiver](#receiver) - -| Field | Description | -| --- | --- | -| agent_id#
_string_ | _(Optional)_
| -| api_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
The secret's key that contains the WeChat API key.
The secret needs to be in the same namespace as the AlertmanagerConfig
fallback to global alertmanager setting if empty | -| api_url#
_string_ | _(Optional)_
The WeChat API URL.
fallback to global alertmanager setting if empty | -| corp_id#
_string_ | _(Optional)_
The corp id for authentication.
fallback to global alertmanager setting if empty | -| http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
HTTP client configuration. | -| message#
_string_ | _(Required)_
API request data as defined by the WeChat API. | -| message_type#
_string_ | _(Optional)_
| -| send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | -| to_party#
_string_ | _(Optional)_
| -| to_tag#
_string_ | _(Optional)_
| -| to_user#
_string_ | _(Optional)_
| - #### WebexConfig Appears in: [Receiver](#receiver) @@ -4956,4 +5006,25 @@ Appears in: [Receiver](#receiver) | send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | | timeout#
_string_ | _(Optional)_
Timeout is the maximum time allowed to invoke the webhook
available since v0.28.0 alertmanager version | | url#
_string_ | _(Optional)_
URL to send requests to,
one of `urlSecret` and `url` must be defined. | -| url_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
URLSecret defines secret name and key at the CRD namespace.
It must contain the webhook URL.
one of `urlSecret` and `url` must be defined. | \ No newline at end of file +| url_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
URLSecret defines secret name and key at the CRD namespace.
It must contain the webhook URL.
one of `urlSecret` and `url` must be defined. | + +#### WechatConfig + +WechatConfig configures notifications via Wechat. +See https://prometheus.io/docs/alerting/latest/configuration/#wechat_config + +Appears in: [Receiver](#receiver) + +| Field | Description | +| --- | --- | +| agent_id#
_string_ | _(Optional)_
| +| api_secret#
_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#secretkeyselector-v1-core)_ | _(Optional)_
The secret's key that contains the WeChat API key.
The secret needs to be in the same namespace as the AlertmanagerConfig
fallback to global alertmanager setting if empty | +| api_url#
_string_ | _(Optional)_
The WeChat API URL.
fallback to global alertmanager setting if empty | +| corp_id#
_string_ | _(Optional)_
The corp id for authentication.
fallback to global alertmanager setting if empty | +| http_config#
_[HTTPConfig](#httpconfig)_ | _(Optional)_
HTTP client configuration. | +| message#
_string_ | _(Required)_
API request data as defined by the WeChat API. | +| message_type#
_string_ | _(Optional)_
| +| send_resolved#
_boolean_ | _(Optional)_
SendResolved controls notify about resolved alerts. | +| to_party#
_string_ | _(Optional)_
| +| to_tag#
_string_ | _(Optional)_
| +| to_user#
_string_ | _(Optional)_
| \ No newline at end of file diff --git a/internal/controller/operator/factory/converter/v1alpha1/apis.go b/internal/controller/operator/factory/converter/v1alpha1/apis.go index 3b4b40ec8..0e0fc7777 100644 --- a/internal/controller/operator/factory/converter/v1alpha1/apis.go +++ b/internal/controller/operator/factory/converter/v1alpha1/apis.go @@ -227,11 +227,11 @@ func convertReceivers(promReceivers []promv1alpha1.Receiver) []vmv1beta1.Receive OpsGenieConfigs: make([]vmv1beta1.OpsGenieConfig, 0, len(promR.OpsGenieConfigs)), WebhookConfigs: make([]vmv1beta1.WebhookConfig, 0, len(promR.WebhookConfigs)), VictorOpsConfigs: make([]vmv1beta1.VictorOpsConfig, 0, len(promR.VictorOpsConfigs)), - WeChatConfigs: make([]vmv1beta1.WeChatConfig, 0, len(promR.WeChatConfigs)), + WechatConfigs: make([]vmv1beta1.WechatConfig, 0, len(promR.WeChatConfigs)), TelegramConfigs: make([]vmv1beta1.TelegramConfig, 0, len(promR.TelegramConfigs)), MSTeamsConfigs: make([]vmv1beta1.MSTeamsConfig, 0, len(promR.MSTeamsConfigs)), DiscordConfigs: make([]vmv1beta1.DiscordConfig, 0, len(promR.DiscordConfigs)), - SNSConfigs: make([]vmv1beta1.SnsConfig, 0, len(promR.SNSConfigs)), + SNSConfigs: make([]vmv1beta1.SNSConfig, 0, len(promR.SNSConfigs)), WebexConfigs: make([]vmv1beta1.WebexConfig, 0, len(promR.WebexConfigs)), MSTeamsV2Configs: make([]vmv1beta1.MSTeamsV2Config, 0, len(promR.MSTeamsV2Configs)), } @@ -411,7 +411,7 @@ func convertReceivers(promReceivers []promv1alpha1.Receiver) []vmv1beta1.Receive dst.VictorOpsConfigs = append(dst.VictorOpsConfigs, vo) } for _, obj := range promR.WeChatConfigs { - vo := vmv1beta1.WeChatConfig{ + vo := vmv1beta1.WechatConfig{ SendResolved: obj.SendResolved, HTTPConfig: convertHTTPConfig(obj.HTTPConfig), APISecret: obj.APISecret, @@ -424,7 +424,7 @@ func convertReceivers(promReceivers []promv1alpha1.Receiver) []vmv1beta1.Receive Message: ptr.Deref(obj.Message, ""), MessageType: ptr.Deref(obj.MessageType, ""), } - dst.WeChatConfigs = append(dst.WeChatConfigs, vo) + dst.WechatConfigs = append(dst.WechatConfigs, vo) } for _, obj := range promR.TelegramConfigs { vo := vmv1beta1.TelegramConfig{ @@ -468,7 +468,7 @@ func convertReceivers(promReceivers []promv1alpha1.Receiver) []vmv1beta1.Receive dst.DiscordConfigs = append(dst.DiscordConfigs, vo) } for _, obj := range promR.SNSConfigs { - vo := vmv1beta1.SnsConfig{ + vo := vmv1beta1.SNSConfig{ SendResolved: obj.SendResolved, HTTPConfig: convertHTTPConfig(obj.HTTPConfig), URL: ptr.Deref(obj.ApiURL, ""), @@ -519,7 +519,6 @@ func convertReceivers(promReceivers []promv1alpha1.Receiver) []vmv1beta1.Receive } dst.MSTeamsV2Configs = append(dst.MSTeamsV2Configs, vo) } - vmReceivers = append(vmReceivers, dst) } diff --git a/internal/controller/operator/factory/vmalertmanager/config.go b/internal/controller/operator/factory/vmalertmanager/config.go index bb158c358..31f840bc0 100644 --- a/internal/controller/operator/factory/vmalertmanager/config.go +++ b/internal/controller/operator/factory/vmalertmanager/config.go @@ -13,58 +13,122 @@ import ( "github.com/VictoriaMetrics/operator/internal/controller/operator/factory/build" ) +type extraFields map[string]any + +func (f *extraFields) MarshalYAML() (any, error) { + if f == nil { + return nil, nil + } + vs := *f + dstKeys := make([]string, 0, len(vs)) + for key := range vs { + dstKeys = append(dstKeys, key) + } + slices.Sort(dstKeys) + var result yaml.MapSlice + for _, key := range dstKeys { + result = append(result, yaml.MapItem{Key: key, Value: vs[key]}) + } + return result, nil +} + +// contains only global configuration param for config validation +type globalConfig struct { + SMTPFrom string `yaml:"smtp_from,omitempty"` + SMTPSmarthost string `yaml:"smtp_smarthost,omitempty"` + SlackAPIURL string `yaml:"slack_api_url,omitempty"` + SlackAPIURLFile string `yaml:"slack_api_url_file,omitempty"` + OpsGenieAPIKey string `yaml:"opsgenie_api_key,omitempty"` + OpsGenieAPIKeyFile string `yaml:"opsgenie_api_key_file,omitempty"` + WechatAPISecret string `yaml:"wechat_api_secret,omitempty"` + WechatAPICorpID string `yaml:"wechat_api_corp_id,omitempty"` + VictorOpsAPIKey string `yaml:"victorops_api_key,omitempty"` + VictorOpsAPIKeyFile string `yaml:"victorops_api_key_file,omitempty"` + JiraAPIURL string `yaml:"jira_api_url,omitempty"` + RocketchatAPIURL string `yaml:"rocketchat_api_url,omitempty"` + RocketchatToken string `yaml:"rocketchat_token,omitempty"` + RocketchatTokenFile string `yaml:"rocketchat_token_file,omitempty"` + RocketchatTokenID string `yaml:"rocketchat_token_id,omitempty"` + RocketchatTokenIDFile string `yaml:"rocketchat_token_id_file,omitempty"` + XXX extraFields `yaml:",inline"` +} + +type amConfig struct { + Global *globalConfig `yaml:"global,omitempty"` + Route *route `yaml:"route,omitempty"` + InhibitRules []yaml.MapSlice `yaml:"inhibit_rules,omitempty"` + Receivers []receiver `yaml:"receivers,omitempty"` + TimeIntervals []yaml.MapSlice `yaml:"time_intervals,omitempty"` + Templates []string `yaml:"templates"` + TracingConfig yaml.MapSlice `yaml:"tracing,omitempty"` +} + +type receiver struct { + Name string `yaml:"name"` + SNSConfigs []yaml.MapSlice `yaml:"sns_configs,omitempty"` + WebexConfigs []yaml.MapSlice `yaml:"webex_configs,omitempty"` + JiraConfigs []yaml.MapSlice `yaml:"jira_configs,omitempty"` + RocketchatConfigs []yaml.MapSlice `yaml:"rocketchat_configs,omitempty"` + IncidentioConfigs []yaml.MapSlice `yaml:"incidentio_configs,omitempty"` + MSTeamsV2Configs []yaml.MapSlice `yaml:"msteamsv2_configs,omitempty"` + VictorOpsConfigs []yaml.MapSlice `yaml:"victorops_configs,omitempty"` + WechatConfigs []yaml.MapSlice `yaml:"wechat_configs,omitempty"` + WebhookConfigs []yaml.MapSlice `yaml:"webhook_configs,omitempty"` + TelegramConfigs []yaml.MapSlice `yaml:"telegram_configs,omitempty"` + MSTeamsConfigs []yaml.MapSlice `yaml:"msteams_configs,omitempty"` + DiscordConfigs []yaml.MapSlice `yaml:"discord_configs,omitempty"` + OpsGenieConfigs []yaml.MapSlice `yaml:"opsgenie_configs,omitempty"` + EmailConfigs []yaml.MapSlice `yaml:"email_configs,omitempty"` + SlackConfigs []yaml.MapSlice `yaml:"slack_configs,omitempty"` + PagerDutyConfigs []yaml.MapSlice `yaml:"pagerduty_configs,omitempty"` + PushoverConfigs []yaml.MapSlice `yaml:"pushover_configs,omitempty"` + MattermostConfigs []yaml.MapSlice `yaml:"mattermost_configs,omitempty"` +} + +type route struct { + Receiver string `yaml:"receiver,omitempty"` + GroupByStr []string `yaml:"group_by,omitempty"` + Match map[string]string `yaml:"match,omitempty"` + MatchRE map[string]string `yaml:"match_re,omitempty"` + Continue bool `yaml:"continue,omitempty"` + Routes []yaml.MapSlice `yaml:"routes,omitempty"` + GroupWait string `yaml:"group_wait,omitempty"` + GroupInterval string `yaml:"group_interval,omitempty"` + RepeatInterval string `yaml:"repeat_interval,omitempty"` + MuteTimeIntervals []string `yaml:"mute_time_intervals,omitempty"` + ActiveTimeIntervals []string `yaml:"active_time_intervals,omitempty"` +} + type parsedObjects struct { configs *build.ChildObjects[*vmv1beta1.VMAlertmanagerConfig] } -func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []byte, ac *build.AssetsCache) ([]byte, error) { +func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, data []byte, ac *build.AssetsCache) ([]byte, error) { if len(pos.configs.All()) == 0 && cr.Spec.TracingConfig == nil { - return baseCfg, nil + return data, nil } - var baseYAMLCfg alertmanagerConfig - if err := yaml.Unmarshal(baseCfg, &baseYAMLCfg); err != nil { + var baseCfg amConfig + if err := yaml.Unmarshal(data, &baseCfg); err != nil { return nil, fmt.Errorf("cannot parse base cfg: %w", err) } - if baseYAMLCfg.Route == nil { - baseYAMLCfg.Route = &route{ + if baseCfg.Route == nil { + baseCfg.Route = &route{ Receiver: "blackhole", } - var isBlackholeDefined bool - for _, recv := range baseYAMLCfg.Receivers { - var recvName string - for _, entry := range recv { - if entry.Key == "name" { - s, ok := entry.Value.(string) - if !ok { - return nil, fmt.Errorf("incorrect base configuration=%q, expected receiver name=%v to be a string", string(baseCfg), entry.Value) - } - recvName = s - break - } - } - if recvName == "blackhole" { - isBlackholeDefined = true - break - } - } + hasBlackhole := slices.ContainsFunc(baseCfg.Receivers, func(r receiver) bool { + return r.Name == "blackhole" + }) // conditionally add blackhole as default route path // alertmanager config must have some default route - if !isBlackholeDefined { - baseYAMLCfg.Receivers = append(baseYAMLCfg.Receivers, yaml.MapSlice{ - { - Key: "name", - Value: "blackhole", - }, + if !hasBlackhole { + baseCfg.Receivers = append(baseCfg.Receivers, receiver{ + Name: "blackhole", }) } } if len(pos.configs.All()) > 0 { - var globalConfigOpts globalAlertmanagerConfig - if err := yaml.Unmarshal(baseCfg, &globalConfigOpts); err != nil { - return nil, fmt.Errorf("cannot parse global config options: %w", err) - } var subRoutes []yaml.MapSlice var timeIntervals []yaml.MapSlice pos.configs.ForEachCollectSkipInvalid(func(cfg *vmv1beta1.VMAlertmanagerConfig) error { @@ -78,15 +142,15 @@ func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []by return err } } - var receiverCfgs []yaml.MapSlice - for _, receiver := range cfg.Spec.Receivers { - receiverCfg, err := buildReceiver(cfg, receiver, &globalConfigOpts, ac) - if err != nil { - return err + var receiverCfgs []receiver + for _, r := range cfg.Spec.Receivers { + result := receiver{ + Name: buildCRPrefixedName(cfg, r.Name), } - if len(receiverCfg) > 0 { - receiverCfgs = append(receiverCfgs, receiverCfg) + if err := buildReceiver(&result, cfg, r, baseCfg.Global, ac); err != nil { + return err } + receiverCfgs = append(receiverCfgs, result) } mtis, err := buildGlobalTimeIntervals(cfg) if err != nil { @@ -99,9 +163,9 @@ func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []by } subRoutes = append(subRoutes, route) } - baseYAMLCfg.Receivers = append(baseYAMLCfg.Receivers, receiverCfgs...) + baseCfg.Receivers = append(baseCfg.Receivers, receiverCfgs...) for _, rule := range cfg.Spec.InhibitRules { - baseYAMLCfg.InhibitRules = append(baseYAMLCfg.InhibitRules, buildInhibitRule(cfg.Namespace, rule, !cr.Spec.DisableNamespaceMatcher)) + baseCfg.InhibitRules = append(baseCfg.InhibitRules, buildInhibitRule(cfg.Namespace, rule, !cr.Spec.DisableNamespaceMatcher)) } if len(mtis) > 0 { timeIntervals = append(timeIntervals, mtis...) @@ -109,20 +173,27 @@ func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []by return nil }) if len(subRoutes) > 0 { - baseYAMLCfg.Route.Routes = append(baseYAMLCfg.Route.Routes, subRoutes...) + baseCfg.Route.Routes = append(baseCfg.Route.Routes, subRoutes...) } if len(timeIntervals) > 0 { - baseYAMLCfg.TimeIntervals = append(baseYAMLCfg.TimeIntervals, timeIntervals...) + baseCfg.TimeIntervals = append(baseCfg.TimeIntervals, timeIntervals...) } } + if len(cr.Spec.Templates) > 0 { + templatePaths := make([]string, 0, len(cr.Spec.Templates)) + for _, template := range cr.Spec.Templates { + templatePaths = append(templatePaths, path.Join(templatesDir, template.Name, template.Key)) + } + addConfigTemplates(&baseCfg, templatePaths) + } if cr.Spec.TracingConfig != nil { tracingCfg, err := buildTracingConfig(cr, ac) if err != nil { return nil, err } - baseYAMLCfg.TracingConfig = tracingCfg + baseCfg.TracingConfig = tracingCfg } - data, err := yaml.Marshal(baseYAMLCfg) + data, err := yaml.Marshal(baseCfg) if err != nil { return nil, err } @@ -130,16 +201,12 @@ func (pos *parsedObjects) buildConfig(cr *vmv1beta1.VMAlertmanager, baseCfg []by } // addConfigTemplates adds external templates to the given based configuration -func addConfigTemplates(baseCfg []byte, templates []string) ([]byte, error) { +func addConfigTemplates(baseCfg *amConfig, templates []string) { if len(templates) == 0 { - return baseCfg, nil - } - var baseYAMLCfg alertmanagerConfig - if err := yaml.Unmarshal(baseCfg, &baseYAMLCfg); err != nil { - return nil, fmt.Errorf("cannot parse base cfg: %w", err) + return } templatesSetByIdx := make(map[string]int) - for idx, v := range baseYAMLCfg.Templates { + for idx, v := range baseCfg.Templates { templatesSetByIdx[v] = idx } for _, v := range templates { @@ -151,13 +218,63 @@ func addConfigTemplates(baseCfg []byte, templates []string) ([]byte, error) { } // override value with correct path if idx, ok := templatesSetByIdx[path.Base(v)]; ok { - baseYAMLCfg.Templates[idx] = v + baseCfg.Templates[idx] = v continue } - baseYAMLCfg.Templates = append(baseYAMLCfg.Templates, v) - templatesSetByIdx[v] = len(baseYAMLCfg.Templates) - 1 + baseCfg.Templates = append(baseCfg.Templates, v) + templatesSetByIdx[v] = len(baseCfg.Templates) - 1 } - return yaml.Marshal(baseYAMLCfg) +} + +type rawValue struct { + items yaml.MapSlice +} + +func (r *rawValue) set(k string, v any) { + switch item := v.(type) { + case []string: + if len(item) > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case string: + if len(item) > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case []yaml.MapSlice: + if len(item) > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case int: + if item > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case int32: + if item > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case int64: + if item > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case float64: + if item > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case bool: + if item { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + case map[string]string: + if len(item) > 0 { + r.items = append(r.items, yaml.MapItem{Key: k, Value: item}) + } + default: + r.items = append(r.items, yaml.MapItem{Key: k, Value: v}) + } +} + +func (r *rawValue) reset() { + r.items = yaml.MapSlice{} } func buildGlobalTimeIntervals(cr *vmv1beta1.VMAlertmanagerConfig) ([]yaml.MapSlice, error) { @@ -173,34 +290,24 @@ func buildGlobalTimeIntervals(cr *vmv1beta1.VMAlertmanagerConfig) ([]yaml.MapSli continue } var temp []yaml.MapSlice - var tiItem yaml.MapSlice - toYaml := func(key string, src []string) { - if len(src) > 0 { - tiItem = append(tiItem, yaml.MapItem{Key: key, Value: src}) - } - } + var tiItem rawValue for _, ti := range mti.TimeIntervals { - tiItem = yaml.MapSlice{} - toYaml("days_of_month", ti.DaysOfMonth) - toYaml("weekdays", ti.Weekdays) - toYaml("months", ti.Months) - toYaml("years", ti.Years) - if len(ti.Location) > 0 { - tiItem = append(tiItem, yaml.MapItem{Key: "location", Value: ti.Location}) - } - + tiItem.set("days_of_month", ti.DaysOfMonth) + tiItem.set("weekdays", ti.Weekdays) + tiItem.set("months", ti.Months) + tiItem.set("years", ti.Years) + tiItem.set("location", ti.Location) var trss []yaml.MapSlice for _, trs := range ti.Times { if trs.EndTime != "" && trs.StartTime != "" { trss = append(trss, yaml.MapSlice{{Key: "start_time", Value: trs.StartTime}, {Key: "end_time", Value: trs.EndTime}}) } } - if len(trss) > 0 { - tiItem = append(tiItem, yaml.MapItem{Key: "times", Value: trss}) - } - if len(tiItem) > 0 { - temp = append(temp, tiItem) + tiItem.set("times", trss) + if len(tiItem.items) > 0 { + temp = append(temp, tiItem.items) } + tiItem.reset() } if len(temp) > 0 { r = append(r, yaml.MapSlice{{Key: "name", Value: buildCRPrefixedName(cr, mti.Name)}, {Key: "time_intervals", Value: temp}}) @@ -210,7 +317,7 @@ func buildGlobalTimeIntervals(cr *vmv1beta1.VMAlertmanagerConfig) ([]yaml.MapSli } func buildRoute(cr *vmv1beta1.VMAlertmanagerConfig, cfgRoute *vmv1beta1.Route, topLevel bool, alertmanagerCR *vmv1beta1.VMAlertmanager) (yaml.MapSlice, error) { - var r yaml.MapSlice + var r rawValue matchers := cfgRoute.Matchers // enforce continue when route is first-level and vmalertmanager disableRouteContinueEnforce filed is not set, // otherwise, always inherit from VMAlertmanagerConfig @@ -237,1131 +344,919 @@ func buildRoute(cr *vmv1beta1.VMAlertmanagerConfig, cfgRoute *vmv1beta1.Route, t tmpRoute := vmv1beta1.Route(*nestedRoute) route, err := buildRoute(cr, &tmpRoute, false, alertmanagerCR) if err != nil { - return r, err + return r.items, err } nestedRoutes = append(nestedRoutes, route) } - if len(nestedRoutes) > 0 { - r = append(r, yaml.MapItem{Key: "routes", Value: nestedRoutes}) - } - toYaml := func(key string, src []string) { - if len(src) > 0 { - r = append(r, yaml.MapItem{Key: key, Value: src}) - } - } - toYamlString := func(key string, src string) { - if len(src) > 0 { - r = append(r, yaml.MapItem{Key: key, Value: src}) - } - } - toYamlTimeIntervals := func(key string, src []string) { - if len(src) > 0 { - tis := make([]string, 0, len(src)) - for _, ti := range src { - tis = append(tis, buildCRPrefixedName(cr, ti)) - } - r = append(r, yaml.MapItem{Key: key, Value: tis}) - } - } - - toYaml("matchers", matchers) - toYaml("group_by", cfgRoute.GroupBy) - toYamlTimeIntervals("active_time_intervals", cfgRoute.ActiveTimeIntervals) - toYamlTimeIntervals("mute_time_intervals", cfgRoute.MuteTimeIntervals) - - toYamlString("group_interval", cfgRoute.GroupInterval) - toYamlString("group_wait", cfgRoute.GroupWait) - toYamlString("repeat_interval", cfgRoute.RepeatInterval) - if len(cfgRoute.Receiver) > 0 { - r = append(r, yaml.MapItem{Key: "receiver", Value: buildCRPrefixedName(cr, cfgRoute.Receiver)}) - } - r = append(r, yaml.MapItem{Key: "continue", Value: continueSetting}) - return r, nil + addPrefix := func(items []string) []string { + vs := make([]string, len(items)) + for i := range items { + vs[i] = buildCRPrefixedName(cr, items[i]) + } + return vs + } + r.set("routes", nestedRoutes) + r.set("matchers", matchers) + r.set("group_by", cfgRoute.GroupBy) + r.set("active_time_intervals", addPrefix(cfgRoute.ActiveTimeIntervals)) + r.set("mute_time_intervals", addPrefix(cfgRoute.MuteTimeIntervals)) + r.set("group_interval", cfgRoute.GroupInterval) + r.set("group_wait", cfgRoute.GroupWait) + r.set("repeat_interval", cfgRoute.RepeatInterval) + r.set("receiver", buildCRPrefixedName(cr, cfgRoute.Receiver)) + r.set("continue", continueSetting) + return r.items, nil } -func buildInhibitRule(namespace string, rule vmv1beta1.InhibitRule, mustAddNamespaceMatcher bool) yaml.MapSlice { - var r yaml.MapSlice +func buildInhibitRule(ns string, rule vmv1beta1.InhibitRule, mustAddNamespaceMatcher bool) yaml.MapSlice { + var r rawValue if mustAddNamespaceMatcher { - namespaceMatch := fmt.Sprintf("namespace = %q", namespace) + namespaceMatch := fmt.Sprintf("namespace = %q", ns) rule.SourceMatchers = append(rule.SourceMatchers, namespaceMatch) rule.TargetMatchers = append(rule.TargetMatchers, namespaceMatch) } - toYaml := func(key string, src []string) { - if len(src) > 0 { - r = append(r, yaml.MapItem{ - Key: key, - Value: src, - }) - } - } - toYaml("target_matchers", rule.TargetMatchers) - toYaml("source_matchers", rule.SourceMatchers) - toYaml("equal", rule.Equal) - return r + r.set("target_matchers", rule.TargetMatchers) + r.set("source_matchers", rule.SourceMatchers) + r.set("equal", rule.Equal) + return r.items } func buildCRPrefixedName(cr *vmv1beta1.VMAlertmanagerConfig, name string) string { return fmt.Sprintf("%s-%s-%s", cr.Namespace, cr.Name, name) } -// contains only global configuration param for config validation -type globalAlertmanagerConfig struct { - Global struct { - SMTPFrom string `yaml:"smtp_from,omitempty" json:"smtp_from,omitempty"` - SMTPSmarthost string `yaml:"smtp_smarthost,omitempty" json:"smtp_smarthost,omitempty"` - SlackAPIURL string `yaml:"slack_api_url,omitempty" json:"slack_api_url,omitempty"` - SlackAPIURLFile string `yaml:"slack_api_url_file,omitempty" json:"slack_api_url_file,omitempty"` - OpsGenieAPIKey string `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"` - OpsGenieAPIKeyFile string `yaml:"opsgenie_api_key_file,omitempty" json:"opsgenie_api_key_file,omitempty"` - WeChatAPISecret string `yaml:"wechat_api_secret,omitempty" json:"wechat_api_secret,omitempty"` - WeChatAPICorpID string `yaml:"wechat_api_corp_id,omitempty" json:"wechat_api_corp_id,omitempty"` - VictorOpsAPIKey string `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"` - VictorOpsAPIKeyFile string `yaml:"victorops_api_key_file,omitempty" json:"victorops_api_key_file,omitempty"` - JiraAPIURL string `yaml:"jira_api_url,omitempty" json:"jira_api_url,omitempty"` - RocketchatAPIURL string `yaml:"rocketchat_api_url,omitempty" json:"rocketchat_api_url,omitempty"` - RocketchatToken string `yaml:"rocketchat_token,omitempty" json:"rocketchat_token,omitempty"` - RocketchatTokenFile string `yaml:"rocketchat_token_file,omitempty" json:"rocketchat_token_file,omitempty"` - RocketchatTokenID string `yaml:"rocketchat_token_id,omitempty" json:"rocketchat_token_id,omitempty"` - RocketchatTokenIDFile string `yaml:"rocketchat_token_id_file,omitempty" json:"rocketchat_token_id_file,omitempty"` - } `yaml:"global,omitempty"` -} - -type alertmanagerConfig struct { - Global any `yaml:"global,omitempty" json:"global,omitempty"` - Route *route `yaml:"route,omitempty" json:"route,omitempty"` - InhibitRules []yaml.MapSlice `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"` - Receivers []yaml.MapSlice `yaml:"receivers,omitempty" json:"receivers,omitempty"` - TimeIntervals []yaml.MapSlice `yaml:"time_intervals,omitempty" json:"time_intervals"` - Templates []string `yaml:"templates" json:"templates"` - TracingConfig yaml.MapSlice `yaml:"tracing,omitempty" json:"tracing,omitempty"` -} - -type route struct { - Receiver string `yaml:"receiver,omitempty" json:"receiver,omitempty"` - GroupByStr []string `yaml:"group_by,omitempty" json:"group_by,omitempty"` - Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"` - MatchRE map[string]string `yaml:"match_re,omitempty" json:"match_re,omitempty"` - Continue bool `yaml:"continue,omitempty" json:"continue,omitempty"` - Routes []yaml.MapSlice `yaml:"routes,omitempty" json:"routes,omitempty"` - GroupWait string `yaml:"group_wait,omitempty" json:"group_wait,omitempty"` - GroupInterval string `yaml:"group_interval,omitempty" json:"group_interval,omitempty"` - RepeatInterval string `yaml:"repeat_interval,omitempty" json:"repeat_interval,omitempty"` - MuteTimeIntervals []string `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"` - ActiveTimeIntervals []string `yaml:"active_time_intervals,omitempty" json:"active_time_intervals,omitempty"` -} - func buildReceiver( + result *receiver, cr *vmv1beta1.VMAlertmanagerConfig, - receiver vmv1beta1.Receiver, - globalCfg *globalAlertmanagerConfig, + r vmv1beta1.Receiver, + gc *globalConfig, ac *build.AssetsCache, -) (yaml.MapSlice, error) { - cb := initConfigBuilder(cr, receiver.Name, globalCfg, ac) - cb.result = yaml.MapSlice{ - { - Key: "name", - Value: buildCRPrefixedName(cr, receiver.Name), - }, - } - if err := cb.buildCfg(receiver); err != nil { - return nil, err +) error { + for _, c := range r.OpsGenieConfigs { + o, err := buildOpsGenie(gc, c, cr.Namespace, ac) + if err != nil { + return err + } + result.OpsGenieConfigs = append(result.OpsGenieConfigs, o) } - return cb.result, nil -} - -type configBuilder struct { - cache *build.AssetsCache - namespace string - globalConfig *globalAlertmanagerConfig - currentYaml []yaml.MapSlice - result yaml.MapSlice -} - -func initConfigBuilder( - cr *vmv1beta1.VMAlertmanagerConfig, - receiver string, - globalCfg *globalAlertmanagerConfig, - ac *build.AssetsCache, -) *configBuilder { - cb := configBuilder{ - cache: ac, - namespace: cr.Namespace, - globalConfig: globalCfg, - result: yaml.MapSlice{ - { - Key: "name", - Value: buildCRPrefixedName(cr, receiver), - }, - }, - } - - return &cb -} - -func (cb *configBuilder) buildCfg(receiver vmv1beta1.Receiver) error { - for _, opsGenCfg := range receiver.OpsGenieConfigs { - if err := cb.buildOpsGenie(opsGenCfg); err != nil { + for _, c := range r.EmailConfigs { + o, err := buildEmail(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.EmailConfigs = append(result.EmailConfigs, o) } - cb.finalizeSection("opsgenie_configs") - - for _, emailCfg := range receiver.EmailConfigs { - if err := cb.buildEmail(emailCfg); err != nil { + for _, c := range r.SlackConfigs { + o, err := buildSlack(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.SlackConfigs = append(result.SlackConfigs, o) } - cb.finalizeSection("email_configs") - - for _, slackCfg := range receiver.SlackConfigs { - if err := cb.buildSlack(slackCfg); err != nil { + for _, c := range r.PagerDutyConfigs { + o, err := buildPagerDuty(c, cr.Namespace, ac) + if err != nil { return err } + result.PagerDutyConfigs = append(result.PagerDutyConfigs, o) } - cb.finalizeSection("slack_configs") - - for _, pgCfg := range receiver.PagerDutyConfigs { - if err := cb.buildPagerDuty(pgCfg); err != nil { + for _, c := range r.PushoverConfigs { + o, err := buildPushover(c, cr.Namespace, ac) + if err != nil { return err } + result.PushoverConfigs = append(result.PushoverConfigs, o) } - cb.finalizeSection("pagerduty_configs") - - for _, poCfg := range receiver.PushoverConfigs { - if err := cb.buildPushOver(poCfg); err != nil { + for _, c := range r.VictorOpsConfigs { + o, err := buildVictorOps(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.VictorOpsConfigs = append(result.VictorOpsConfigs, o) } - cb.finalizeSection("pushover_configs") - - for _, voCfg := range receiver.VictorOpsConfigs { - if err := cb.buildVictorOps(voCfg); err != nil { + for _, c := range r.WechatConfigs { + o, err := buildWechat(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.WechatConfigs = append(result.WechatConfigs, o) } - cb.finalizeSection("victorops_configs") - - for _, wcCfg := range receiver.WeChatConfigs { - if err := cb.buildWeeChat(wcCfg); err != nil { + for _, c := range r.MattermostConfigs { + o, err := buildMattermost(c, cr.Namespace, ac) + if err != nil { return err } + result.MattermostConfigs = append(result.MattermostConfigs, o) } - cb.finalizeSection("wechat_configs") - - for _, whCfg := range receiver.WebhookConfigs { - if err := cb.buildWebhook(whCfg); err != nil { + for _, c := range r.WebhookConfigs { + o, err := buildWebhook(c, cr.Namespace, ac) + if err != nil { return err } + result.WebhookConfigs = append(result.WebhookConfigs, o) } - cb.finalizeSection("webhook_configs") - - for _, tgCfg := range receiver.TelegramConfigs { - if err := cb.buildTelegram(tgCfg); err != nil { + for _, c := range r.TelegramConfigs { + o, err := buildTelegram(c, cr.Namespace, ac) + if err != nil { return err } + result.TelegramConfigs = append(result.TelegramConfigs, o) } - cb.finalizeSection("telegram_configs") - - for _, mcCfg := range receiver.MSTeamsConfigs { - if err := cb.buildTeams(mcCfg); err != nil { + for _, c := range r.MSTeamsConfigs { + o, err := buildMSTeams(c, cr.Namespace, ac) + if err != nil { return err } + result.MSTeamsConfigs = append(result.MSTeamsConfigs, o) } - cb.finalizeSection("msteams_configs") - - for _, mcCfg := range receiver.DiscordConfigs { - if err := cb.buildDiscord(mcCfg); err != nil { + for _, c := range r.DiscordConfigs { + o, err := buildDiscord(c, cr.Namespace, ac) + if err != nil { return err } + result.DiscordConfigs = append(result.DiscordConfigs, o) } - cb.finalizeSection("discord_configs") - - for _, snsCfg := range receiver.SNSConfigs { - if err := cb.buildSNS(snsCfg); err != nil { + for _, c := range r.SNSConfigs { + o, err := buildSNS(c, cr.Namespace, ac) + if err != nil { return err } + result.SNSConfigs = append(result.SNSConfigs, o) } - cb.finalizeSection("sns_configs") - - for _, webexCfg := range receiver.WebexConfigs { - if err := cb.buildWebex(webexCfg); err != nil { + for _, c := range r.WebexConfigs { + o, err := buildWebex(c, cr.Namespace, ac) + if err != nil { return err } + result.WebexConfigs = append(result.WebexConfigs, o) } - cb.finalizeSection("webex_configs") - - for _, jiraCfg := range receiver.JiraConfigs { - if err := cb.buildJira(jiraCfg); err != nil { + for _, c := range r.JiraConfigs { + o, err := buildJira(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.JiraConfigs = append(result.JiraConfigs, o) } - cb.finalizeSection("jira_configs") - - for _, rcCfg := range receiver.RocketchatConfigs { - if err := cb.buildRocketchat(rcCfg); err != nil { + for _, c := range r.RocketchatConfigs { + o, err := buildRocketchat(gc, c, cr.Namespace, ac) + if err != nil { return err } + result.RocketchatConfigs = append(result.RocketchatConfigs, o) } - cb.finalizeSection("rocketchat_configs") - - for _, c := range receiver.IncidentIOConfigs { - if err := cb.buildIncidentIO(c); err != nil { + for _, c := range r.IncidentioConfigs { + o, err := buildIncidentio(c, cr.Namespace, ac) + if err != nil { return err } + result.IncidentioConfigs = append(result.IncidentioConfigs, o) } - cb.finalizeSection("incidentio_configs") - - for _, rcCfg := range receiver.MSTeamsV2Configs { - if err := cb.buildTeamsV2(rcCfg); err != nil { + for _, c := range r.MSTeamsV2Configs { + o, err := buildMSTeamsV2(c, cr.Namespace, ac) + if err != nil { return err } + result.MSTeamsV2Configs = append(result.MSTeamsV2Configs, o) } - cb.finalizeSection("msteamsv2_configs") - return nil } -func (cb *configBuilder) finalizeSection(name string) { - if len(cb.currentYaml) > 0 { - cb.result = append(cb.result, yaml.MapItem{ - Key: name, - Value: cb.currentYaml, - }) - cb.currentYaml = make([]yaml.MapSlice, 0, len(cb.currentYaml)) - } -} - -func (cb *configBuilder) buildTeams(ms vmv1beta1.MSTeamsConfig) error { - var temp yaml.MapSlice - if ms.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(ms.HTTPConfig) +func buildMSTeams(rc vmv1beta1.MSTeamsConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) + r.set("http_config", c) } - if ms.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *ms.SendResolved}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - - if ms.URLSecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, ms.URLSecret) + if rc.URLSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.URLSecret) if err != nil { - return err + return nil, err } if err := parseURL(secret); err != nil { - return fmt.Errorf("invalid URL %s in key %s from secret %s: %w", secret, ms.URLSecret.Key, ms.URLSecret.Name, err) - } - temp = append(temp, yaml.MapItem{Key: "webhook_url", Value: secret}) - } else if ms.URL != nil { - temp = append(temp, yaml.MapItem{Key: "webhook_url", Value: ms.URL}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, fmt.Errorf("invalid URL %s in key %s from secret %s: %w", secret, rc.URLSecret.Key, rc.URLSecret.Name, err) } + r.set("webhook_url", secret) + } else if rc.URL != nil { + r.set("webhook_url", rc.URL) } - toYaml("title", ms.Title) - toYaml("text", ms.Text) - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("title", rc.Title) + r.set("text", rc.Text) + return r.items, nil } -func (cb *configBuilder) buildDiscord(dc vmv1beta1.DiscordConfig) error { - var temp yaml.MapSlice - if dc.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(dc.HTTPConfig) +func buildMattermost(rc vmv1beta1.MattermostConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) + r.set("http_config", c) } - if dc.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *dc.SendResolved}) + r.set("username", rc.Username) + r.set("channel", rc.Channel) + r.set("text", rc.Text) + r.set("icon_url", rc.IconURL) + r.set("icon_emoji", rc.IconEmoji) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } + var u string + if rc.URLSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.URLSecret) + if err != nil { + return nil, err + } + u = secret + } else if rc.URL != nil { + u = *rc.URL + } + if len(u) > 0 { + if err := parseURL(u); err != nil { + return nil, fmt.Errorf("invalid URL %s: %w", u, err) + } + r.set("webhook_url", u) + } + var attachments []yaml.MapSlice + for _, attachment := range rc.Attachments { + var ar rawValue + ar.set("fallback", attachment.Fallback) + ar.set("color", attachment.Color) + ar.set("pretext", attachment.Pretext) + ar.set("text", attachment.Text) + ar.set("author_name", attachment.AuthorName) + ar.set("author_link", attachment.AuthorLink) + ar.set("author_icon", attachment.AuthorIcon) + ar.set("title", attachment.Title) + ar.set("title_link", attachment.TitleLink) + ar.set("thumb_url", attachment.ThumbURL) + ar.set("footer", attachment.Footer) + ar.set("footer_icon", attachment.FooterIcon) + ar.set("image_url", attachment.ImageURL) + var fields []yaml.MapSlice + for _, field := range attachment.Fields { + var fr rawValue + fr.set("title", field.Title) + fr.set("value", field.Value) + fr.set("short", field.Short) + fields = append(fields, fr.items) + } + ar.set("fields", fields) + attachments = append(attachments, ar.items) + } + if len(attachments) > 0 { + r.set("attachments", attachments) + } + if rc.Props != nil { + var pr rawValue + if rc.Props.Card != nil { + pr.set("card", rc.Props.Card) + } + r.set("props", pr.items) + } + if rc.Priority != nil { + var pr rawValue + pr.set("priority", rc.Priority.Priority) + if rc.Priority.RequestedAck != nil { + pr.set("requested_ack", rc.Priority.RequestedAck) + } + if rc.Priority.PersistentNotifications != nil { + pr.set("persistent_notifications", rc.Priority.PersistentNotifications) + } + r.set("priority", pr.items) + } + return r.items, nil +} - if dc.URLSecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, dc.URLSecret) +func buildDiscord(rc vmv1beta1.DiscordConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - if err := parseURL(secret); err != nil { - return fmt.Errorf("invalid URL %s in key %s from secret %s: %v", secret, dc.URLSecret.Key, dc.URLSecret.Name, err) + r.set("http_config", c) + } + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) + } + var u string + if rc.URLSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.URLSecret) + if err != nil { + return nil, err } - temp = append(temp, yaml.MapItem{Key: "webhook_url", Value: secret}) - } else if dc.URL != nil { - temp = append(temp, yaml.MapItem{Key: "webhook_url", Value: dc.URL}) + u = secret + } else if rc.URL != nil { + u = *rc.URL } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + if len(u) > 0 { + if err := parseURL(u); err != nil { + return nil, fmt.Errorf("invalid URL %s: %w", u, err) } + r.set("webhook_url", u) } - toYaml("title", dc.Title) - toYaml("message", dc.Message) - toYaml("content", dc.Content) - toYaml("username", dc.Username) - toYaml("avatar_url", dc.AvatarURL) - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("title", rc.Title) + r.set("message", rc.Message) + r.set("content", rc.Content) + r.set("username", rc.Username) + r.set("avatar_url", rc.AvatarURL) + return r.items, nil } -func (cb *configBuilder) buildSNS(sns vmv1beta1.SnsConfig) error { - var temp yaml.MapSlice - if sns.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(sns.HTTPConfig) +func buildSNS(rc vmv1beta1.SNSConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) - } - if sns.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *sns.SendResolved}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, err } + r.set("http_config", c) } - toYaml("api_url", sns.URL) - toYaml("topic_arn", sns.TopicArn) - toYaml("subject", sns.Subject) - toYaml("phone_number", sns.PhoneNumber) - toYaml("target_arn", sns.TargetArn) - toYaml("message", sns.Message) - if len(sns.Attributes) > 0 { + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) + } + r.set("api_url", rc.URL) + r.set("topic_arn", rc.TopicArn) + r.set("subject", rc.Subject) + r.set("phone_number", rc.PhoneNumber) + r.set("target_arn", rc.TargetArn) + r.set("message", rc.Message) + if len(rc.Attributes) > 0 { var attributes yaml.MapSlice - for k, v := range sns.Attributes { + for k, v := range rc.Attributes { attributes = append(attributes, yaml.MapItem{Key: k, Value: v}) } - temp = append(temp, yaml.MapItem{Key: "attributes", Value: attributes}) - } - if sns.Sigv4 != nil { - var sigv4 yaml.MapSlice - toYamlSig := func(key string, src string) { - if len(src) > 0 { - sigv4 = append(sigv4, yaml.MapItem{Key: key, Value: src}) - } - } - toYamlSig("region", sns.Sigv4.Region) - toYamlSig("profile", sns.Sigv4.Profile) - toYamlSig("role_arn", sns.Sigv4.RoleArn) - if sns.Sigv4.AccessKey != "" { - toYamlSig("access_key", sns.Sigv4.AccessKey) - } else if sns.Sigv4.AccessKeySelector != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, sns.Sigv4.AccessKeySelector) + r.set("attributes", attributes) + } + if rc.Sigv4 != nil { + var sr rawValue + sr.set("region", rc.Sigv4.Region) + sr.set("profile", rc.Sigv4.Profile) + sr.set("role_arn", rc.Sigv4.RoleArn) + if rc.Sigv4.AccessKey != "" { + sr.set("access_key", rc.Sigv4.AccessKey) + } else if rc.Sigv4.AccessKeySelector != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.Sigv4.AccessKeySelector) if err != nil { - return err + return nil, err } - toYamlSig("access_key", secret) + sr.set("access_key", secret) } - if sns.Sigv4.SecretKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, sns.Sigv4.SecretKey) + if rc.Sigv4.SecretKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.Sigv4.SecretKey) if err != nil { - return err + return nil, err } - toYamlSig("secret_key", secret) + sr.set("secret_key", secret) } - temp = append(temp, yaml.MapItem{Key: "sigv4", Value: sigv4}) + r.set("sigv4", sr.items) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildWebex(web vmv1beta1.WebexConfig) error { - var temp yaml.MapSlice - if web.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(web.HTTPConfig) +func buildWebex(rc vmv1beta1.WebexConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) + r.set("http_config", c) } - if web.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *web.SendResolved}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - if web.URL != nil { - toYaml("api_url", *web.URL) + if rc.URL != nil { + r.set("api_url", rc.URL) } - toYaml("room_id", web.RoomId) - toYaml("message", web.Message) - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("room_id", rc.RoomId) + r.set("message", rc.Message) + return r.items, nil } -func (cb *configBuilder) buildJira(jira vmv1beta1.JiraConfig) error { - var temp yaml.MapSlice - if jira.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(jira.HTTPConfig) - if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) +func buildJira(gc *globalConfig, rc vmv1beta1.JiraConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.APIURL == nil && (gc == nil || len(gc.JiraAPIURL) == 0) { + return nil, fmt.Errorf("api_url secret is not defined and no global Jira API URL set") } - if jira.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *jira.SendResolved}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) + if err != nil { + return nil, err } + r.set("http_config", c) } - if jira.APIURL != nil { - toYaml("api_url", *jira.APIURL) - } - if jira.APIURL == nil && cb.globalConfig.Global.JiraAPIURL == "" { - return fmt.Errorf("api_url secret is not defined and no global Jira API URL set") - } - - toYaml("project", jira.Project) - toYaml("issue_type", jira.IssueType) - toYaml("description", jira.Description) - toYaml("priority", jira.Priority) - toYaml("summary", jira.Summary) - toYaml("reopen_transition", jira.ReopenTransition) - toYaml("resolve_transition", jira.ResolveTransition) - toYaml("wont_fix_resolution", jira.WontFixResolution) - toYaml("reopen_duration", jira.ReopenDuration) - - if len(jira.Labels) > 0 { - temp = append(temp, yaml.MapItem{ - Key: "labels", - Value: jira.Labels, - }) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - if len(jira.Fields) > 0 { - sortableFieldIdxs := make([]string, 0, len(jira.Fields)) - for key := range jira.Fields { + if rc.APIURL != nil { + r.set("api_url", rc.APIURL) + } + r.set("project", rc.Project) + r.set("issue_type", rc.IssueType) + r.set("description", rc.Description) + r.set("priority", rc.Priority) + r.set("summary", rc.Summary) + r.set("reopen_transition", rc.ReopenTransition) + r.set("resolve_transition", rc.ResolveTransition) + r.set("wont_fix_resolution", rc.WontFixResolution) + r.set("reopen_duration", rc.ReopenDuration) + r.set("labels", rc.Labels) + if len(rc.Fields) > 0 { + sortableFieldIdxs := make([]string, 0, len(rc.Fields)) + for key := range rc.Fields { sortableFieldIdxs = append(sortableFieldIdxs, key) } slices.Sort(sortableFieldIdxs) - fields := make(yaml.MapSlice, 0, len(jira.Fields)) + fields := make(yaml.MapSlice, 0, len(rc.Fields)) for _, key := range sortableFieldIdxs { fields = append(fields, yaml.MapItem{ Key: key, - Value: string(jira.Fields[key].Raw), + Value: string(rc.Fields[key].Raw), }) } - temp = append(temp, yaml.MapItem{ - Key: "fields", - Value: fields, - }) + r.set("fields", fields) } - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildIncidentIO(rc vmv1beta1.IncidentIOConfig) error { - var temp yaml.MapSlice +func buildIncidentio(rc vmv1beta1.IncidentioConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue if rc.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(rc.HTTPConfig) + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, err } + r.set("http_config", c) } if rc.AlertSourceToken != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, rc.AlertSourceToken) + secret, err := ac.LoadKeyFromSecret(ns, rc.AlertSourceToken) if err != nil { - return err + return nil, err } - toYaml("alert_source_token", secret) + r.set("alert_source_token", secret) } if rc.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *rc.SendResolved}) - } - if len(rc.URL) > 0 { - toYaml("url", rc.URL) - } - if len(rc.Timeout) > 0 { - toYaml("timeout", rc.Timeout) + r.set("send_resolved", rc.SendResolved) } - if rc.MaxAlerts > 0 { - temp = append(temp, yaml.MapItem{Key: "max_alerts", Value: rc.MaxAlerts}) - } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("url", rc.URL) + r.set("timeout", rc.Timeout) + r.set("max_alerts", rc.MaxAlerts) + return r.items, nil } -func (cb *configBuilder) buildRocketchat(rc vmv1beta1.RocketchatConfig) error { +func buildRocketchat(gc *globalConfig, rc vmv1beta1.RocketchatConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { if rc.TokenID == nil { - if cb.globalConfig.Global.RocketchatTokenID == "" && len(cb.globalConfig.Global.RocketchatTokenIDFile) == 0 { - return fmt.Errorf("no global Rocketchat TokenID set either inline or in a file") + if gc == nil || (len(gc.RocketchatTokenID) == 0 && len(gc.RocketchatTokenIDFile) == 0) { + return nil, fmt.Errorf("no global Rocketchat TokenID set either inline or in a file") } } if rc.Token == nil { - if cb.globalConfig.Global.RocketchatToken == "" && len(cb.globalConfig.Global.RocketchatTokenFile) == 0 { - return fmt.Errorf("no global Rocketchat Token set either inline or in a file") + if gc == nil || (len(gc.RocketchatToken) == 0 && len(gc.RocketchatTokenFile) == 0) { + return nil, fmt.Errorf("no global Rocketchat Token set either inline or in a file") } } - var temp yaml.MapSlice + var r rawValue if rc.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(rc.HTTPConfig) + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) + r.set("http_config", c) } if rc.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *rc.SendResolved}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } + r.set("send_resolved", rc.SendResolved) } if rc.APIURL != nil { - toYaml("api_url", *rc.APIURL) + r.set("api_url", rc.APIURL) } if rc.TokenID != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, rc.TokenID) + secret, err := ac.LoadKeyFromSecret(ns, rc.TokenID) if err != nil { - return err + return nil, err } - toYaml("token_id", secret) + r.set("token_id", secret) } if rc.Token != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, rc.Token) + secret, err := ac.LoadKeyFromSecret(ns, rc.Token) if err != nil { - return err + return nil, err } - toYaml("token", secret) - } - toYaml("channel", rc.Channel) - toYaml("color", rc.Color) - toYaml("title", rc.Title) - toYaml("text", rc.Text) - toYaml("emoji", rc.Emoji) - toYaml("icon_url", rc.IconURL) - toYaml("image_url", rc.ImageURL) - toYaml("thumb_url", rc.ThumbURL) - - if rc.ShortFields { - temp = append(temp, yaml.MapItem{Key: "short_fields", Value: rc.ShortFields}) - } - if rc.LinkNames { - temp = append(temp, yaml.MapItem{Key: "link_names", Value: rc.LinkNames}) - } + r.set("token", secret) + } + r.set("channel", rc.Channel) + r.set("color", rc.Color) + r.set("title", rc.Title) + r.set("text", rc.Text) + r.set("emoji", rc.Emoji) + r.set("icon_url", rc.IconURL) + r.set("image_url", rc.ImageURL) + r.set("thumb_url", rc.ThumbURL) + r.set("short_fields", rc.ShortFields) + r.set("link_names", rc.LinkNames) if len(rc.Fields) > 0 { fields := make([]yaml.MapSlice, 0, len(rc.Fields)) for _, f := range rc.Fields { - field := make(yaml.MapSlice, 0, 4) - if len(f.Title) > 0 { - field = append(field, yaml.MapItem{ - Key: "title", - Value: f.Title, - }) - } - if len(f.Value) > 0 { - field = append(field, yaml.MapItem{ - Key: "value", - Value: f.Value, - }) - } + var fr rawValue + fr.set("title", f.Title) + fr.set("value", f.Value) if f.Short != nil { - field = append(field, yaml.MapItem{ - Key: "short", - Value: *f.Short, - }) + fr.set("short", *f.Short) } - fields = append(fields, field) + fields = append(fields, fr.items) } - temp = append(temp, yaml.MapItem{ - Key: "fields", - Value: fields, - }) + r.set("fields", fields) } if len(rc.Actions) > 0 { actions := make([]yaml.MapSlice, 0, len(rc.Actions)) for _, a := range rc.Actions { - action := make(yaml.MapSlice, 0, 4) - actionToYaml := func(key string, src string) { - if len(src) > 0 { - action = append(action, yaml.MapItem{Key: key, Value: src}) - } - } - actionToYaml("type", a.Type) - actionToYaml("text,omitempty", a.Text) - actionToYaml("url", a.URL) - actionToYaml("msg", a.Msg) - - actions = append(actions, action) + var ar rawValue + ar.set("type", a.Type) + ar.set("text,omitempty", a.Text) + ar.set("url", a.URL) + ar.set("msg", a.Msg) + actions = append(actions, ar.items) } - temp = append(temp, yaml.MapItem{ - Key: "actions", - Value: actions, - }) + r.set("actions", actions) } - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildTelegram(tg vmv1beta1.TelegramConfig) error { - var temp yaml.MapSlice - - if tg.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(tg.HTTPConfig) +func buildTelegram(rc vmv1beta1.TelegramConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) + r.set("http_config", c) } - if tg.BotToken != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, tg.BotToken) + if rc.BotToken != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.BotToken) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "bot_token", Value: secret}) - } - if tg.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *tg.SendResolved}) + r.set("bot_token", secret) } - if tg.DisableNotifications != nil { - temp = append(temp, yaml.MapItem{Key: "disable_notifications", Value: *tg.DisableNotifications}) - } - temp = append(temp, yaml.MapItem{Key: "chat_id", Value: tg.ChatID}) - if tg.MessageThreadID > 0 { - temp = append(temp, yaml.MapItem{Key: "message_thread_id", Value: tg.MessageThreadID}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } + if rc.DisableNotifications != nil { + r.set("disable_notifications", rc.DisableNotifications) } - toYaml("api_url", tg.APIUrl) - toYaml("message", tg.Message) - toYaml("parse_mode", tg.ParseMode) - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("chat_id", rc.ChatID) + r.set("message_thread_id", rc.MessageThreadID) + r.set("api_url", rc.APIUrl) + r.set("message", rc.Message) + r.set("parse_mode", rc.ParseMode) + return r.items, nil } -func (cb *configBuilder) buildSlack(slack vmv1beta1.SlackConfig) error { - var temp yaml.MapSlice - if slack.HTTPConfig != nil { - c, err := cb.buildHTTPConfig(slack.HTTPConfig) - if err != nil { - return err +func buildSlack(gc *globalConfig, rc vmv1beta1.SlackConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.APIURL == nil { + if gc == nil || (len(gc.SlackAPIURL) == 0 && gc.SlackAPIURLFile == "") { + return nil, fmt.Errorf("api_url secret is not defined and no global Slack API URL set either inline or in a file") } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: c}) } - if slack.APIURL == nil && cb.globalConfig.Global.SlackAPIURL == "" && cb.globalConfig.Global.SlackAPIURLFile == "" { - return fmt.Errorf("api_url secret is not defined and no global Slack API URL set either inline or in a file") + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) + if err != nil { + return nil, err + } + r.set("http_config", c) } - if slack.APIURL != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, slack.APIURL) + if rc.APIURL != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.APIURL) if err != nil { - return err + return nil, err } if err := parseURL(secret); err != nil { - return fmt.Errorf("invalid URL %s in key %s from secret %s: %v", secret, slack.APIURL.Key, slack.APIURL.Name, err) - } - temp = append(temp, yaml.MapItem{Key: "api_url", Value: secret}) - } - if slack.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *slack.SendResolved}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, fmt.Errorf("invalid URL %s in key %s from secret %s: %v", secret, rc.APIURL.Key, rc.APIURL.Name, err) } + r.set("api_url", secret) } - toYaml("username", slack.Username) - toYaml("channel", slack.Channel) - toYaml("color", slack.Color) - toYaml("fallback", slack.Fallback) - toYaml("footer", slack.Footer) - toYaml("icon_emoji", slack.IconEmoji) - toYaml("icon_url", slack.IconURL) - toYaml("image_url", slack.ImageURL) - toYaml("pretext", slack.Pretext) - toYaml("text", slack.Text) - toYaml("title", slack.Title) - toYaml("title_link", slack.TitleLink) - toYaml("thumb_url", slack.ThumbURL) - toYaml("callback_id", slack.CallbackID) - if slack.LinkNames { - temp = append(temp, yaml.MapItem{Key: "link_names", Value: slack.LinkNames}) - } - if slack.ShortFields { - temp = append(temp, yaml.MapItem{Key: "short_fields", Value: slack.ShortFields}) - } - if slack.UpdateMessage != nil { - temp = append(temp, yaml.MapItem{Key: "update_message", Value: *slack.UpdateMessage}) - } - if len(slack.MrkdwnIn) > 0 { - temp = append(temp, yaml.MapItem{Key: "mrkdwn_in", Value: slack.MrkdwnIn}) - } + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) + } + r.set("username", rc.Username) + r.set("channel", rc.Channel) + r.set("color", rc.Color) + r.set("fallback", rc.Fallback) + r.set("footer", rc.Footer) + r.set("icon_emoji", rc.IconEmoji) + r.set("icon_url", rc.IconURL) + r.set("image_url", rc.ImageURL) + r.set("pretext", rc.Pretext) + r.set("text", rc.Text) + r.set("title", rc.Title) + r.set("title_link", rc.TitleLink) + r.set("thumb_url", rc.ThumbURL) + r.set("callback_id", rc.CallbackID) + r.set("link_names", rc.LinkNames) + r.set("short_fields", rc.ShortFields) + if rc.UpdateMessage != nil { + r.set("update_message", rc.UpdateMessage) + } + r.set("mrkdwn_in", rc.MrkdwnIn) var actions []yaml.MapSlice - for _, action := range slack.Actions { - var actionYAML yaml.MapSlice - toActionYAML := func(key, src string) { - if len(src) > 0 { - actionYAML = append(actionYAML, yaml.MapItem{Key: key, Value: src}) - } - } - toActionYAML("name", action.Name) - toActionYAML("value", action.Value) - toActionYAML("text", action.Text) - toActionYAML("url", action.URL) - toActionYAML("type", action.Type) - toActionYAML("style", action.Style) - + for _, action := range rc.Actions { + var ar rawValue + ar.set("name", action.Name) + ar.set("value", action.Value) + ar.set("text", action.Text) + ar.set("url", action.URL) + ar.set("type", action.Type) + ar.set("style", action.Style) if action.ConfirmField != nil { - var confirmYAML yaml.MapSlice - toConfirm := func(key, src string) { - if len(src) > 0 { - confirmYAML = append(confirmYAML, yaml.MapItem{Key: key, Value: src}) - } - } - toConfirm("text", action.ConfirmField.Text) - toConfirm("ok_text", action.ConfirmField.OkText) - toConfirm("dismiss_text", action.ConfirmField.DismissText) - toConfirm("title", action.ConfirmField.Title) - actionYAML = append(actionYAML, yaml.MapItem{Key: "confirm", Value: confirmYAML}) + var cfr rawValue + cfr.set("text", action.ConfirmField.Text) + cfr.set("ok_text", action.ConfirmField.OkText) + cfr.set("dismiss_text", action.ConfirmField.DismissText) + cfr.set("title", action.ConfirmField.Title) + ar.set("confirm", cfr.items) } - actions = append(actions, actionYAML) + actions = append(actions, ar.items) } if len(actions) > 0 { - temp = append(temp, yaml.MapItem{Key: "actions", Value: actions}) + r.set("actions", actions) } var fields []yaml.MapSlice - for _, field := range slack.Fields { - var fieldYAML yaml.MapSlice - if len(field.Value) > 0 { - fieldYAML = append(fieldYAML, yaml.MapItem{Key: "value", Value: field.Value}) - } - if len(field.Title) > 0 { - fieldYAML = append(fieldYAML, yaml.MapItem{Key: "title", Value: field.Title}) - } - - if field.Short != nil { - fieldYAML = append(fieldYAML, yaml.MapItem{Key: "short", Value: *field.Short}) - } - fields = append(fields, fieldYAML) + for _, field := range rc.Fields { + var fr rawValue + fr.set("value", field.Value) + fr.set("title", field.Title) + fr.set("short", field.Short) + fields = append(fields, fr.items) } if len(fields) > 0 { - temp = append(temp, yaml.MapItem{Key: "fields", Value: fields}) + r.set("fields", fields) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildTeamsV2(mstCfg vmv1beta1.MSTeamsV2Config) error { - if mstCfg.URL == nil && mstCfg.URLSecret == nil { - return fmt.Errorf("one of required fields 'webhook_url' or 'webhook_url_secret' are not set") +func buildMSTeamsV2(rc vmv1beta1.MSTeamsV2Config, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.URL == nil && rc.URLSecret == nil { + return nil, fmt.Errorf("one of required fields 'webhook_url' or 'webhook_url_secret' are not set") } - var temp yaml.MapSlice - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } - } - if mstCfg.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(mstCfg.HTTPConfig) + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) + r.set("http_config", c) } - if mstCfg.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *mstCfg.SendResolved}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - var whURL string - switch { - case mstCfg.URLSecret != nil: - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, mstCfg.URLSecret) + var u string + if rc.URLSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.URLSecret) if err != nil { - return err + return nil, err } - whURL = secret - case mstCfg.URL != nil: - whURL = *mstCfg.URL - default: - panic("BUG: impossible switch statement") + u = secret + } else if rc.URL != nil { + u = *rc.URL } - if _, err := url.Parse(whURL); err != nil { - return fmt.Errorf("unexpected webhook_url value=%q: %w", whURL, err) + if len(u) == 0 { + return nil, nil } - toYaml("webhook_url", whURL) - toYaml("text", mstCfg.Text) - toYaml("title", mstCfg.Title) - - cb.currentYaml = append(cb.currentYaml, temp) - - return nil + if err := parseURL(u); err != nil { + return nil, fmt.Errorf("unexpected webhook_url value=%q: %w", u, err) + } + r.set("webhook_url", u) + r.set("text", rc.Text) + r.set("title", rc.Title) + return r.items, nil } -func (cb *configBuilder) buildWebhook(wh vmv1beta1.WebhookConfig) error { - var temp yaml.MapSlice - if wh.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(wh.HTTPConfig) +func buildWebhook(rc vmv1beta1.WebhookConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) + r.set("http_config", c) } - if wh.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *wh.SendResolved}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } var url string - - if wh.URL != nil { - url = *wh.URL - } else if wh.URLSecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, wh.URLSecret) + if rc.URLSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.URLSecret) if err != nil { - return err + return nil, err } url = secret + } else if rc.URL != nil { + url = *rc.URL } // no point to add config without url - if url == "" { - return nil + if len(url) == 0 { + return nil, nil } if err := parseURL(url); err != nil { - return fmt.Errorf("failed to parse webhook url: %w", err) + return nil, fmt.Errorf("failed to parse webhook url: %w", err) } - - temp = append(temp, yaml.MapItem{Key: "url", Value: url}) - if wh.MaxAlerts != 0 { - temp = append(temp, yaml.MapItem{Key: "max_alerts", Value: wh.MaxAlerts}) - } - if len(wh.Timeout) > 0 { - temp = append(temp, yaml.MapItem{Key: "timeout", Value: wh.Timeout}) - } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + r.set("url", url) + r.set("max_alerts", rc.MaxAlerts) + r.set("timeout", rc.Timeout) + return r.items, nil } -func (cb *configBuilder) buildWeeChat(wc vmv1beta1.WeChatConfig) error { - if wc.APISecret == nil && cb.globalConfig.Global.WeChatAPISecret == "" { - return fmt.Errorf("api_secret is not set and no global Wechat ApiSecret set") +func buildWechat(gc *globalConfig, rc vmv1beta1.WechatConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.APISecret == nil && (gc == nil || gc.WechatAPISecret == "") { + return nil, fmt.Errorf("api_secret is not set and no global Wechat ApiSecret set") } - if wc.CorpID == "" && cb.globalConfig.Global.WeChatAPICorpID == "" { - return fmt.Errorf("cord_id is not set and no global Wechat CorpID set") + if rc.CorpID == "" && (gc == nil || gc.WechatAPICorpID == "") { + return nil, fmt.Errorf("cord_id is not set and no global Wechat CorpID set") } - var temp yaml.MapSlice - if wc.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(wc.HTTPConfig) + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) + r.set("http_config", c) } - if wc.APISecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, wc.APISecret) + if rc.APISecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.APISecret) if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "api_secret", Value: secret}) - } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, err } - } - toYaml("message", wc.Message) - toYaml("message_type", wc.MessageType) - toYaml("agent_id", wc.AgentID) - toYaml("corp_id", wc.CorpID) - toYaml("to_party", wc.ToParty) - toYaml("to_tag", wc.ToTag) - toYaml("to_user", wc.ToUser) - toYaml("api_url", wc.APIURL) - if wc.APIURL != "" { - err := parseURL(wc.APIURL) - if err != nil { - return err + r.set("api_secret", secret) + } + r.set("message", rc.Message) + r.set("message_type", rc.MessageType) + r.set("agent_id", rc.AgentID) + r.set("corp_id", rc.CorpID) + r.set("to_party", rc.ToParty) + r.set("to_tag", rc.ToTag) + r.set("to_user", rc.ToUser) + if rc.APIURL != "" { + if err := parseURL(rc.APIURL); err != nil { + return nil, err } + r.set("api_url", rc.APIURL) } - if wc.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *wc.SendResolved}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildVictorOps(vo vmv1beta1.VictorOpsConfig) error { - if vo.APIKey == nil && cb.globalConfig.Global.VictorOpsAPIKey == "" && cb.globalConfig.Global.VictorOpsAPIKeyFile == "" { - return fmt.Errorf("api_key secret is not set and no global VictorOps API Key set") - } - var temp yaml.MapSlice - if vo.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(vo.HTTPConfig) - if err != nil { - return err +func buildVictorOps(gc *globalConfig, rc vmv1beta1.VictorOpsConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.APIKey == nil { + if gc == nil || (gc.VictorOpsAPIKey == "" && gc.VictorOpsAPIKeyFile == "") { + return nil, fmt.Errorf("api_key secret is not set and no global VictorOps API Key set") } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) } - if vo.APIKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, vo.APIKey) + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "api_key", Value: secret}) + r.set("http_config", c) } - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + if rc.APIKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.APIKey) + if err != nil { + return nil, err } + r.set("api_key", secret) } - toYaml("api_url", vo.APIURL) - if vo.APIURL != "" { - err := parseURL(vo.APIURL) - if err != nil { - return err + if rc.APIURL != "" { + if err := parseURL(rc.APIURL); err != nil { + return nil, err } + r.set("api_url", rc.APIURL) } - toYaml("routing_key", vo.RoutingKey) - toYaml("message_type", vo.MessageType) - toYaml("entity_display_name", vo.EntityDisplayName) - toYaml("state_message", vo.StateMessage) - toYaml("monitoring_tool", vo.MonitoringTool) - if vo.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *vo.SendResolved}) + r.set("routing_key", rc.RoutingKey) + r.set("message_type", rc.MessageType) + r.set("entity_display_name", rc.EntityDisplayName) + r.set("state_message", rc.StateMessage) + r.set("monitoring_tool", rc.MonitoringTool) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - if len(vo.CustomFields) > 0 { - var cfs yaml.MapSlice + if len(rc.CustomFields) > 0 { + var cfs rawValue var customFieldIDs []string - for customFieldKey := range vo.CustomFields { + for customFieldKey := range rc.CustomFields { customFieldIDs = append(customFieldIDs, customFieldKey) } slices.Sort(customFieldIDs) for _, customFieldKey := range customFieldIDs { - value := vo.CustomFields[customFieldKey] - cfs = append(cfs, yaml.MapItem{Key: customFieldKey, Value: value}) + value := rc.CustomFields[customFieldKey] + cfs.set(customFieldKey, value) } - temp = append(temp, yaml.MapItem{Key: "custom_fields", Value: cfs}) + r.set("custom_fields", cfs.items) } - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildPushOver(po vmv1beta1.PushoverConfig) error { - var temp yaml.MapSlice - toYaml := func(key, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } - } - if po.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(po.HTTPConfig) +func buildPushover(rc vmv1beta1.PushoverConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) + r.set("http_config", c) } - if po.UserKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, po.UserKey) + if rc.UserKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.UserKey) if err != nil { - return err + return nil, err } - toYaml("user_key", secret) + r.set("user_key", secret) } - if po.Token != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, po.Token) + if rc.Token != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.Token) if err != nil { - return err + return nil, err } - toYaml("token", secret) + r.set("token", secret) } - toYaml("url", po.URL) - toYaml("sound", po.Sound) - toYaml("priority", po.Priority) - toYaml("message", po.Message) - toYaml("expire", po.Expire) - toYaml("retry", po.Retry) - toYaml("title", po.Title) - toYaml("url_title", po.URLTitle) - temp = append(temp, yaml.MapItem{Key: "html", Value: po.HTML}) - if po.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *po.SendResolved}) + r.set("url", rc.URL) + r.set("sound", rc.Sound) + r.set("priority", rc.Priority) + r.set("message", rc.Message) + r.set("expire", rc.Expire) + r.set("retry", rc.Retry) + r.set("title", rc.Title) + r.set("url_title", rc.URLTitle) + r.set("html", rc.HTML) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildPagerDuty(pd vmv1beta1.PagerDutyConfig) error { - var temp yaml.MapSlice - toYaml := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) - } - } - if pd.HTTPConfig != nil { - h, err := cb.buildHTTPConfig(pd.HTTPConfig) +func buildPagerDuty(rc vmv1beta1.PagerDutyConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: h}) + r.set("http_config", c) } - if pd.RoutingKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, pd.RoutingKey) + if rc.RoutingKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.RoutingKey) if err != nil { - return err + return nil, err } - toYaml("routing_key", secret) + r.set("routing_key", secret) } - if pd.ServiceKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, pd.ServiceKey) + if rc.ServiceKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.ServiceKey) if err != nil { - return err + return nil, err } - toYaml("service_key", secret) + r.set("service_key", secret) } - toYaml("url", pd.URL) - if pd.URL != "" { - err := parseURL(pd.URL) - if err != nil { - return err + if rc.URL != "" { + if err := parseURL(rc.URL); err != nil { + return nil, err } + r.set("url", rc.URL) } - toYaml("description", pd.Description) - toYaml("client_url", pd.ClientURL) - toYaml("client", pd.Client) - toYaml("class", pd.Class) - toYaml("component", pd.Component) - toYaml("group", pd.Group) - toYaml("severity", pd.Severity) + r.set("description", rc.Description) + r.set("client_url", rc.ClientURL) + r.set("client", rc.Client) + r.set("class", rc.Class) + r.set("component", rc.Component) + r.set("group", rc.Group) + r.set("severity", rc.Severity) var images []yaml.MapSlice - for _, image := range pd.Images { - var imageYAML yaml.MapSlice - if len(image.Href) > 0 { - imageYAML = append(imageYAML, yaml.MapItem{Key: "href", Value: image.Href}) - } - if len(image.Source) > 0 { - imageYAML = append(imageYAML, yaml.MapItem{Key: "source", Value: image.Source}) - } - if len(image.Alt) > 0 { - imageYAML = append(imageYAML, yaml.MapItem{Key: "alt", Value: image.Alt}) - } - images = append(images, imageYAML) + for _, image := range rc.Images { + var ir rawValue + ir.set("href", image.Href) + ir.set("source", image.Source) + ir.set("alt", image.Alt) + images = append(images, ir.items) } if len(images) > 0 { - temp = append(temp, yaml.MapItem{Key: "images", Value: images}) + r.set("images", images) } var links []yaml.MapSlice - for _, link := range pd.Links { + for _, link := range rc.Links { var linkYAML yaml.MapSlice if len(link.Href) > 0 { linkYAML = append(linkYAML, yaml.MapItem{Key: "href", Value: link.Href}) @@ -1372,10 +1267,10 @@ func (cb *configBuilder) buildPagerDuty(pd vmv1beta1.PagerDutyConfig) error { links = append(links, linkYAML) } if len(links) > 0 { - temp = append(temp, yaml.MapItem{Key: "links", Value: links}) + r.set("links", links) } - detailKeys := make([]string, 0, len(pd.Details)) - for detailKey, value := range pd.Details { + detailKeys := make([]string, 0, len(rc.Details)) + for detailKey, value := range rc.Details { if len(value) == 0 { continue } @@ -1385,232 +1280,202 @@ func (cb *configBuilder) buildPagerDuty(pd vmv1beta1.PagerDutyConfig) error { if len(detailKeys) > 0 { var detailsYaml yaml.MapSlice for _, detailKey := range detailKeys { - detailsYaml = append(detailsYaml, yaml.MapItem{Key: detailKey, Value: pd.Details[detailKey]}) + detailsYaml = append(detailsYaml, yaml.MapItem{Key: detailKey, Value: rc.Details[detailKey]}) } - temp = append(temp, yaml.MapItem{Key: "details", Value: detailsYaml}) + r.set("details", detailsYaml) } - if pd.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *pd.SendResolved}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildEmail(email vmv1beta1.EmailConfig) error { - var temp yaml.MapSlice - if email.RequireTLS != nil { - temp = append(temp, yaml.MapItem{Key: "require_tls", Value: *email.RequireTLS}) +func buildEmail(gc *globalConfig, rc vmv1beta1.EmailConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if len(rc.Smarthost) == 0 && (gc == nil || len(gc.SMTPSmarthost) == 0) { + return nil, fmt.Errorf("required email smarthost is not set at local and global alertmanager config") } - if email.Smarthost == "" && cb.globalConfig.Global.SMTPSmarthost == "" { - return fmt.Errorf("required email smarthost is not set at local and global alertmanager config") + if len(rc.Smarthost) == 0 && (gc == nil || len(gc.SMTPSmarthost) == 0) { + return nil, fmt.Errorf("required email smarthost is not set at local and global alertmanager config") } - if email.From == "" && cb.globalConfig.Global.SMTPFrom == "" { - return fmt.Errorf("required email from is not set at local and global alertmanager config") + if rc.From == "" && (gc == nil || gc.SMTPFrom == "") { + return nil, fmt.Errorf("required email from is not set at local and global alertmanager config") } + var r rawValue + if rc.RequireTLS != nil { + r.set("require_tls", rc.RequireTLS) + } // add tls config in any case // require_tls is true by default and it could be managed via global configuration - if email.TLSConfig != nil { - cfg, err := cb.cache.TLSToYAML(cb.namespace, "", email.TLSConfig) + if rc.TLSConfig != nil { + cfg, err := ac.TLSToYAML(ns, "", rc.TLSConfig) if err != nil { - return err + return nil, err } if len(cfg) > 0 { - temp = append(temp, yaml.MapItem{Key: "tls_config", Value: cfg}) + r.set("tls_config", cfg) } } - - if email.AuthPassword != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, email.AuthPassword) + if rc.AuthPassword != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.AuthPassword) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "auth_password", Value: secret}) + r.set("auth_password", secret) } - if email.AuthSecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, email.AuthSecret) + if rc.AuthSecret != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.AuthSecret) if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "auth_secret", Value: secret}) - } - if len(email.Headers) > 0 { - temp = append(temp, yaml.MapItem{Key: "headers", Value: email.Headers}) - } - toYamlString := func(key string, src string) { - if len(src) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: src}) + return nil, err } + r.set("auth_secret", secret) + } + r.set("headers", rc.Headers) + r.set("from", rc.From) + r.set("text", rc.Text) + r.set("to", rc.To) + r.set("html", rc.HTML) + r.set("auth_identity", rc.AuthIdentity) + r.set("auth_username", rc.AuthUsername) + r.set("hello", rc.Hello) + r.set("smarthost", rc.Smarthost) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } - toYamlString("from", email.From) - toYamlString("text", email.Text) - toYamlString("to", email.To) - toYamlString("html", email.HTML) - toYamlString("auth_identity", email.AuthIdentity) - toYamlString("auth_username", email.AuthUsername) - toYamlString("hello", email.Hello) - toYamlString("smarthost", email.Smarthost) - if email.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *email.SendResolved}) - } - - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildOpsGenie(og vmv1beta1.OpsGenieConfig) error { - if og.APIKey == nil && cb.globalConfig.Global.OpsGenieAPIKey == "" && cb.globalConfig.Global.OpsGenieAPIKeyFile == "" { - return fmt.Errorf("api_key secret is not defined and no global OpsGenie API Key set either inline or in a file") - } - var temp yaml.MapSlice - if og.APIKey != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, og.APIKey) - if err != nil { - return err - } - temp = append(temp, yaml.MapItem{Key: "api_key", Value: secret}) - } - toYamlString := func(key string, value string) { - if len(value) > 0 { - temp = append(temp, yaml.MapItem{Key: key, Value: value}) +func buildOpsGenie(gc *globalConfig, rc vmv1beta1.OpsGenieConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + if rc.APIKey == nil { + if gc == nil || (gc.OpsGenieAPIKey == "" && gc.OpsGenieAPIKeyFile == "") { + return nil, fmt.Errorf("api_key secret is not defined and no global OpsGenie API Key set either inline or in a file") } } - toYamlString("source", og.Source) - toYamlString("description", og.Description) - toYamlString("message", og.Message) - toYamlString("tags", og.Tags) - toYamlString("note", og.Note) - toYamlString("api_url", og.APIURL) - toYamlString("entity", og.Entity) - toYamlString("Actions", og.Actions) - - if og.APIURL != "" { - err := parseURL(og.APIURL) + var r rawValue + if rc.APIKey != nil { + secret, err := ac.LoadKeyFromSecret(ns, rc.APIKey) if err != nil { - return err + return nil, err } + r.set("api_key", secret) + } + r.set("source", rc.Source) + r.set("message", rc.Message) + r.set("description", rc.Description) + r.set("tags", rc.Tags) + r.set("note", rc.Note) + r.set("entity", rc.Entity) + r.set("Actions", rc.Actions) + if rc.APIURL != "" { + if err := parseURL(rc.APIURL); err != nil { + return nil, err + } + r.set("api_url", rc.APIURL) } - toYamlString("priority", og.Priority) - if og.Details != nil { - temp = append(temp, yaml.MapItem{Key: "details", Value: og.Details}) - } - if og.SendResolved != nil { - temp = append(temp, yaml.MapItem{Key: "send_resolved", Value: *og.SendResolved}) + r.set("priority", rc.Priority) + if rc.Details != nil { + r.set("details", rc.Details) } - if og.UpdateAlerts { - temp = append(temp, yaml.MapItem{Key: "update_alerts", Value: og.UpdateAlerts}) + if rc.SendResolved != nil { + r.set("send_resolved", rc.SendResolved) } + r.set("update_alerts", rc.UpdateAlerts) var responders []yaml.MapSlice - for _, responder := range og.Responders { - var responderYAML yaml.MapSlice - toResponderYAML := func(key, src string) { - if len(src) > 0 { - responderYAML = append(responderYAML, yaml.MapItem{Key: key, Value: src}) - } - } - toResponderYAML("name", responder.Name) - toResponderYAML("username", responder.Username) - toResponderYAML("id", responder.ID) - toResponderYAML("type", responder.Type) - - responders = append(responders, responderYAML) + for _, responder := range rc.Responders { + var rr rawValue + rr.set("name", responder.Name) + rr.set("username", responder.Username) + rr.set("id", responder.ID) + rr.set("type", responder.Type) + responders = append(responders, rr.items) } if len(responders) > 0 { - temp = append(temp, yaml.MapItem{Key: "responders", Value: responders}) + r.set("responders", responders) } - - if og.HTTPConfig != nil { - yamlHTTP, err := cb.buildHTTPConfig(og.HTTPConfig) + if rc.HTTPConfig != nil { + c, err := buildHTTPConfig(rc.HTTPConfig, ns, ac) if err != nil { - return err + return nil, err } - temp = append(temp, yaml.MapItem{Key: "http_config", Value: yamlHTTP}) + r.set("http_config", c) } - cb.currentYaml = append(cb.currentYaml, temp) - return nil + return r.items, nil } -func (cb *configBuilder) buildHTTPConfig(httpCfg *vmv1beta1.HTTPConfig) (yaml.MapSlice, error) { - var r yaml.MapSlice - +func buildHTTPConfig(httpCfg *vmv1beta1.HTTPConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { if httpCfg == nil { return nil, nil } + var r rawValue if httpCfg.TLSConfig != nil { - cfg, err := cb.cache.TLSToYAML(cb.namespace, "", httpCfg.TLSConfig) + cfg, err := ac.TLSToYAML(ns, "", httpCfg.TLSConfig) if err != nil { return nil, err } if len(cfg) > 0 { - r = append(r, yaml.MapItem{Key: "tls_config", Value: cfg}) + r.set("tls_config", cfg) } } if httpCfg.Authorization != nil { - cfg, err := cb.cache.AuthorizationToYAML(cb.namespace, httpCfg.Authorization) + cfg, err := ac.AuthorizationToYAML(ns, httpCfg.Authorization) if err != nil { return nil, err } - r = append(r, cfg...) + r.items = append(r.items, cfg...) } if httpCfg.BasicAuth != nil { - cfg, err := cb.cache.BasicAuthToYAML(cb.namespace, httpCfg.BasicAuth) + cfg, err := ac.BasicAuthToYAML(ns, httpCfg.BasicAuth) if err != nil { return nil, err } - r = append(r, yaml.MapItem{Key: "basic_auth", Value: cfg}) + r.set("basic_auth", cfg) } - var tokenAuth yaml.MapSlice + var tokenAuth rawValue if httpCfg.BearerTokenSecret != nil { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, httpCfg.BearerTokenSecret) + secret, err := ac.LoadKeyFromSecret(ns, httpCfg.BearerTokenSecret) if err != nil { return nil, fmt.Errorf("cannot find secret for bearerToken: %w", err) } - tokenAuth = append(tokenAuth, yaml.MapItem{Key: "credentials", Value: secret}) + tokenAuth.set("credentials", secret) } if len(httpCfg.BearerTokenFile) > 0 { - tokenAuth = append(tokenAuth, yaml.MapItem{Key: "credentials_file", Value: httpCfg.BearerTokenFile}) + tokenAuth.set("credentials_file", httpCfg.BearerTokenFile) } - if len(tokenAuth) > 0 { - r = append(r, yaml.MapItem{Key: "authorization", Value: tokenAuth}) + if len(tokenAuth.items) > 0 { + r.set("authorization", tokenAuth.items) } if httpCfg.FollowRedirects != nil { - r = append(r, yaml.MapItem{Key: "follow_redirects", Value: *httpCfg.FollowRedirects}) + r.set("follow_redirects", *httpCfg.FollowRedirects) } if httpCfg.OAuth2 != nil { - cfg, err := cb.cache.OAuth2ToYAML(cb.namespace, httpCfg.OAuth2) + cfg, err := ac.OAuth2ToYAML(ns, httpCfg.OAuth2) if err != nil { return nil, fmt.Errorf("cannot build oauth2 configuration: %w", err) } - r = append(r, cfg...) + r.items = append(r.items, cfg...) } - cfg, err := cb.buildProxyConfig(&httpCfg.ProxyConfig) + cfg, err := buildProxyConfig(&httpCfg.ProxyConfig, ns, ac) if err != nil { return nil, err } if len(cfg) > 0 { - r = append(r, cfg...) + r.items = append(r.items, cfg...) } - return r, nil + return r.items, nil } -func (cb *configBuilder) buildProxyConfig(proxyCfg *vmv1beta1.ProxyConfig) (yaml.MapSlice, error) { - var r yaml.MapSlice - if len(proxyCfg.ProxyURL) > 0 { - r = append(r, yaml.MapItem{Key: "proxy_url", Value: proxyCfg.ProxyURL}) - } - if len(proxyCfg.NoProxy) > 0 { - r = append(r, yaml.MapItem{Key: "no_proxy", Value: proxyCfg.NoProxy}) - } - if proxyCfg.ProxyFromEnvironment { - r = append(r, yaml.MapItem{Key: "proxy_from_environment", Value: proxyCfg.ProxyFromEnvironment}) - } +func buildProxyConfig(proxyCfg *vmv1beta1.ProxyConfig, ns string, ac *build.AssetsCache) (yaml.MapSlice, error) { + var r rawValue + r.set("proxy_url", proxyCfg.ProxyURL) + r.set("no_proxy", proxyCfg.NoProxy) + r.set("proxy_from_environment", proxyCfg.ProxyFromEnvironment) if len(proxyCfg.ProxyConnectHeader) > 0 { var h yaml.MapSlice for k, vs := range proxyCfg.ProxyConnectHeader { var secrets []string for i, v := range vs { - secret, err := cb.cache.LoadKeyFromSecret(cb.namespace, &v) + secret, err := ac.LoadKeyFromSecret(ns, &v) if err != nil { return nil, fmt.Errorf("cannot find secret for proxy_connect_header[%q][%d]: %w", k, i, err) } @@ -1619,21 +1484,20 @@ func (cb *configBuilder) buildProxyConfig(proxyCfg *vmv1beta1.ProxyConfig) (yaml h = append(h, yaml.MapItem{Key: k, Value: secrets}) } if len(h) > 0 { - r = append(r, yaml.MapItem{Key: "proxy_connect_header", Value: h}) + r.items = append(r.items, yaml.MapItem{Key: "proxy_connect_header", Value: h}) } } - return r, nil + return r.items, nil } // builds configuration according to https://prometheus.io/docs/alerting/latest/configuration/#tracing-configuration func buildTracingConfig(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCache) (yaml.MapSlice, error) { - var cfg yaml.MapSlice + var cfg rawValue if cr == nil || cr.Spec.TracingConfig == nil { - return cfg, nil + return cfg.items, nil } tracingCfg := cr.Spec.TracingConfig if tracingCfg.TLSConfig != nil { - var tlsCfg yaml.MapSlice if tracingCfg.TLSConfig.CASecretRef != nil { file, err := ac.LoadPathFromSecret(build.TLSAssetsResourceKind, cr.Namespace, tracingCfg.TLSConfig.CASecretRef) if err != nil { @@ -1657,43 +1521,22 @@ func buildTracingConfig(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCache) (ya tracingCfg.TLSConfig.KeyFile = file } - if len(tracingCfg.TLSConfig.CAFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "ca_file", Value: tracingCfg.TLSConfig.CAFile}) - } - if len(tracingCfg.TLSConfig.CertFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cert_file", Value: tracingCfg.TLSConfig.CertFile}) - } - if len(tracingCfg.TLSConfig.KeyFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "key_file", Value: tracingCfg.TLSConfig.KeyFile}) - } - if tracingCfg.TLSConfig.InsecureSkipVerify { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "insecure_skip_verify", Value: tracingCfg.TLSConfig.InsecureSkipVerify}) - } - if len(tracingCfg.TLSConfig.ServerName) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "server_name", Value: tracingCfg.TLSConfig.ServerName}) - } - cfg = append(cfg, yaml.MapItem{Key: "tls_config", Value: tlsCfg}) - } - if tracingCfg.Insecure { - cfg = append(cfg, yaml.MapItem{Key: "insecure", Value: true}) - } - if len(tracingCfg.ClientType) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "client_type", Value: tracingCfg.ClientType}) - } - if len(tracingCfg.SamplingFraction) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "sampling_fraction", Value: tracingCfg.SamplingFraction}) - } - if len(tracingCfg.Timeout) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "timeout", Value: tracingCfg.Timeout}) - } - if len(tracingCfg.Compression) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "compression", Value: tracingCfg.Compression}) - } - if len(tracingCfg.HTTPHeaders) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "http_headers", Value: tracingCfg.HTTPHeaders}) - } - cfg = append(cfg, yaml.MapItem{Key: "endpoint", Value: tracingCfg.Endpoint}) - return cfg, nil + var r rawValue + r.set("ca_file", tracingCfg.TLSConfig.CAFile) + r.set("cert_file", tracingCfg.TLSConfig.CertFile) + r.set("key_file", tracingCfg.TLSConfig.KeyFile) + r.set("insecure_skip_verify", tracingCfg.TLSConfig.InsecureSkipVerify) + r.set("server_name", tracingCfg.TLSConfig.ServerName) + cfg.items = append(cfg.items, yaml.MapItem{Key: "tls_config", Value: r.items}) + } + cfg.set("insecure", tracingCfg.Insecure) + cfg.set("client_type", tracingCfg.ClientType) + cfg.set("sampling_fraction", tracingCfg.SamplingFraction) + cfg.set("timeout", tracingCfg.Timeout) + cfg.set("compression", tracingCfg.Compression) + cfg.set("http_headers", tracingCfg.Headers) + cfg.set("endpoint", tracingCfg.Endpoint) + return cfg.items, nil } func parseURL(s string) error { @@ -1718,7 +1561,6 @@ func buildGossipConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCache) var cfg yaml.MapSlice gossipCfg := cr.Spec.GossipConfig if gossipCfg.TLSServerConfig != nil { - var tlsCfg yaml.MapSlice if gossipCfg.TLSServerConfig.ClientCASecretRef != nil { file, err := ac.LoadPathFromSecret(build.TLSAssetsResourceKind, cr.Namespace, gossipCfg.TLSServerConfig.ClientCASecretRef) if err != nil { @@ -1742,39 +1584,22 @@ func buildGossipConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCache) gossipCfg.TLSServerConfig.KeyFile = file } - if len(gossipCfg.TLSServerConfig.ClientCAFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "client_ca_file", Value: gossipCfg.TLSServerConfig.ClientCAFile}) - } - if len(gossipCfg.TLSServerConfig.CertFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cert_file", Value: gossipCfg.TLSServerConfig.CertFile}) - } - if len(gossipCfg.TLSServerConfig.KeyFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "key_file", Value: gossipCfg.TLSServerConfig.KeyFile}) - } - if len(gossipCfg.TLSServerConfig.CipherSuites) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cipher_suites", Value: gossipCfg.TLSServerConfig.CipherSuites}) - } - if len(gossipCfg.TLSServerConfig.CurvePreferences) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "curve_preferences", Value: gossipCfg.TLSServerConfig.CurvePreferences}) - } - if len(gossipCfg.TLSServerConfig.ClientAuthType) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "client_auth_type", Value: gossipCfg.TLSServerConfig.ClientAuthType}) - } - if gossipCfg.TLSServerConfig.PreferServerCipherSuites { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "prefer_server_cipher_suites", Value: gossipCfg.TLSServerConfig.PreferServerCipherSuites}) + var r rawValue + r.set("client_ca_file", gossipCfg.TLSServerConfig.ClientCAFile) + r.set("cert_file", gossipCfg.TLSServerConfig.CertFile) + r.set("key_file", gossipCfg.TLSServerConfig.KeyFile) + r.set("cipher_suites", gossipCfg.TLSServerConfig.CipherSuites) + r.set("curve_preferences", gossipCfg.TLSServerConfig.CurvePreferences) + r.set("client_auth_type", gossipCfg.TLSServerConfig.ClientAuthType) + if gossipCfg.TLSServerConfig.PreferServerCipherSuites != nil { + r.set("prefer_server_cipher_suites", *gossipCfg.TLSServerConfig.PreferServerCipherSuites) } - if len(gossipCfg.TLSServerConfig.MaxVersion) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "max_version", Value: gossipCfg.TLSServerConfig.MaxVersion}) - } - if len(gossipCfg.TLSServerConfig.MinVersion) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "min_version", Value: gossipCfg.TLSServerConfig.MinVersion}) - } - - cfg = append(cfg, yaml.MapItem{Key: "tls_server_config", Value: tlsCfg}) + r.set("max_version", gossipCfg.TLSServerConfig.MaxVersion) + r.set("min_version", gossipCfg.TLSServerConfig.MinVersion) + cfg = append(cfg, yaml.MapItem{Key: "tls_server_config", Value: r.items}) } if gossipCfg.TLSClientConfig != nil { - var tlsCfg yaml.MapSlice if gossipCfg.TLSClientConfig.CASecretRef != nil { file, err := ac.LoadPathFromSecret(build.TLSAssetsResourceKind, cr.Namespace, gossipCfg.TLSClientConfig.CASecretRef) if err != nil { @@ -1797,24 +1622,13 @@ func buildGossipConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCache) } gossipCfg.TLSClientConfig.KeyFile = file } - - if len(gossipCfg.TLSClientConfig.CAFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "ca_file", Value: gossipCfg.TLSClientConfig.CAFile}) - } - if len(gossipCfg.TLSClientConfig.CertFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cert_file", Value: gossipCfg.TLSClientConfig.CertFile}) - } - if len(gossipCfg.TLSClientConfig.KeyFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "key_file", Value: gossipCfg.TLSClientConfig.KeyFile}) - } - if gossipCfg.TLSClientConfig.InsecureSkipVerify { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "insecure_skip_verify", Value: gossipCfg.TLSClientConfig.InsecureSkipVerify}) - } - if len(gossipCfg.TLSClientConfig.ServerName) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "server_name", Value: gossipCfg.TLSClientConfig.ServerName}) - } - - cfg = append(cfg, yaml.MapItem{Key: "tls_client_config", Value: tlsCfg}) + var r rawValue + r.set("ca_file", gossipCfg.TLSClientConfig.CAFile) + r.set("cert_file", gossipCfg.TLSClientConfig.CertFile) + r.set("key_file", gossipCfg.TLSClientConfig.KeyFile) + r.set("insecure_skip_verify", gossipCfg.TLSClientConfig.InsecureSkipVerify) + r.set("server_name", gossipCfg.TLSClientConfig.ServerName) + cfg = append(cfg, yaml.MapItem{Key: "tls_client_config", Value: r.items}) } data, err := yaml.Marshal(cfg) if err != nil { @@ -1839,12 +1653,11 @@ func buildWebServerConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCach wCfg = append(wCfg, yaml.MapItem{Key: "http2", Value: webCfg.HTTPServerConfig.HTTP2}) } if len(webCfg.HTTPServerConfig.Headers) > 0 { - wCfg = append(wCfg, yaml.MapItem{Key: "headers", Value: orderedYAMLMAp(webCfg.HTTPServerConfig.Headers)}) + wCfg = append(wCfg, yaml.MapItem{Key: "headers", Value: orderedYAMLMap(webCfg.HTTPServerConfig.Headers)}) } cfg = append(cfg, yaml.MapItem{Key: "http_server_config", Value: wCfg}) } if webCfg.TLSServerConfig != nil { - var tlsCfg yaml.MapSlice if webCfg.TLSServerConfig.ClientCASecretRef != nil { file, err := ac.LoadPathFromSecret(build.TLSAssetsResourceKind, cr.Namespace, webCfg.TLSServerConfig.ClientCASecretRef) if err != nil { @@ -1868,39 +1681,23 @@ func buildWebServerConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCach webCfg.TLSServerConfig.KeyFile = file } - if len(webCfg.TLSServerConfig.ClientCAFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "client_ca_file", Value: webCfg.TLSServerConfig.ClientCAFile}) - } - if len(webCfg.TLSServerConfig.CertFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cert_file", Value: webCfg.TLSServerConfig.CertFile}) - } - if len(webCfg.TLSServerConfig.KeyFile) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "key_file", Value: webCfg.TLSServerConfig.KeyFile}) - } - if len(webCfg.TLSServerConfig.CipherSuites) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "cipher_suites", Value: webCfg.TLSServerConfig.CipherSuites}) + var r rawValue + r.set("client_ca_file", webCfg.TLSServerConfig.ClientCAFile) + r.set("cert_file", webCfg.TLSServerConfig.CertFile) + r.set("key_file", webCfg.TLSServerConfig.KeyFile) + r.set("cipher_suites", webCfg.TLSServerConfig.CipherSuites) + r.set("curve_preferences", webCfg.TLSServerConfig.CurvePreferences) + r.set("client_auth_type", webCfg.TLSServerConfig.ClientAuthType) + if webCfg.TLSServerConfig.PreferServerCipherSuites != nil { + r.set("prefer_server_cipher_suites", *webCfg.TLSServerConfig.PreferServerCipherSuites) } - if len(webCfg.TLSServerConfig.CurvePreferences) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "curve_preferences", Value: webCfg.TLSServerConfig.CurvePreferences}) - } - if len(webCfg.TLSServerConfig.ClientAuthType) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "client_auth_type", Value: webCfg.TLSServerConfig.ClientAuthType}) - } - if webCfg.TLSServerConfig.PreferServerCipherSuites { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "prefer_server_cipher_suites", Value: webCfg.TLSServerConfig.PreferServerCipherSuites}) - } - if len(webCfg.TLSServerConfig.MaxVersion) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "max_version", Value: webCfg.TLSServerConfig.MaxVersion}) - } - if len(webCfg.TLSServerConfig.MinVersion) > 0 { - tlsCfg = append(tlsCfg, yaml.MapItem{Key: "min_version", Value: webCfg.TLSServerConfig.MinVersion}) - } - - cfg = append(cfg, yaml.MapItem{Key: "tls_server_config", Value: tlsCfg}) + r.set("max_version", webCfg.TLSServerConfig.MaxVersion) + r.set("min_version", webCfg.TLSServerConfig.MinVersion) + cfg = append(cfg, yaml.MapItem{Key: "tls_server_config", Value: r.items}) } if len(webCfg.BasicAuthUsers) > 0 { - cfg = append(cfg, yaml.MapItem{Key: "basic_auth_users", Value: orderedYAMLMAp(webCfg.BasicAuthUsers)}) + cfg = append(cfg, yaml.MapItem{Key: "basic_auth_users", Value: orderedYAMLMap(webCfg.BasicAuthUsers)}) } data, err := yaml.Marshal(cfg) @@ -1910,7 +1707,7 @@ func buildWebServerConfigYAML(cr *vmv1beta1.VMAlertmanager, ac *build.AssetsCach return data, nil } -func orderedYAMLMAp(src map[string]string) yaml.MapSlice { +func orderedYAMLMap(src map[string]string) yaml.MapSlice { dstKeys := make([]string, 0, len(src)) for key := range src { dstKeys = append(dstKeys, key) diff --git a/internal/controller/operator/factory/vmalertmanager/config_test.go b/internal/controller/operator/factory/vmalertmanager/config_test.go index 82678a224..4bf799739 100644 --- a/internal/controller/operator/factory/vmalertmanager/config_test.go +++ b/internal/controller/operator/factory/vmalertmanager/config_test.go @@ -36,7 +36,6 @@ func TestBuildConfig(t *testing.T) { predefinedObjects []runtime.Object want string parseError string - wantErr bool } f := func(o opts) { t.Helper() @@ -55,10 +54,6 @@ func TestBuildConfig(t *testing.T) { ctx := context.TODO() ac := getAssetsCache(ctx, testClient, o.cr) got, data, err := buildAlertmanagerConfigWithCRDs(ctx, testClient, o.cr, o.baseCfg, ac) - if o.wantErr { - assert.Error(t, err) - return - } assert.NoError(t, err) broken := got.configs.Broken() if len(broken) > 0 { @@ -88,7 +83,7 @@ func TestBuildConfig(t *testing.T) { }, }, Compression: "gzip", - HTTPHeaders: map[string]string{ + Headers: map[string]string{ "name": "value", }, }, @@ -148,7 +143,7 @@ tracing: }, }, Compression: "gzip", - HTTPHeaders: map[string]string{ + Headers: map[string]string{ "name": "value", }, }, @@ -250,6 +245,7 @@ tracing: baseCfg: []byte(`global: time_out: 1min smtp_smarthost: some:443 +templates: [] `), predefinedObjects: []runtime.Object{ &vmv1beta1.VMAlertmanagerConfig{ @@ -323,12 +319,10 @@ route: - pod=dev-env group_wait: 10min receiver: default-base-email - continue: false matchers: - team=prod group_wait: 5min receiver: default-base-email-sub-1 - continue: false matchers: - env=~{"dev|prod"} - pod!="" @@ -478,6 +472,7 @@ templates: [] baseCfg: []byte(`global: time_out: 1min opsgenie_api_key: some-key +templates: [] `), predefinedObjects: []runtime.Object{ &vmv1beta1.VMAlertmanagerConfig{ @@ -571,7 +566,6 @@ route: routes: - routes: - receiver: default-base-webhook - continue: false matchers: - namespace = "default" group_wait: 1min @@ -701,6 +695,20 @@ templates: [] Receivers: []vmv1beta1.Receiver{ { Name: "slack", + MattermostConfigs: []vmv1beta1.MattermostConfig{ + { + URL: ptr.To("http://mattermost:8080"), + SendResolved: ptr.To(true), + Attachments: []*vmv1beta1.MattermostAttachment{{ + Text: "test", + Fields: []vmv1beta1.MattermostField{{ + Title: "main", + Value: "value", + Short: true, + }}, + }}, + }, + }, SlackConfigs: []vmv1beta1.SlackConfig{ { APIURL: &corev1.SecretKeySelector{ @@ -788,6 +796,15 @@ receivers: - value: test title: fields short: true + mattermost_configs: + - send_resolved: true + webhook_url: http://mattermost:8080 + attachments: + - text: test + fields: + - title: main + value: value + short: true templates: [] `, }) @@ -1070,9 +1087,9 @@ templates: [] // jira section f(opts{ baseCfg: []byte(`global: - time_out: 1min smtp_smarthost: some:443 jira_api_url: "https://jira.cloud" + time_out: 1min `), predefinedObjects: []runtime.Object{ &corev1.Secret{ @@ -1195,8 +1212,8 @@ templates: [] }, }, want: `global: - jira_api_url: https://jira.cloud smtp_smarthost: some:443 + jira_api_url: https://jira.cloud time_out: 1min route: receiver: blackhole @@ -1360,7 +1377,7 @@ templates: [] Receivers: []vmv1beta1.Receiver{ { Name: "incidentio", - IncidentIOConfigs: []vmv1beta1.IncidentIOConfig{ + IncidentioConfigs: []vmv1beta1.IncidentioConfig{ { URL: "http://example.com/", AlertSourceToken: &corev1.SecretKeySelector{ @@ -1487,21 +1504,19 @@ templates: [] func TestAddConfigTemplates(t *testing.T) { type opts struct { - config []byte + config string templates []string want string - wantErr bool } f := func(o opts) { t.Helper() - got, err := addConfigTemplates(o.config, o.templates) - if o.wantErr { - assert.Error(t, err) - return - } + var baseCfg amConfig + assert.NoError(t, yaml.Unmarshal([]byte(o.config), &baseCfg)) + addConfigTemplates(&baseCfg, o.templates) + data, err := yaml.Marshal(&baseCfg) assert.NoError(t, err) - assert.Equal(t, o.want, string(got)) + assert.Equal(t, o.want, string(data)) } // add templates to empty config @@ -1514,7 +1529,7 @@ func TestAddConfigTemplates(t *testing.T) { // add templates to config without templates f(opts{ - config: []byte(`global: + config: `global: resolve_timeout: 5m route: receiver: webhook @@ -1525,7 +1540,7 @@ receivers: - name: webhook webhook_configs: - url: http://localhost:30500/ -`), +`, templates: []string{ "/etc/vm/templates/test/template1.tmpl", "/etc/vm/templates/test/template2.tmpl", @@ -1549,7 +1564,7 @@ templates: // add templates to config with templates f(opts{ - config: []byte(`global: + config: `global: resolve_timeout: 5m route: receiver: webhook @@ -1563,7 +1578,7 @@ receivers: templates: - /etc/vm/templates/test/template1.tmpl - /etc/vm/templates/test/template2.tmpl -`), +`, templates: []string{ "/etc/vm/templates/test/template3.tmpl", "/etc/vm/templates/test/template4.tmpl", @@ -1605,21 +1620,18 @@ templates: // add empty templates list f(opts{ - config: []byte(`test`), + config: `global: + test: test`, templates: []string{}, - want: `test`, - }) - - // wrong config - f(opts{ - config: []byte(`test`), - templates: []string{"test"}, - wantErr: true, + want: `global: + test: test +templates: [] +`, }) // add template duplicates without path f(opts{ - config: []byte(`global: + config: `global: resolve_timeout: 5m route: receiver: webhook @@ -1634,7 +1646,7 @@ templates: - template1.tmpl - template2.tmpl - /etc/vm/templates/test/template3.tmpl -`), +`, templates: []string{ "/etc/vm/templates/test/template1.tmpl", "/etc/vm/templates/test/template2.tmpl", @@ -1665,7 +1677,6 @@ func Test_configBuilder_buildHTTPConfig(t *testing.T) { httpCfg *vmv1beta1.HTTPConfig predefinedObjects []runtime.Object want string - wantErr bool } f := func(o opts) { t.Helper() @@ -1676,15 +1687,8 @@ func Test_configBuilder_buildHTTPConfig(t *testing.T) { Namespace: "default", }, } - cb := &configBuilder{ - cache: getAssetsCache(context.Background(), testClient, cr), - namespace: cr.Namespace, - } - gotYAML, err := cb.buildHTTPConfig(o.httpCfg) - if o.wantErr { - assert.Error(t, err) - return - } + ac := getAssetsCache(context.Background(), testClient, cr) + gotYAML, err := buildHTTPConfig(o.httpCfg, cr.Namespace, ac) assert.NoError(t, err) got, err := yaml.Marshal(gotYAML) assert.NoError(t, err) @@ -1962,7 +1966,6 @@ authorization: func Test_UpdateDefaultAMConfig(t *testing.T) { type opts struct { cr *vmv1beta1.VMAlertmanager - wantErr bool predefinedObjects []runtime.Object secretMustBeMissing bool } @@ -1973,12 +1976,7 @@ func Test_UpdateDefaultAMConfig(t *testing.T) { ctx := context.TODO() // Create secret with alert manager config - err := CreateOrUpdateConfig(ctx, fclient, o.cr, nil) - if o.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } + assert.NoError(t, CreateOrUpdateConfig(ctx, fclient, o.cr, nil)) var amCfgs []*vmv1beta1.VMAlertmanagerConfig opts := &k8stools.SelectorOpts{ SelectAll: o.cr.Spec.SelectAllByDefault, @@ -2010,7 +2008,7 @@ func Test_UpdateDefaultAMConfig(t *testing.T) { // check secret config after creating d, ok := createdSecret.Data[alertmanagerSecretConfigKeyGz] assert.True(t, ok) - var secretConfig alertmanagerConfig + var secretConfig amConfig data, err := build.GunzipConfig(d) assert.NoError(t, err) assert.NoError(t, yaml.Unmarshal(data, &secretConfig)) @@ -2022,12 +2020,7 @@ func Test_UpdateDefaultAMConfig(t *testing.T) { assert.Len(t, secretConfig.Route.Routes, 1) assert.Len(t, secretConfig.Route.Routes[0], len(amc.Spec.Route.Routes)+2) // Update secret with alert manager config - err = CreateOrUpdateConfig(ctx, fclient, o.cr, nil) - if o.wantErr { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } + assert.NoError(t, CreateOrUpdateConfig(ctx, fclient, o.cr, nil)) if err := fclient.Get(ctx, types.NamespacedName{Namespace: o.cr.Namespace, Name: secretName}, &createdSecret); err != nil { if k8serrors.IsNotFound(err) && o.secretMustBeMissing { @@ -2120,7 +2113,6 @@ func TestBuildWebConfig(t *testing.T) { cr *vmv1beta1.VMAlertmanager predefinedObjects []runtime.Object want string - wantErr bool } f := func(o opts) { t.Helper() @@ -2128,10 +2120,6 @@ func TestBuildWebConfig(t *testing.T) { ctx := context.TODO() ac := getAssetsCache(ctx, fclient, o.cr) c, err := buildWebServerConfigYAML(o.cr, ac) - if o.wantErr { - assert.Error(t, err) - return - } assert.NoError(t, err) assert.Equal(t, o.want, string(c)) } diff --git a/internal/controller/operator/factory/vmalertmanager/statefulset.go b/internal/controller/operator/factory/vmalertmanager/statefulset.go index 68685ec9e..1d6e11b08 100644 --- a/internal/controller/operator/factory/vmalertmanager/statefulset.go +++ b/internal/controller/operator/factory/vmalertmanager/statefulset.go @@ -509,19 +509,6 @@ func CreateOrUpdateConfig(ctx context.Context, rclient client.Client, cr *vmv1be return fmt.Errorf("cannot build gossip config: %w", err) } - // add templates from CR to alermanager config - if len(cr.Spec.Templates) > 0 { - templatePaths := make([]string, 0, len(cr.Spec.Templates)) - for _, template := range cr.Spec.Templates { - templatePaths = append(templatePaths, path.Join(templatesDir, template.Name, template.Key)) - } - mergedCfg, err := addConfigTemplates(alertmanagerConfig, templatePaths) - if err != nil { - return fmt.Errorf("cannot build alertmanager config with templates, err: %w", err) - } - alertmanagerConfig = mergedCfg - } - if err := vmv1beta1.ValidateAlertmanagerConfigSpec(alertmanagerConfig); err != nil { return fmt.Errorf("incorrect result configuration, config source=%s: %w", configSourceName, err) } From 0fddb662813b5b64c227f926f5ce7a2ebc7c0bee Mon Sep 17 00:00:00 2001 From: Vadim Rutkovsky Date: Wed, 22 Apr 2026 08:45:57 +0200 Subject: [PATCH 4/5] fix: add default scrape class verification for VMSingle --- api/operator/v1beta1/vmsingle_types.go | 15 ++++++ api/operator/v1beta1/vmsingle_types_test.go | 55 +++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 api/operator/v1beta1/vmsingle_types_test.go diff --git a/api/operator/v1beta1/vmsingle_types.go b/api/operator/v1beta1/vmsingle_types.go index c5d263929..33ddfd3ff 100644 --- a/api/operator/v1beta1/vmsingle_types.go +++ b/api/operator/v1beta1/vmsingle_types.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -376,6 +377,20 @@ func (cr *VMSingle) Validate() error { return err } } + scrapeClassNames := sets.New[string]() + defaultScrapeClass := false + for _, sc := range cr.Spec.ScrapeClasses { + if scrapeClassNames.Has(sc.Name) { + return fmt.Errorf("duplicated scrapeClass=%q", sc.Name) + } + scrapeClassNames.Insert(sc.Name) + if ptr.Deref(sc.Default, false) { + if defaultScrapeClass { + return fmt.Errorf("multiple default scrape classes defined") + } + defaultScrapeClass = true + } + } if cr.Spec.StorageDataPath != "" { if len(cr.Spec.Volumes) == 0 { return fmt.Errorf("spec.volumes must have at least 1 value for spec.storageDataPath=%q", cr.Spec.StorageDataPath) diff --git a/api/operator/v1beta1/vmsingle_types_test.go b/api/operator/v1beta1/vmsingle_types_test.go new file mode 100644 index 000000000..696a1e769 --- /dev/null +++ b/api/operator/v1beta1/vmsingle_types_test.go @@ -0,0 +1,55 @@ +package v1beta1 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/utils/ptr" +) + +func TestVMSingle_Validate(t *testing.T) { + f := func(spec VMSingleSpec, wantErr bool) { + t.Helper() + r := &VMSingle{ + Spec: spec, + } + if wantErr { + assert.Error(t, r.Validate()) + } else { + assert.NoError(t, r.Validate()) + } + } + + // no scrape classes + f(VMSingleSpec{}, false) + + // single default scrape class + f(VMSingleSpec{ + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "default", Default: ptr.To(true)}, + {Name: "other"}, + }, + }, + }, false) + + // multiple default scrape classes + f(VMSingleSpec{ + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "default", Default: ptr.To(true)}, + {Name: "other", Default: ptr.To(true)}, + }, + }, + }, true) + + // duplicated scrape class names + f(VMSingleSpec{ + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "cls"}, + {Name: "cls"}, + }, + }, + }, true) +} From 7b7441aedcfddabf2d3dcca14cb5d7054ec5d5ec Mon Sep 17 00:00:00 2001 From: Vadim Rutkovsky Date: Wed, 22 Apr 2026 08:47:18 +0200 Subject: [PATCH 5/5] fix: update vmagent defautl scrape class selection using sets, add tests --- api/operator/v1beta1/vmagent_types.go | 6 ++-- api/operator/v1beta1/vmagent_types_test.go | 34 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/api/operator/v1beta1/vmagent_types.go b/api/operator/v1beta1/vmagent_types.go index c50939d69..ee6361fe7 100644 --- a/api/operator/v1beta1/vmagent_types.go +++ b/api/operator/v1beta1/vmagent_types.go @@ -11,6 +11,7 @@ import ( "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -197,12 +198,13 @@ func (cr *VMAgent) Validate() error { return err } } - scrapeClassNames := make(map[string]struct{}) + scrapeClassNames := sets.New[string]() defaultScrapeClass := false for _, sc := range cr.Spec.ScrapeClasses { - if _, ok := scrapeClassNames[sc.Name]; ok { + if scrapeClassNames.Has(sc.Name) { return fmt.Errorf("duplicated scrapeClass=%q", sc.Name) } + scrapeClassNames.Insert(sc.Name) if ptr.Deref(sc.Default, false) { if defaultScrapeClass { return fmt.Errorf("multiple default scrape classes defined") diff --git a/api/operator/v1beta1/vmagent_types_test.go b/api/operator/v1beta1/vmagent_types_test.go index 48455a5db..ba88cdc45 100644 --- a/api/operator/v1beta1/vmagent_types_test.go +++ b/api/operator/v1beta1/vmagent_types_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "k8s.io/utils/ptr" ) func TestVMAgent_Validate(t *testing.T) { @@ -69,4 +70,37 @@ func TestVMAgent_Validate(t *testing.T) { }, }, }, false) + + // single default scrape class - valid + f(VMAgentSpec{ + RemoteWrite: []VMAgentRemoteWriteSpec{{URL: "http://some-rw"}}, + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "default", Default: ptr.To(true)}, + {Name: "other"}, + }, + }, + }, false) + + // multiple default scrape classes - invalid + f(VMAgentSpec{ + RemoteWrite: []VMAgentRemoteWriteSpec{{URL: "http://some-rw"}}, + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "default", Default: ptr.To(true)}, + {Name: "other", Default: ptr.To(true)}, + }, + }, + }, true) + + // duplicated scrape class names - invalid + f(VMAgentSpec{ + RemoteWrite: []VMAgentRemoteWriteSpec{{URL: "http://some-rw"}}, + CommonScrapeParams: CommonScrapeParams{ + ScrapeClasses: []ScrapeClass{ + {Name: "cls"}, + {Name: "cls"}, + }, + }, + }, true) }