diff --git a/Makefile b/Makefile index aded3e52..cc78d785 100644 --- a/Makefile +++ b/Makefile @@ -54,14 +54,6 @@ endif all: build -gen-client: - client-gen --go-header-file hack/boilerplate.go.txt \ - --input-base=""\ - --input=$(REPO)/api/v1beta1 \ - --clientset-name "versioned" \ - --output-package=$(REPO)/pkg/client \ - --output-base "" - cp -R $(REPO)/pkg/client ./pkg install-golint: which golint || GO111MODULE=off go get -u golang.org/x/lint/golint @@ -178,7 +170,7 @@ vet: # Generate code generate: controller-gen - $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./.../api" + $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..." # Build the docker image docker-build: test diff --git a/README.md b/README.md index 4f8fb185..18d9593f 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,10 @@ ## Documentation - quick start [doc](/docs/quick-start.MD) -- design and description of implementation [design](/docs/design.MD) - high availability [doc](/docs/high-availability.MD) +- relabeling configuration [doc](/docs/relabeling.MD) +- managing crd objects versions [doc](/docs/managing-versions.MD) +- design and description of implementation [design](/docs/design.MD) - operator objects description [doc](/docs/api.MD) diff --git a/api/v1beta1/additional.go b/api/v1beta1/additional.go index 64f05ddf..04aa413f 100644 --- a/api/v1beta1/additional.go +++ b/api/v1beta1/additional.go @@ -83,11 +83,11 @@ type EmbeddedPersistentVolumeClaim struct { // More info: https://prometheus.io/docs/operating/configuration/#endpoints // +k8s:openapi-gen=true type BasicAuth struct { - // The secret in the service monitor namespace that contains the username + // The secret in the service scrape namespace that contains the username // for authentication. // +optional Username v1.SecretKeySelector `json:"username,omitempty"` - // The secret in the service monitor namespace that contains the password + // The secret in the service scrape namespace that contains the password // for authentication. // +optional Password v1.SecretKeySelector `json:"password,omitempty"` diff --git a/api/v1beta1/vmagent_types.go b/api/v1beta1/vmagent_types.go index dc675e3d..e9faa1e5 100644 --- a/api/v1beta1/vmagent_types.go +++ b/api/v1beta1/vmagent_types.go @@ -18,15 +18,12 @@ type VMAgentSpec struct { // PodMetadata configures Labels and Annotations which are propagated to the vmagent pods. // +optional PodMetadata *EmbeddedObjectMetadata `json:"podMetadata,omitempty"` - // Image - victoria metrics agent base image - // if not specified - use default from operator config + // Image - docker image settings for VMAgent + // if no specified operator uses default config version // +optional - Image *string `json:"image,omitempty"` - // Version for VMAgent. - // +optional - Version string `json:"version,omitempty"` - // ImagePullSecrets optional list of references to secrets in the same namespace - // to use for pulling prometheus and vmagent images from registries + Image Image `json:"image,omitempty"` + // ImagePullSecrets An optional list of references to secrets in the same namespace + // to use for pulling images from registries // see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod // +optional ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"` @@ -121,7 +118,7 @@ type VMAgentSpec struct { // +optional APIServerConfig *APIServerConfig `json:"aPIServerConfig,omitempty"` // OverrideHonorLabels if set to true overrides all user configured honor_labels. - // If HonorLabels is set in ServiceMonitor or PodMonitor to true, this overrides honor_labels to false. + // If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. // +optional OverrideHonorLabels bool `json:"overrideHonorLabels,omitempty"` // OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. @@ -142,11 +139,6 @@ type VMAgentSpec struct { // _not_ be added when value is set to empty string (`""`). // +optional VMAgentExternalLabelName *string `json:"vmAgentExternalLabelName,omitempty"` - // ReplicaExternalLabelName Name of vmagent external label used to denote replica name. - // Defaults to the value of `prometheus_replica`. External label will - // _not_ be added when value is set to empty string (`""`). - // +optional - ReplicaExternalLabelName *string `json:"replicaExternalLabelName,omitempty"` // ExternalLabels The labels to add to any time series or alerts when communicating with // external systems (federation, remote storage, etc). @@ -162,24 +154,24 @@ type VMAgentSpec struct { // This relabeling is applied to all the collected metrics before sending them to remote storage. // +optional RelabelConfig *v1.ConfigMapKeySelector `json:"relabelConfig,omitempty"` - // ServiceMonitorSelector defines ServiceMonitors to be selected for target discovery. if - // neither this nor podMonitorSelector are specified, configuration is + // ServiceScrapeSelector defines ServiceScrapes to be selected for target discovery. if + // neither serviceScrapeNamespaceSelector nor serviceScrapeSelector are specified, configuration is // unmanaged. // +optional - ServiceMonitorSelector *metav1.LabelSelector `json:"serviceMonitorSelector,omitempty"` - // ServiceMonitorNamespaceSelector Namespaces to be selected for ServiceMonitor discovery. If nil, only + ServiceScrapeSelector *metav1.LabelSelector `json:"serviceScrapeSelector,omitempty"` + // ServiceScrapeNamespaceSelector Namespaces to be selected for ServiceMonitor discovery. If nil, only // check own namespace. // +optional - ServiceMonitorNamespaceSelector *metav1.LabelSelector `json:"serviceMonitorNamespaceSelector,omitempty"` - // PodMonitorSelector defines PodMonitors to be selected for target discovery. - // if neither this nor serviceMonitorSelector are specified, + ServiceScrapeNamespaceSelector *metav1.LabelSelector `json:"serviceScrapeNamespaceSelector,omitempty"` + // PodScrapeSelector defines PodScrapes to be selected for target discovery. + // if neither PodScrapeNamespaceSelector this nor PodScrapeSelector are specified, // configuration is unmanaged. // +optional - PodMonitorSelector *metav1.LabelSelector `json:"podMonitorSelector,omitempty"` - // PodMonitorNamespaceSelector defines Namespaces to be selected for PodMonitor discovery. If nil, only + PodScrapeSelector *metav1.LabelSelector `json:"podScrapeSelector,omitempty"` + // PodScrapeNamespaceSelector defines Namespaces to be selected for PodMonitor discovery. If nil, only // check own namespace. // +optional - PodMonitorNamespaceSelector *metav1.LabelSelector `json:"podMonitorNamespaceSelector,omitempty"` + PodScrapeNamespaceSelector *metav1.LabelSelector `json:"podScrapeNamespaceSelector,omitempty"` // AdditionalScrapeConfigs As scrape configs are appended, the user is responsible to make sure it // is valid. Note that using this feature may expose the possibility to // break upgrades of VMAgent. It is advised to review VMAgent release @@ -188,7 +180,7 @@ type VMAgentSpec struct { // +optional AdditionalScrapeConfigs *v1.SecretKeySelector `json:"additionalScrapeConfigs,omitempty"` // ArbitraryFSAccessThroughSMs configures whether configuration - // based on a service monitor can access arbitrary files on the file system + // based on a service scrape can access arbitrary files on the file system // of the VMAgent container e.g. bearer token files. // +optional ArbitraryFSAccessThroughSMs ArbitraryFSAccessThroughSMsConfig `json:"arbitraryFSAccessThroughSMs,omitempty"` diff --git a/api/v1beta1/vmalert_types.go b/api/v1beta1/vmalert_types.go index 7e444928..4add88d4 100644 --- a/api/v1beta1/vmalert_types.go +++ b/api/v1beta1/vmalert_types.go @@ -17,15 +17,16 @@ import ( type VMAlertSpec struct { // PodMetadata configures Labels and Annotations which are propagated to the VMAlert pods. PodMetadata *EmbeddedObjectMetadata `json:"podMetadata,omitempty"` - // Image victoria metrics alert base image + // Image - docker image settings for VMAlert + // if no specified operator uses default config version // +optional - Image *string `json:"image,omitempty"` - // Version the VMAlert should be on. - Version string `json:"version,omitempty"` + Image Image `json:"image,omitempty"` // ImagePullSecrets An optional list of references to secrets in the same namespace - // to use for pulling prometheus and VMAlert images from registries + // to use for pulling images from registries // see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + // +optional ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"` + // Secrets is a list of Secrets in the same namespace as the VMAlert // object, which shall be mounted into the VMAlert Pods. // The Secrets are mounted into /etc/vmalert/secrets/. diff --git a/api/v1beta1/vmalertmanager_types.go b/api/v1beta1/vmalertmanager_types.go index 98c06e0c..351e7de6 100644 --- a/api/v1beta1/vmalertmanager_types.go +++ b/api/v1beta1/vmalertmanager_types.go @@ -40,25 +40,12 @@ type VMAlertmanagerSpec struct { // PodMetadata configures Labels and Annotations which are propagated to the alertmanager pods. // +optional PodMetadata *EmbeddedObjectMetadata `json:"podMetadata,omitempty"` - // Image if specified has precedence over baseImage, tag and sha - // combinations. - // +optional - Image *string `json:"image,omitempty"` - // Version the cluster should be on. - // +optional - Version string `json:"version,omitempty"` - // Tag of VMAlertmanager container image to be deployed. Defaults to the value of `version`. - // Version is ignored if Tag is set. - // +optional - Tag string `json:"tag,omitempty"` - // SHA of VMAlertmanager container image to be deployed. Defaults to the value of `version`. - // Similar to a tag, but the SHA explicitly deploys an immutable container image. - // Version and Tag are ignored if SHA is set. - // +optional - SHA string `json:"sha,omitempty"` - // BaseImage that is used to deploy pods, without tag. + + // Image - docker image settings for VMAlertmanager + // if no specified operator uses default config version // +optional - BaseImage string `json:"baseImage,omitempty"` + Image Image `json:"image,omitempty"` + // ImagePullSecrets An optional list of references to secrets in the same namespace // to use for pulling images from registries // see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod diff --git a/api/v1beta1/vmcluster_types.go b/api/v1beta1/vmcluster_types.go index c419c8d7..f392d339 100644 --- a/api/v1beta1/vmcluster_types.go +++ b/api/v1beta1/vmcluster_types.go @@ -485,13 +485,13 @@ type VMBackup struct { // Defines if monthly backups disabled (default false) // +optional DisableMonthly *bool `json:"disableMonthly,omitempty"` - // Image - docker image settings for VMBackyper + // Image - docker image settings for VMBackuper // +optional Image Image `json:"image,omitempty"` - //Port for health check connetions + //Port for health check connections Port string `json:"port,omitempty"` // LogFormat for VMSelect to be configured with. - //default or json + // default or json // +optional // +kubebuilder:validation:Enum=default;json LogFormat *string `json:"logFormat,omitempty"` @@ -625,14 +625,14 @@ func (cr VMCluster) VMInsertPodAnnotations() map[string]string { if cr.Spec.VMInsert == nil || cr.Spec.VMInsert.PodMetadata == nil { return nil } - return cr.Spec.VMSelect.PodMetadata.Annotations + return cr.Spec.VMInsert.PodMetadata.Annotations } func (cr VMCluster) VMStoragePodAnnotations() map[string]string { if cr.Spec.VMStorage == nil || cr.Spec.VMStorage.PodMetadata == nil { return nil } - return cr.Spec.VMSelect.PodMetadata.Annotations + return cr.Spec.VMStorage.PodMetadata.Annotations } func (cr VMCluster) Annotations() map[string]string { diff --git a/api/v1beta1/vmpodscrape_types.go b/api/v1beta1/vmpodscrape_types.go index b2ed8ce4..2264b54c 100644 --- a/api/v1beta1/vmpodscrape_types.go +++ b/api/v1beta1/vmpodscrape_types.go @@ -101,10 +101,10 @@ type PodMetricsEndpoint struct { } // ArbitraryFSAccessThroughSMsConfig enables users to configure, whether -// a service monitor selected by the vmagent instance is allowed to use +// a service scrape selected by the vmagent instance is allowed to use // arbitrary files on the file system of the vmagent container. This is the case // when e.g. a service scrape specifies a BearerTokenFile in an endpoint. A -// malicious user could create a service monitor selecting arbitrary secret files +// malicious user could create a service scrape selecting arbitrary secret files // 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. diff --git a/api/v1beta1/vmservicescrape_types.go b/api/v1beta1/vmservicescrape_types.go index d0b5453a..dc3f4b4a 100644 --- a/api/v1beta1/vmservicescrape_types.go +++ b/api/v1beta1/vmservicescrape_types.go @@ -18,7 +18,7 @@ type VMServiceScrapeSpec struct { // PodTargetLabels transfers labels on the Kubernetes Pod onto the target. // +optional PodTargetLabels []string `json:"podTargetLabels,omitempty"` - // A list of endpoints allowed as part of this ServiceMonitor. + // A list of endpoints allowed as part of this ServiceScrape. Endpoints []Endpoint `json:"endpoints"` // Selector to select Endpoints objects. // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true @@ -107,7 +107,7 @@ type Endpoint struct { // +optional BearerTokenFile string `json:"bearerTokenFile,omitempty"` // Secret to mount to read bearer token for scraping targets. The secret - // needs to be in the same namespace as the service monitor and accessible by + // needs to be in the same namespace as the service scrape and accessible by // the victoria-metrics operator. // +optional BearerTokenSecret v1.SecretKeySelector `json:"bearerTokenSecret,omitempty"` diff --git a/api/v1beta1/vmsingle_types.go b/api/v1beta1/vmsingle_types.go index 77eaf648..504af12e 100644 --- a/api/v1beta1/vmsingle_types.go +++ b/api/v1beta1/vmsingle_types.go @@ -18,12 +18,10 @@ type VMSingleSpec struct { // PodMetadata configures Labels and Annotations which are propagated to the VMSingle pods. // +optional PodMetadata *EmbeddedObjectMetadata `json:"podMetadata,omitempty"` - // Image victoria metrics single base image + // Image - docker image settings for VMSingle + // if no specified operator uses default config version // +optional - Image *string `json:"image,omitempty"` - // Version of victoria metrics single - // +optional - Version string `json:"version,omitempty"` + Image Image `json:"image,omitempty"` // ImagePullSecrets An optional list of references to secrets in the same namespace // to use for pulling images from registries // see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index d32c4d6d..accd2928 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -213,7 +213,6 @@ func (in *Endpoint) DeepCopy() *Endpoint { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Image) DeepCopyInto(out *Image) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image. @@ -654,6 +653,11 @@ func (in *VMAgentRemoteWriteSpec) DeepCopyInto(out *VMAgentRemoteWriteSpec) { *out = new(string) **out = **in } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAgentRemoteWriteSpec. @@ -674,11 +678,7 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(EmbeddedObjectMetadata) (*in).DeepCopyInto(*out) } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(string) - **out = **in - } + out.Image = in.Image if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets *out = make([]v1.LocalObjectReference, len(*in)) @@ -755,11 +755,6 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(string) **out = **in } - if in.ReplicaExternalLabelName != nil { - in, out := &in.ReplicaExternalLabelName, &out.ReplicaExternalLabelName - *out = new(string) - **out = **in - } if in.ExternalLabels != nil { in, out := &in.ExternalLabels, &out.ExternalLabels *out = make(map[string]string, len(*in)) @@ -779,23 +774,23 @@ func (in *VMAgentSpec) DeepCopyInto(out *VMAgentSpec) { *out = new(v1.ConfigMapKeySelector) (*in).DeepCopyInto(*out) } - if in.ServiceMonitorSelector != nil { - in, out := &in.ServiceMonitorSelector, &out.ServiceMonitorSelector + if in.ServiceScrapeSelector != nil { + in, out := &in.ServiceScrapeSelector, &out.ServiceScrapeSelector *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } - if in.ServiceMonitorNamespaceSelector != nil { - in, out := &in.ServiceMonitorNamespaceSelector, &out.ServiceMonitorNamespaceSelector + if in.ServiceScrapeNamespaceSelector != nil { + in, out := &in.ServiceScrapeNamespaceSelector, &out.ServiceScrapeNamespaceSelector *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } - if in.PodMonitorSelector != nil { - in, out := &in.PodMonitorSelector, &out.PodMonitorSelector + if in.PodScrapeSelector != nil { + in, out := &in.PodScrapeSelector, &out.PodScrapeSelector *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } - if in.PodMonitorNamespaceSelector != nil { - in, out := &in.PodMonitorNamespaceSelector, &out.PodMonitorNamespaceSelector + if in.PodScrapeNamespaceSelector != nil { + in, out := &in.PodScrapeNamespaceSelector, &out.PodScrapeNamespaceSelector *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } @@ -881,6 +876,11 @@ func (in *VMAlertDatasourceSpec) DeepCopyInto(out *VMAlertDatasourceSpec) { *out = new(BasicAuth) (*in).DeepCopyInto(*out) } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAlertDatasourceSpec. @@ -925,6 +925,31 @@ func (in *VMAlertList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VMAlertNotifierSpec) DeepCopyInto(out *VMAlertNotifierSpec) { + *out = *in + if in.BasicAuth != nil { + in, out := &in.BasicAuth, &out.BasicAuth + *out = new(BasicAuth) + (*in).DeepCopyInto(*out) + } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAlertNotifierSpec. +func (in *VMAlertNotifierSpec) DeepCopy() *VMAlertNotifierSpec { + if in == nil { + return nil + } + out := new(VMAlertNotifierSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VMAlertRemoteReadSpec) DeepCopyInto(out *VMAlertRemoteReadSpec) { *out = *in @@ -938,6 +963,11 @@ func (in *VMAlertRemoteReadSpec) DeepCopyInto(out *VMAlertRemoteReadSpec) { *out = new(string) **out = **in } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAlertRemoteReadSpec. @@ -978,6 +1008,11 @@ func (in *VMAlertRemoteWriteSpec) DeepCopyInto(out *VMAlertRemoteWriteSpec) { *out = new(int32) **out = **in } + if in.TLSConfig != nil { + in, out := &in.TLSConfig, &out.TLSConfig + *out = new(TLSConfig) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMAlertRemoteWriteSpec. @@ -998,11 +1033,7 @@ func (in *VMAlertSpec) DeepCopyInto(out *VMAlertSpec) { *out = new(EmbeddedObjectMetadata) (*in).DeepCopyInto(*out) } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(string) - **out = **in - } + out.Image = in.Image if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets *out = make([]v1.LocalObjectReference, len(*in)) @@ -1079,6 +1110,7 @@ func (in *VMAlertSpec) DeepCopyInto(out *VMAlertSpec) { *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } + in.Notifier.DeepCopyInto(&out.Notifier) if in.RemoteWrite != nil { in, out := &in.RemoteWrite, &out.RemoteWrite *out = new(VMAlertRemoteWriteSpec) @@ -1207,11 +1239,7 @@ func (in *VMAlertmanagerSpec) DeepCopyInto(out *VMAlertmanagerSpec) { *out = new(EmbeddedObjectMetadata) (*in).DeepCopyInto(*out) } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(string) - **out = **in - } + out.Image = in.Image if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets *out = make([]v1.LocalObjectReference, len(*in)) @@ -1322,6 +1350,75 @@ func (in *VMAlertmanagerStatus) DeepCopy() *VMAlertmanagerStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VMBackup) DeepCopyInto(out *VMBackup) { + *out = *in + if in.Concurrency != nil { + in, out := &in.Concurrency, &out.Concurrency + *out = new(int32) + **out = **in + } + if in.CustomS3Endpoint != nil { + in, out := &in.CustomS3Endpoint, &out.CustomS3Endpoint + *out = new(string) + **out = **in + } + if in.CredentialsSecret != nil { + in, out := &in.CredentialsSecret, &out.CredentialsSecret + *out = new(v1.SecretKeySelector) + (*in).DeepCopyInto(*out) + } + if in.DisableHourly != nil { + in, out := &in.DisableHourly, &out.DisableHourly + *out = new(bool) + **out = **in + } + if in.DisableDaily != nil { + in, out := &in.DisableDaily, &out.DisableDaily + *out = new(bool) + **out = **in + } + if in.DisableWeekly != nil { + in, out := &in.DisableWeekly, &out.DisableWeekly + *out = new(bool) + **out = **in + } + if in.DisableMonthly != nil { + in, out := &in.DisableMonthly, &out.DisableMonthly + *out = new(bool) + **out = **in + } + out.Image = in.Image + if in.LogFormat != nil { + in, out := &in.LogFormat, &out.LogFormat + *out = new(string) + **out = **in + } + if in.LogLevel != nil { + in, out := &in.LogLevel, &out.LogLevel + *out = new(string) + **out = **in + } + in.Resources.DeepCopyInto(&out.Resources) + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMBackup. +func (in *VMBackup) DeepCopy() *VMBackup { + if in == nil { + return nil + } + out := new(VMBackup) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VMCluster) DeepCopyInto(out *VMCluster) { *out = *in @@ -1329,7 +1426,6 @@ func (in *VMCluster) DeepCopyInto(out *VMCluster) { in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) out.Status = in.Status - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMCluster. @@ -1362,7 +1458,6 @@ func (in *VMClusterList) DeepCopyInto(out *VMClusterList) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMClusterList. @@ -1411,7 +1506,6 @@ func (in *VMClusterSpec) DeepCopyInto(out *VMClusterSpec) { *out = new(VMStorage) (*in).DeepCopyInto(*out) } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMClusterSpec. @@ -1427,7 +1521,6 @@ func (in *VMClusterSpec) DeepCopy() *VMClusterSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VMClusterStatus) DeepCopyInto(out *VMClusterStatus) { *out = *in - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMClusterStatus. @@ -1524,7 +1617,6 @@ func (in *VMInsert) DeepCopyInto(out *VMInsert) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMInsert. @@ -1829,7 +1921,6 @@ func (in *VMSelect) DeepCopyInto(out *VMSelect) { (*out)[key] = val } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMSelect. @@ -2017,11 +2108,7 @@ func (in *VMSingleSpec) DeepCopyInto(out *VMSingleSpec) { *out = new(EmbeddedObjectMetadata) (*in).DeepCopyInto(*out) } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(string) - **out = **in - } + out.Image = in.Image if in.ImagePullSecrets != nil { in, out := &in.ImagePullSecrets, &out.ImagePullSecrets *out = make([]v1.LocalObjectReference, len(*in)) @@ -2093,6 +2180,11 @@ func (in *VMSingleSpec) DeepCopyInto(out *VMSingleSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.VMBackup != nil { + in, out := &in.VMBackup, &out.VMBackup + *out = new(VMBackup) + (*in).DeepCopyInto(*out) + } if in.ExtraArgs != nil { in, out := &in.ExtraArgs, &out.ExtraArgs *out = make(map[string]string, len(*in)) @@ -2209,6 +2301,11 @@ func (in *VMStorage) DeepCopyInto(out *VMStorage) { *out = new(StorageSpec) (*in).DeepCopyInto(*out) } + if in.VMBackup != nil { + in, out := &in.VMBackup, &out.VMBackup + *out = new(VMBackup) + (*in).DeepCopyInto(*out) + } if in.ExtraArgs != nil { in, out := &in.ExtraArgs, &out.ExtraArgs *out = make(map[string]string, len(*in)) @@ -2223,7 +2320,6 @@ func (in *VMStorage) DeepCopyInto(out *VMStorage) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VMStorage. diff --git a/conf/config.go b/conf/config.go index 3c8e197d..5743d465 100644 --- a/conf/config.go +++ b/conf/config.go @@ -18,7 +18,7 @@ const prefixVar = "VM" type BaseOperatorConf struct { VMAlertDefault struct { Image string `default:"victoriametrics/vmalert"` - Version string `default:"v1.37.0"` + Version string `default:"v1.39.2"` Port string `default:"8080"` Resource struct { Limit struct { @@ -36,7 +36,7 @@ type BaseOperatorConf struct { } VMAgentDefault struct { Image string `default:"victoriametrics/vmagent"` - Version string `default:"v1.37.0"` + Version string `default:"v1.39.2"` ConfigReloadImage string `default:"quay.io/coreos/prometheus-config-reloader:v0.30.1"` Port string `default:"8429"` Resource struct { @@ -55,7 +55,7 @@ type BaseOperatorConf struct { VMSingleDefault struct { Image string `default:"victoriametrics/victoria-metrics"` - Version string `default:"v1.37.0"` + Version string `default:"v1.39.2"` Port string `default:"8429"` Resource struct { Limit struct { @@ -74,7 +74,7 @@ type BaseOperatorConf struct { VMClusterDefault struct { VMSelectDefault struct { Image string `default:"victoriametrics/vmselect"` - Version string `default:"v1.37.0-cluster"` + Version string `default:"v1.39.2-cluster"` Port string `default:"8481"` Resource struct { Limit struct { @@ -89,7 +89,7 @@ type BaseOperatorConf struct { } VMStorageDefault struct { Image string `default:"victoriametrics/vmstorage"` - Version string `default:"v1.37.0-cluster"` + Version string `default:"v1.39.2-cluster"` VMInsertPort string `default:"8400"` VMSelectPort string `default:"8401"` Port string `default:"8482"` @@ -106,7 +106,7 @@ type BaseOperatorConf struct { } VMInsertDefault struct { Image string `default:"victoriametrics/vminsert"` - Version string `default:"v1.37.0-cluster"` + Version string `default:"v1.39.2-cluster"` Port string `default:"8480"` Resource struct { Limit struct { @@ -137,7 +137,8 @@ type BaseOperatorConf struct { KubeletObject string } - VMBackup struct { + DisableSelfServiceScrapeCreation bool `default:"false"` + VMBackup struct { Image string `default:"tenmozes/backup"` Version string `default:"latest"` Port string `default:"8300"` @@ -155,8 +156,7 @@ type BaseOperatorConf struct { LogFormat string } - DisableSelfServiceMonitorCreation bool `default:"false"` - EnabledPrometheusConverter struct { + EnabledPrometheusConverter struct { PodMonitor bool `default:"true"` ServiceScrape bool `default:"true"` PrometheusRule bool `default:"true"` diff --git a/config/crd/bases/operator.victoriametrics.com_vmagents.yaml b/config/crd/bases/operator.victoriametrics.com_vmagents.yaml index db160b8c..a61ba7c6 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmagents.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmagents.yaml @@ -47,7 +47,7 @@ spec: authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -66,7 +66,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -812,8 +812,8 @@ spec: type: object arbitraryFSAccessThroughSMs: description: ArbitraryFSAccessThroughSMs configures whether configuration - based on a service monitor can access arbitrary files on the file - system of the VMAgent container e.g. bearer token files. + based on a service scrape can access arbitrary files on the file system + of the VMAgent container e.g. bearer token files. properties: deny: type: boolean @@ -2006,13 +2006,24 @@ spec: to false. type: boolean image: - description: Image - victoria metrics agent base image if not specified - - use default from operator config - type: string + description: Image - docker image settings for VMAgent if no specified + operator uses default config version + properties: + pullPolicy: + description: PullPolicy describes how to pull docker image + type: string + repository: + description: Repository contains name of docker image + it's repository + if needed + type: string + tag: + description: Tag contains desired docker image version + type: string + type: object imagePullSecrets: - description: ImagePullSecrets optional list of references to secrets - in the same namespace to use for pulling prometheus and vmagent images - from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + description: ImagePullSecrets An optional list of references to secrets + in the same namespace to use for pulling images from registries see + http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod items: description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. @@ -3094,7 +3105,7 @@ spec: type: string overrideHonorLabels: description: OverrideHonorLabels if set to true overrides all user configured - honor_labels. If HonorLabels is set in ServiceMonitor or PodMonitor + honor_labels. If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. type: boolean overrideHonorTimestamps: @@ -3129,8 +3140,8 @@ spec: definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' type: string type: object - podMonitorNamespaceSelector: - description: PodMonitorNamespaceSelector defines Namespaces to be selected + podScrapeNamespaceSelector: + description: PodScrapeNamespaceSelector defines Namespaces to be selected for PodMonitor discovery. If nil, only check own namespace. properties: matchExpressions: @@ -3173,10 +3184,10 @@ spec: are ANDed. type: object type: object - podMonitorSelector: - description: PodMonitorSelector defines PodMonitors to be selected for - target discovery. if neither this nor serviceMonitorSelector are specified, - configuration is unmanaged. + podScrapeSelector: + description: PodScrapeSelector defines PodScrapes to be selected for + target discovery. if neither PodScrapeNamespaceSelector this nor PodScrapeSelector + are specified, configuration is unmanaged. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -3255,7 +3266,7 @@ spec: basic authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -3274,7 +3285,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -3508,12 +3519,6 @@ spec: replica usage format: int32 type: integer - replicaExternalLabelName: - description: ReplicaExternalLabelName Name of vmagent external label - used to denote replica name. Defaults to the value of `prometheus_replica`. - External label will _not_ be added when value is set to empty string - (`""`). - type: string resources: description: Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ if not specified - default setting will be used @@ -3678,8 +3683,8 @@ spec: description: ServiceAccountName is the name of the ServiceAccount to use to run the VMAgent Pods. required type: string - serviceMonitorNamespaceSelector: - description: ServiceMonitorNamespaceSelector Namespaces to be selected + serviceScrapeNamespaceSelector: + description: ServiceScrapeNamespaceSelector Namespaces to be selected for ServiceMonitor discovery. If nil, only check own namespace. properties: matchExpressions: @@ -3722,10 +3727,10 @@ spec: are ANDed. type: object type: object - serviceMonitorSelector: - description: ServiceMonitorSelector defines ServiceMonitors to be selected - for target discovery. if neither this nor podMonitorSelector are specified, - configuration is unmanaged. + serviceScrapeSelector: + description: ServiceScrapeSelector defines ServiceScrapes to be selected + for target discovery. if neither serviceScrapeNamespaceSelector nor + serviceScrapeSelector are specified, configuration is unmanaged. properties: matchExpressions: description: matchExpressions is a list of label selector requirements. @@ -3807,9 +3812,6 @@ spec: type: string type: object type: array - version: - description: Version for VMAgent. - type: string vmAgentExternalLabelName: description: VMAgentExternalLabelName Name of vmAgent external label used to denote vmAgent instance name. Defaults to the value of `prometheus`. diff --git a/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml b/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml index e2837dad..4ebb7633 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmalertmanagers.yaml @@ -389,9 +389,6 @@ spec: type: array type: object type: object - baseImage: - description: BaseImage that is used to deploy pods, without tag. - type: string clusterAdvertiseAddress: description: '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' type: string @@ -1126,8 +1123,18 @@ spec: description: HostNetwork controls whether the pod may use the node network namespace type: boolean image: - description: Image if specified has precedence over baseImage, tag and sha combinations. - type: string + description: Image - docker image settings for VMAlertmanager if no specified operator uses default config version + properties: + pullPolicy: + description: PullPolicy describes how to pull docker image + type: string + repository: + description: Repository contains name of docker image + it's repository if needed + type: string + tag: + description: Tag contains desired docker image version + type: string + type: object imagePullSecrets: description: ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod items: @@ -2006,9 +2013,6 @@ spec: serviceAccountName: description: ServiceAccountName is the name of the ServiceAccount to use type: string - sha: - description: SHA of VMAlertmanager container image to be deployed. Defaults to the value of `version`. Similar to a tag, but the SHA explicitly deploys an immutable container image. Version and Tag are ignored if SHA is set. - type: string storage: description: Storage is the definition of how storage will be used by the VMAlertmanager instances. properties: @@ -2193,9 +2197,6 @@ spec: type: object type: object type: object - tag: - description: Tag of VMAlertmanager container image to be deployed. Defaults to the value of `version`. Version is ignored if Tag is set. - type: string tolerations: description: Tolerations If specified, the pod's tolerations. items: @@ -2219,9 +2220,6 @@ spec: type: string type: object type: array - version: - description: Version the cluster should be on. - type: string volumeMounts: description: VolumeMounts allows configuration of additional VolumeMounts on the output StatefulSet definition. VolumeMounts specified will be appended to other VolumeMounts in the alertmanager container, that are generated as a result of StorageSpec objects. items: diff --git a/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml b/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml index 1a48d9a8..b71cafe1 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmalerts.yaml @@ -1670,7 +1670,7 @@ spec: authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -1689,7 +1689,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -1961,12 +1961,24 @@ spec: namespace type: boolean image: - description: Image victoria metrics alert base image - type: string + description: Image - docker image settings for VMAlert if no specified + operator uses default config version + properties: + pullPolicy: + description: PullPolicy describes how to pull docker image + type: string + repository: + description: Repository contains name of docker image + it's repository + if needed + type: string + tag: + description: Tag contains desired docker image version + type: string + type: object imagePullSecrets: description: ImagePullSecrets An optional list of references to secrets - in the same namespace to use for pulling prometheus and VMAlert images - from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod + in the same namespace to use for pulling images from registries see + http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod items: description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. @@ -3055,7 +3067,7 @@ spec: authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -3074,7 +3086,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -3262,7 +3274,7 @@ spec: authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -3281,7 +3293,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -3441,7 +3453,7 @@ spec: authentication properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -3460,7 +3472,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -3928,9 +3940,6 @@ spec: type: string type: object type: array - version: - description: Version the VMAlert should be on. - type: string volumeMounts: description: VolumeMounts allows configuration of additional VolumeMounts on the output Deployment definition. VolumeMounts specified will be diff --git a/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml b/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml index 6cccf218..4ffab43c 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmclusters.yaml @@ -4079,7 +4079,7 @@ spec: description: extra args like maxBytesPerSecond default 0 type: object image: - description: Image - docker image settings for VMBackyper + description: Image - docker image settings for VMBackuper properties: pullPolicy: description: PullPolicy describes how to pull docker image @@ -4107,7 +4107,7 @@ spec: - PANIC type: string port: - description: Port for health check connetions + description: Port for health check connections type: string resources: description: Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ if not defined default resources from operator config will be used diff --git a/config/crd/bases/operator.victoriametrics.com_vmservicescrapes.yaml b/config/crd/bases/operator.victoriametrics.com_vmservicescrapes.yaml index 1f97be6c..695f72db 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmservicescrapes.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmservicescrapes.yaml @@ -39,7 +39,7 @@ spec: description: VMServiceScrapeSpec defines the desired state of VMServiceScrape properties: endpoints: - description: A list of endpoints allowed as part of this ServiceMonitor. + description: A list of endpoints allowed as part of this ServiceScrape. items: description: Endpoint defines a scrapeable endpoint serving Prometheus metrics. @@ -49,7 +49,7 @@ spec: basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints' properties: password: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the password for authentication. properties: key: @@ -68,7 +68,7 @@ spec: - key type: object username: - description: The secret in the service monitor namespace that + description: The secret in the service scrape namespace that contains the username for authentication. properties: key: @@ -93,7 +93,7 @@ spec: bearerTokenSecret: description: Secret to mount to read bearer token for scraping targets. The secret needs to be in the same namespace as the - service monitor and accessible by the victoria-metrics operator. + service scrape and accessible by the victoria-metrics operator. properties: key: description: The key of the secret to select from. Must be diff --git a/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml b/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml index bad1a441..0a227a1f 100644 --- a/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml +++ b/config/crd/bases/operator.victoriametrics.com_vmsingles.yaml @@ -1777,8 +1777,20 @@ spec: namespace type: boolean image: - description: Image victoria metrics single base image - type: string + description: Image - docker image settings for VMSingle if no specified + operator uses default config version + properties: + pullPolicy: + description: PullPolicy describes how to pull docker image + type: string + repository: + description: Repository contains name of docker image + it's repository + if needed + type: string + tag: + description: Tag contains desired docker image version + type: string + type: object imagePullSecrets: description: ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see @@ -3234,9 +3246,6 @@ spec: type: string type: object type: array - version: - description: Version of victoria metrics single - type: string vmBackup: description: VMBackup configuration for backup properties: @@ -3288,7 +3297,7 @@ spec: description: extra args like maxBytesPerSecond default 0 type: object image: - description: Image - docker image settings for VMBackyper + description: Image - docker image settings for VMBackuper properties: pullPolicy: description: PullPolicy describes how to pull docker image @@ -3318,7 +3327,7 @@ spec: - PANIC type: string port: - description: Port for health check connetions + description: Port for health check connections type: string resources: description: Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ diff --git a/config/examples/vmagent-full.yaml b/config/examples/vmagent-full.yaml index bc297da7..1b1f4121 100644 --- a/config/examples/vmagent-full.yaml +++ b/config/examples/vmagent-full.yaml @@ -47,8 +47,8 @@ kind: VMAgent metadata: name: example-vmagent spec: - serviceMonitorNamespaceSelector: {} - serviceMonitorSelector: {} + serviceScrapeNamespaceSelector: {} + serviceScrapeSelector: {} # Add fields here replicaCount: 1 resources: diff --git a/config/examples/vmagent.yaml b/config/examples/vmagent.yaml index 71160158..a37ec442 100644 --- a/config/examples/vmagent.yaml +++ b/config/examples/vmagent.yaml @@ -3,8 +3,10 @@ kind: VMAgent metadata: name: example-vmagent spec: - serviceMonitorNamespaceSelector: {} - serviceMonitorSelector: {} + serviceScrapeNamespaceSelector: {} + serviceScrapeSelector: {} + podScrapeNamespaceSelector: {} + podScrapeSelector: {} # Add fields here replicaCount: 1 resources: diff --git a/config/examples/vmagent_tls.yaml b/config/examples/vmagent_tls.yaml index 18954b40..21c1adad 100644 --- a/config/examples/vmagent_tls.yaml +++ b/config/examples/vmagent_tls.yaml @@ -3,8 +3,10 @@ kind: VMAgent metadata: name: example-vmagent-tls spec: - serviceMonitorNamespaceSelector: {} - serviceMonitorSelector: {} + serviceScrapenamespaceSelector: {} + serviceScrapeSelector: {} + podScrapenamespaceSelector: {} + podScrapeSelector: {} # Add fields here replicaCount: 1 resources: diff --git a/config/examples/vmpodscrape.yaml b/config/examples/vmpodscrape.yaml index 2ff2c253..e0bdb44f 100644 --- a/config/examples/vmpodscrape.yaml +++ b/config/examples/vmpodscrape.yaml @@ -7,5 +7,6 @@ spec: - port: metrics scheme: http selector: - monitored-by: vm-operator - app.kubernetes.io/name: example-application + matchLabels: + monitored-by: vm-operator + app.kubernetes.io/name: example-application diff --git a/controllers/factory/alertmanager.go b/controllers/factory/alertmanager.go index befceb7a..15003a12 100644 --- a/controllers/factory/alertmanager.go +++ b/controllers/factory/alertmanager.go @@ -73,14 +73,14 @@ func updateStsForAlertManager(ctx context.Context, rclient client.Client, oldSts func newStsForAlertManager(cr *victoriametricsv1beta1.VMAlertmanager, c *conf.BaseOperatorConf) (*appsv1.StatefulSet, error) { - if cr.Spec.BaseImage == "" { - cr.Spec.BaseImage = c.VMAlertManager.AlertmanagerDefaultBaseImage + if cr.Spec.Image.Repository == "" { + cr.Spec.Image.Repository = c.VMAlertManager.AlertmanagerDefaultBaseImage } if cr.Spec.PortName == "" { cr.Spec.PortName = defaultPortName } - if cr.Spec.Version == "" { - cr.Spec.Version = c.VMAlertManager.AlertManagerVersion + if cr.Spec.Image.Tag == "" { + cr.Spec.Image.Tag = c.VMAlertManager.AlertManagerVersion } if cr.Spec.ReplicaCount == nil { cr.Spec.ReplicaCount = &minReplicas @@ -239,16 +239,7 @@ func makeStatefulSetSpec(cr *victoriametricsv1beta1.VMAlertmanager, config *conf cr = cr.DeepCopy() - image := fmt.Sprintf("%s:%s", cr.Spec.BaseImage, cr.Spec.Version) - if cr.Spec.Tag != "" { - image = fmt.Sprintf("%s:%s", cr.Spec.BaseImage, cr.Spec.Tag) - } - if cr.Spec.SHA != "" { - image = fmt.Sprintf("%s@sha256:%s", cr.Spec.BaseImage, cr.Spec.SHA) - } - if cr.Spec.Image != nil && *cr.Spec.Image != "" { - image = *cr.Spec.Image - } + image := fmt.Sprintf("%s:%s", cr.Spec.Image.Repository, cr.Spec.Image.Tag) amArgs := []string{ fmt.Sprintf("--config.file=%s", alertmanagerConfFile), @@ -360,7 +351,7 @@ func makeStatefulSetSpec(cr *victoriametricsv1beta1.VMAlertmanager, config *conf }, ports...) } - version, err := semver.ParseTolerant(cr.Spec.Version) + version, err := semver.ParseTolerant(cr.Spec.Image.Tag) if err != nil { log.Error(err, "cannot parse alert manager version") } else { @@ -471,14 +462,15 @@ func makeStatefulSetSpec(cr *victoriametricsv1beta1.VMAlertmanager, config *conf defaultContainers := []v1.Container{ { - Args: amArgs, - Name: "alertmanager", - Image: image, - Ports: ports, - VolumeMounts: amVolumeMounts, - LivenessProbe: livenessProbe, - ReadinessProbe: readinessProbe, - Resources: cr.Spec.Resources, + Args: amArgs, + Name: "alertmanager", + Image: image, + ImagePullPolicy: cr.Spec.Image.PullPolicy, + Ports: ports, + VolumeMounts: amVolumeMounts, + LivenessProbe: livenessProbe, + ReadinessProbe: readinessProbe, + Resources: cr.Spec.Resources, Env: []v1.EnvVar{ { // Necessary for '--cluster.listen-address' flag diff --git a/controllers/factory/servicemons.go b/controllers/factory/scrapes.go similarity index 77% rename from controllers/factory/servicemons.go rename to controllers/factory/scrapes.go index eb80d352..a689534c 100644 --- a/controllers/factory/servicemons.go +++ b/controllers/factory/scrapes.go @@ -20,13 +20,13 @@ import ( var invalidDNS1123Characters = regexp.MustCompile("[^-a-z0-9]+") func CreateOrUpdateConfigurationSecret(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client, c *conf.BaseOperatorConf) error { - // If no service or pod monitor selectors are configured, the user wants to + // If no service or pod scrape selectors are configured, the user wants to // manage configuration themselves. Do create an empty Secret if it doesn't // exist. l := log.WithValues("vmagent", cr.Name, "namespace", cr.Namespace) - if cr.Spec.ServiceMonitorSelector == nil && cr.Spec.PodMonitorSelector == nil { - l.Info("neither ServiceMonitor not PodMonitor selector specified, leaving configuration unmanaged") + if cr.Spec.ServiceScrapeSelector == nil && cr.Spec.PodScrapeSelector == nil { + l.Info("neither ServiceScrape nor PodScrape selector specified, leaving configuration unmanaged") s, err := makeEmptyConfigurationSecret(cr, c) if err != nil { @@ -45,14 +45,14 @@ func CreateOrUpdateConfigurationSecret(ctx context.Context, cr *victoriametricsv return nil } - smons, err := SelectServiceMonitors(ctx, cr, rclient) + smons, err := SelectServiceScrapes(ctx, cr, rclient) if err != nil { - return fmt.Errorf("selecting ServiceMonitors failed: %w", err) + return fmt.Errorf("selecting ServiceScrapes failed: %w", err) } - pmons, err := SelectPodMonitors(ctx, cr, rclient) + pmons, err := SelectPodScrapes(ctx, cr, rclient) if err != nil { - return fmt.Errorf("selecting PodMonitors failed: %w", err) + return fmt.Errorf("selecting PodScrapes failed: %w", err) } SecretsInNS := &v1.SecretList{} @@ -126,22 +126,22 @@ func CreateOrUpdateConfigurationSecret(ctx context.Context, cr *victoriametricsv return rclient.Update(ctx, s) } -func SelectServiceMonitors(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client) (map[string]*victoriametricsv1beta1.VMServiceScrape, error) { +func SelectServiceScrapes(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client) (map[string]*victoriametricsv1beta1.VMServiceScrape, error) { res := make(map[string]*victoriametricsv1beta1.VMServiceScrape) namespaces := []string{} - //list namespaces matched by nameselector + //list namespaces matched by namespaceselector //for each namespace apply list with selector //combine result - if cr.Spec.ServiceMonitorNamespaceSelector == nil { + if cr.Spec.ServiceScrapeNamespaceSelector == nil { namespaces = append(namespaces, cr.Namespace) - } else if cr.Spec.ServiceMonitorNamespaceSelector.MatchExpressions == nil && cr.Spec.ServiceMonitorNamespaceSelector.MatchLabels == nil { + } else if cr.Spec.ServiceScrapeNamespaceSelector.MatchExpressions == nil && cr.Spec.ServiceScrapeNamespaceSelector.MatchLabels == nil { namespaces = nil } else { - log.Info("namspace selector for serviceMonitors", "selector", cr.Spec.ServiceMonitorNamespaceSelector.String()) - nsSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.ServiceMonitorNamespaceSelector) + log.Info("namspace selector for serviceScrapes", "selector", cr.Spec.ServiceScrapeNamespaceSelector.String()) + nsSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.ServiceScrapeNamespaceSelector) if err != nil { return nil, fmt.Errorf("cannot convert rulenamespace selector: %w", err) } @@ -152,47 +152,47 @@ func SelectServiceMonitors(ctx context.Context, cr *victoriametricsv1beta1.VMAge } // if namespaces isn't nil, then nameSpaceSelector is defined - // but monitorSelector maybe be nil and we must set it to catch all value - if namespaces != nil && cr.Spec.ServiceMonitorSelector == nil { - cr.Spec.ServiceMonitorSelector = &metav1.LabelSelector{} + // but scrapeSelector maybe be nil and we must set it to catch all value + if namespaces != nil && cr.Spec.ServiceScrapeSelector == nil { + cr.Spec.ServiceScrapeSelector = &metav1.LabelSelector{} } - servMonSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.ServiceMonitorSelector) + servMonSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.ServiceScrapeSelector) if err != nil { - return nil, fmt.Errorf("cannot convert ServiceMonitorSelector to labelSelector: %w", err) + return nil, fmt.Errorf("cannot convert ServiceScrapeSelector to labelSelector: %w", err) } - servMonsCombined := []victoriametricsv1beta1.VMServiceScrape{} + servScrapesCombined := []victoriametricsv1beta1.VMServiceScrape{} //list all namespaces for rules with selector if namespaces == nil { - log.Info("listing all namespaces for serviceMonitors", "vmagent", cr.Name) + log.Info("listing all namespaces for serviceScrapes", "vmagent", cr.Name) servMons := &victoriametricsv1beta1.VMServiceScrapeList{} err = rclient.List(ctx, servMons, &client.ListOptions{LabelSelector: servMonSelector}) if err != nil { return nil, fmt.Errorf("cannot list rules from all namespaces: %w", err) } - servMonsCombined = append(servMonsCombined, servMons.Items...) + servScrapesCombined = append(servScrapesCombined, servMons.Items...) } else { for _, ns := range namespaces { - log.Info("listing namespace for serviceMonitors", "ns", ns, "vmagent", cr.Name) + log.Info("listing namespace for serviceScrapes", "ns", ns, "vmagent", cr.Name) listOpts := &client.ListOptions{Namespace: ns, LabelSelector: servMonSelector} servMons := &victoriametricsv1beta1.VMServiceScrapeList{} err = rclient.List(ctx, servMons, listOpts) if err != nil { return nil, fmt.Errorf("cannot list rules at namespace: %s, err: %w", ns, err) } - servMonsCombined = append(servMonsCombined, servMons.Items...) + servScrapesCombined = append(servScrapesCombined, servMons.Items...) } } - for _, mon := range servMonsCombined { - m := mon.DeepCopy() - res[mon.Namespace+"/"+mon.Name] = m + for _, servScrape := range servScrapesCombined { + m := servScrape.DeepCopy() + res[servScrape.Namespace+"/"+servScrape.Name] = m } - // filter out all service monitors that access + // filter out all service scrapes that access // the file system. if cr.Spec.ArbitraryFSAccessThroughSMs.Deny { for namespaceAndName, sm := range res { @@ -210,16 +210,16 @@ func SelectServiceMonitors(ctx context.Context, cr *victoriametricsv1beta1.VMAge } } - serviceMonitors := []string{} + serviceScrapes := []string{} for k := range res { - serviceMonitors = append(serviceMonitors, k) + serviceScrapes = append(serviceScrapes, k) } - log.Info("selected ServiceMonitors", "servicemonitors", strings.Join(serviceMonitors, ","), "namespace", cr.Namespace, "vmagent", cr.Name) + log.Info("selected ServiceScrapes", "servicescrapes", strings.Join(serviceScrapes, ","), "namespace", cr.Namespace, "vmagent", cr.Name) return res, nil } -func SelectPodMonitors(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client) (map[string]*victoriametricsv1beta1.VMPodScrape, error) { +func SelectPodScrapes(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client) (map[string]*victoriametricsv1beta1.VMPodScrape, error) { res := make(map[string]*victoriametricsv1beta1.VMPodScrape) @@ -229,69 +229,69 @@ func SelectPodMonitors(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, // for each namespace apply list with selector // combine result - if cr.Spec.PodMonitorNamespaceSelector == nil { + if cr.Spec.PodScrapeNamespaceSelector == nil { namespaces = append(namespaces, cr.Namespace) - } else if cr.Spec.PodMonitorNamespaceSelector.MatchExpressions == nil && cr.Spec.PodMonitorNamespaceSelector.MatchLabels == nil { + } else if cr.Spec.PodScrapeNamespaceSelector.MatchExpressions == nil && cr.Spec.PodScrapeNamespaceSelector.MatchLabels == nil { namespaces = nil } else { - log.Info("selector for podMonitor", "vmagent", cr.Name, "selector", cr.Spec.PodMonitorNamespaceSelector.String()) - nsSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.PodMonitorNamespaceSelector) + log.Info("selector for podScrape", "vmagent", cr.Name, "selector", cr.Spec.PodScrapeNamespaceSelector.String()) + nsSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.PodScrapeNamespaceSelector) if err != nil { - return nil, fmt.Errorf("cannot convert ruleNameSpace to labelSelector: %w", err) + return nil, fmt.Errorf("cannot convert podScrapeNamespaceSelector to labelSelector: %w", err) } namespaces, err = selectNamespaces(ctx, rclient, nsSelector) if err != nil { - return nil, fmt.Errorf("cannot select namespaces for rule match: %w", err) + return nil, fmt.Errorf("cannot select namespaces for podScrape match: %w", err) } } // if namespaces isn't nil, then nameSpaceSelector is defined - //but monitorSelector maybe be nil and we have to set it to catch all value - if namespaces != nil && cr.Spec.PodMonitorSelector == nil { - cr.Spec.PodMonitorSelector = &metav1.LabelSelector{} + //but scrapeSelector maybe be nil and we have to set it to catch all value + if namespaces != nil && cr.Spec.PodScrapeSelector == nil { + cr.Spec.PodScrapeSelector = &metav1.LabelSelector{} } - podMonSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.PodMonitorSelector) + podScrapeSelector, err := metav1.LabelSelectorAsSelector(cr.Spec.PodScrapeSelector) if err != nil { - return nil, fmt.Errorf("cannot convert podMonitorSelector to label selector: %w", err) + return nil, fmt.Errorf("cannot convert podScrapeSelector to label selector: %w", err) } - podMonsCombined := []victoriametricsv1beta1.VMPodScrape{} + podScrapesCombined := []victoriametricsv1beta1.VMPodScrape{} //list all namespaces for rules with selector if namespaces == nil { - log.Info("listing all namespaces for rules") + log.Info("listing all namespaces for podScrapes") servMons := &victoriametricsv1beta1.VMPodScrapeList{} - err = rclient.List(ctx, servMons, &client.ListOptions{LabelSelector: podMonSelector}) + err = rclient.List(ctx, servMons, &client.ListOptions{LabelSelector: podScrapeSelector}) if err != nil { - return nil, fmt.Errorf("cannot list pod monitors from all namespaces: %w", err) + return nil, fmt.Errorf("cannot list podScrapes from all namespaces: %w", err) } - podMonsCombined = append(podMonsCombined, servMons.Items...) + podScrapesCombined = append(podScrapesCombined, servMons.Items...) } else { for _, ns := range namespaces { - listOpts := &client.ListOptions{Namespace: ns, LabelSelector: podMonSelector} + listOpts := &client.ListOptions{Namespace: ns, LabelSelector: podScrapeSelector} servMons := &victoriametricsv1beta1.VMPodScrapeList{} err = rclient.List(ctx, servMons, listOpts) if err != nil { - return nil, fmt.Errorf("cannot list podmonitors at namespace: %s, err: %w", ns, err) + return nil, fmt.Errorf("cannot list podscrapes at namespace: %s, err: %w", ns, err) } - podMonsCombined = append(podMonsCombined, servMons.Items...) + podScrapesCombined = append(podScrapesCombined, servMons.Items...) } } - log.Info("filtering namespaces to select PodMonitors from", + log.Info("filtering namespaces to select PodScrapes from", "namespace", cr.Namespace, "vmagent", cr.Name) - for _, podMon := range podMonsCombined { - pm := podMon.DeepCopy() - res[podMon.Namespace+"/"+podMon.Name] = pm + for _, podScrape := range podScrapesCombined { + pm := podScrape.DeepCopy() + res[podScrape.Namespace+"/"+podScrape.Name] = pm } - podMonitors := make([]string, 0) + podScrapes := make([]string, 0) for key := range res { - podMonitors = append(podMonitors, key) + podScrapes = append(podScrapes, key) } - log.Info("selected PodMonitors", "podmonitors", strings.Join(podMonitors, ","), "namespace", cr.Namespace, "vmagent", cr.Name) + log.Info("selected PodScrapes", "podscrapes", strings.Join(podScrapes, ","), "namespace", cr.Namespace, "vmagent", cr.Name) return res, nil } @@ -314,7 +314,7 @@ func loadBasicAuthSecrets( if err != nil { return nil, fmt.Errorf("could not generate basicAuth for vmservicescrape %s. %w", mon.Name, err) } - secrets[fmt.Sprintf("serviceMonitor/%s/%s/%d", mon.Namespace, mon.Name, i)] = credentials + secrets[fmt.Sprintf("serviceScrape/%s/%s/%d", mon.Namespace, mon.Name, i)] = credentials } } @@ -375,7 +375,7 @@ func loadBearerTokensFromSecrets( ) } - tokens[fmt.Sprintf("serviceMonitor/%s/%s/%d", mon.Namespace, mon.Name, i)] = BearerToken(token) + tokens[fmt.Sprintf("serviceScrape/%s/%s/%d", mon.Namespace, mon.Name, i)] = BearerToken(token) } } diff --git a/controllers/factory/servicemons_build.go b/controllers/factory/scrapes_build.go similarity index 95% rename from controllers/factory/servicemons_build.go rename to controllers/factory/scrapes_build.go index 215fdb39..c9425b89 100644 --- a/controllers/factory/servicemons_build.go +++ b/controllers/factory/scrapes_build.go @@ -15,13 +15,12 @@ import ( ) const ( - defaultReplicaExternalLabelName = "prometheus_replica" - defaultScrapeInterval = "30s" - tlsAssetsDir = "/etc/vmagent-tls/certs" - configFilename = "vmagent.yaml.gz" - configEnvsubstFilename = "vmagent.env.yaml" - kubernetesSDRoleEndpoint = "endpoints" - kubernetesSDRolePod = "pod" + defaultScrapeInterval = "30s" + tlsAssetsDir = "/etc/vmagent-tls/certs" + configFilename = "vmagent.yaml.gz" + configEnvsubstFilename = "vmagent.env.yaml" + kubernetesSDRoleEndpoint = "endpoints" + kubernetesSDRolePod = "pod" ) var ( @@ -87,7 +86,7 @@ func generateConfig( for _, identifier := range sMonIdentifiers { for i, ep := range sMons[identifier].Spec.Endpoints { scrapeConfigs = append(scrapeConfigs, - generateServiceMonitorConfig( + generateServiceScrapeConfig( sMons[identifier], ep, i, apiserverConfig, @@ -102,7 +101,7 @@ func generateConfig( for _, identifier := range pMonIdentifiers { for i, ep := range pMons[identifier].Spec.PodMetricsEndpoints { scrapeConfigs = append(scrapeConfigs, - generatePodMonitorConfig( + generatePodScrapeConfig( pMons[identifier], ep, i, apiserverConfig, basicAuthSecrets, @@ -199,7 +198,7 @@ func honorTimestamps(cfg yaml.MapSlice, userHonorTimestamps *bool, overrideHonor return append(cfg, yaml.MapItem{Key: "honor_timestamps", Value: honor && !overrideHonorTimestamps}) } -func generatePodMonitorConfig( +func generatePodScrapeConfig( m *victoriametricsv1beta1.VMPodScrape, ep victoriametricsv1beta1.PodMetricsEndpoint, i int, @@ -249,7 +248,7 @@ func generatePodMonitorConfig( relabelings []yaml.MapSlice labelKeys []string ) - // Filter targets by pods selected by the monitor. + // Filter targets by pods selected by the scrape. // Exact label matches. for k := range m.Spec.Selector.MatchLabels { labelKeys = append(labelKeys, k) @@ -303,7 +302,7 @@ func generatePodMonitorConfig( }) } else if ep.TargetPort != nil { //.Warn(cg.logger).Log("msg", "PodMonitor 'targetPort' is deprecated, use 'port' instead.", - // "podMonitor", m.Name) + // "podScrape", m.Name) if ep.TargetPort.StrVal != "" { relabelings = append(relabelings, yaml.MapSlice{ {Key: "action", Value: "keep"}, @@ -406,7 +405,7 @@ func generatePodMonitorConfig( return cfg } -func generateServiceMonitorConfig( +func generateServiceScrapeConfig( m *victoriametricsv1beta1.VMServiceScrape, ep victoriametricsv1beta1.Endpoint, i int, @@ -460,13 +459,13 @@ func generateServiceMonitorConfig( } if ep.BearerTokenSecret.Name != "" { - if s, ok := bearerTokens[fmt.Sprintf("serviceMonitor/%s/%s/%d", m.Namespace, m.Name, i)]; ok { + if s, ok := bearerTokens[fmt.Sprintf("serviceScrape/%s/%s/%d", m.Namespace, m.Name, i)]; ok { cfg = append(cfg, yaml.MapItem{Key: "bearer_token", Value: s}) } } if ep.BasicAuth != nil { - if s, ok := basicAuthSecrets[fmt.Sprintf("serviceMonitor/%s/%s/%d", m.Namespace, m.Name, i)]; ok { + if s, ok := basicAuthSecrets[fmt.Sprintf("serviceScrape/%s/%s/%d", m.Namespace, m.Name, i)]; ok { cfg = append(cfg, yaml.MapItem{ Key: "basic_auth", Value: yaml.MapSlice{ {Key: "username", Value: s.username}, @@ -478,7 +477,7 @@ func generateServiceMonitorConfig( var relabelings []yaml.MapSlice - // Filter targets by services selected by the monitor. + // Filter targets by services selected by the scrape. // Exact label matches. var labelKeys []string @@ -815,6 +814,7 @@ func buildExternalLabels(p *victoriametricsv1beta1.VMAgent) yaml.MapSlice { m := map[string]string{} // Use "prometheus" external label name by default if field is missing. + // in case of migration from prometheus to vmagent, it helps to have same labels // Do not add external label if field is set to empty string. prometheusExternalLabelName := "prometheus" if p.Spec.VMAgentExternalLabelName != nil { @@ -825,25 +825,10 @@ func buildExternalLabels(p *victoriametricsv1beta1.VMAgent) yaml.MapSlice { } } - // Use defaultReplicaExternalLabelName constant by default if field is missing. - // Do not add external label if field is set to empty string. - replicaExternalLabelName := defaultReplicaExternalLabelName - if p.Spec.ReplicaExternalLabelName != nil { - if *p.Spec.ReplicaExternalLabelName != "" { - replicaExternalLabelName = *p.Spec.ReplicaExternalLabelName - } else { - replicaExternalLabelName = "" - } - } - if prometheusExternalLabelName != "" { m[prometheusExternalLabelName] = fmt.Sprintf("%s/%s", p.Namespace, p.Name) } - if replicaExternalLabelName != "" { - m[replicaExternalLabelName] = "$(POD_NAME)" - } - for n, v := range p.Spec.ExternalLabels { m[n] = v } diff --git a/controllers/factory/servicemons_test.go b/controllers/factory/scrapes_test.go similarity index 90% rename from controllers/factory/servicemons_test.go rename to controllers/factory/scrapes_test.go index 6d9d7e88..aa648a9f 100644 --- a/controllers/factory/servicemons_test.go +++ b/controllers/factory/scrapes_test.go @@ -52,7 +52,7 @@ func TestSelectServiceMonitors(t *testing.T) { predefinedObjest []runtime.Object }{ { - name: "select service monitor inside vmagent namespace", + name: "select service scrape inside vmagent namespace", args: args{ p: &victoriametricsv1beta1.VMAgent{ ObjectMeta: metav1.ObjectMeta{ @@ -60,7 +60,7 @@ func TestSelectServiceMonitors(t *testing.T) { Namespace: "default", }, Spec: victoriametricsv1beta1.VMAgentSpec{ - ServiceMonitorSelector: &metav1.LabelSelector{}, + ServiceScrapeSelector: &metav1.LabelSelector{}, }, }, l: logf.Log.WithName("unit-test"), @@ -75,7 +75,7 @@ func TestSelectServiceMonitors(t *testing.T) { wantErr: false, }, { - name: "select service monitor from namespace with filter", + name: "select service scrape from namespace with filter", args: args{ p: &victoriametricsv1beta1.VMAgent{ ObjectMeta: metav1.ObjectMeta{ @@ -83,8 +83,8 @@ func TestSelectServiceMonitors(t *testing.T) { Namespace: "default", }, Spec: victoriametricsv1beta1.VMAgentSpec{ - ServiceMonitorNamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "stage"}}, - ServiceMonitorSelector: &metav1.LabelSelector{}, + ServiceScrapeNamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "stage"}}, + ServiceScrapeSelector: &metav1.LabelSelector{}, }, }, l: logf.Log.WithName("unit-test"), @@ -110,9 +110,9 @@ func TestSelectServiceMonitors(t *testing.T) { obj := []runtime.Object{} obj = append(obj, tt.predefinedObjest...) fclient := fake.NewFakeClientWithScheme(testGetScheme(), obj...) - got, err := SelectServiceMonitors(context.TODO(), tt.args.p, fclient) + got, err := SelectServiceScrapes(context.TODO(), tt.args.p, fclient) if (err != nil) != tt.wantErr { - t.Errorf("SelectServiceMonitors() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("SelectServiceScrapes() error = %v, wantErr %v", err, tt.wantErr) return } gotNames := []string{} @@ -121,7 +121,7 @@ func TestSelectServiceMonitors(t *testing.T) { } sort.Strings(gotNames) if !reflect.DeepEqual(gotNames, tt.want) { - t.Errorf("SelectServiceMonitors() got = %v, want %v", gotNames, tt.want) + t.Errorf("SelectServiceScrapes() got = %v, want %v", gotNames, tt.want) } }) } @@ -140,7 +140,7 @@ func TestSelectPodMonitors(t *testing.T) { predefinedObjects []runtime.Object }{ { - name: "selector pod monitor at vmagent ns", + name: "selector pod scrape at vmagent ns", args: args{ p: &victoriametricsv1beta1.VMAgent{ ObjectMeta: metav1.ObjectMeta{ @@ -148,7 +148,7 @@ func TestSelectPodMonitors(t *testing.T) { Namespace: "default", }, Spec: victoriametricsv1beta1.VMAgentSpec{ - PodMonitorSelector: &metav1.LabelSelector{}, + PodScrapeSelector: &metav1.LabelSelector{}, }, }, l: logf.Log.WithName("unit-test"), @@ -166,7 +166,7 @@ func TestSelectPodMonitors(t *testing.T) { want: []string{"default/pod1"}, }, { - name: "selector pod monitor at different ns with ns selector", + name: "selector pod scrape at different ns with ns selector", args: args{ p: &victoriametricsv1beta1.VMAgent{ ObjectMeta: metav1.ObjectMeta{ @@ -174,7 +174,7 @@ func TestSelectPodMonitors(t *testing.T) { Namespace: "default", }, Spec: victoriametricsv1beta1.VMAgentSpec{ - PodMonitorNamespaceSelector: &metav1.LabelSelector{ + PodScrapeNamespaceSelector: &metav1.LabelSelector{ MatchLabels: map[string]string{"name": "monitoring"}, }, }, @@ -208,9 +208,9 @@ func TestSelectPodMonitors(t *testing.T) { obj := []runtime.Object{} obj = append(obj, tt.predefinedObjects...) fclient := fake.NewFakeClientWithScheme(testGetScheme(), obj...) - got, err := SelectPodMonitors(context.TODO(), tt.args.p, fclient) + got, err := SelectPodScrapes(context.TODO(), tt.args.p, fclient) if (err != nil) != tt.wantErr { - t.Errorf("SelectPodMonitors() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("SelectPodScrapes() error = %v, wantErr %v", err, tt.wantErr) return } gotNames := []string{} @@ -219,7 +219,7 @@ func TestSelectPodMonitors(t *testing.T) { } sort.Strings(gotNames) if !reflect.DeepEqual(gotNames, tt.want) { - t.Errorf("SelectPodMonitors() got = %v, want %v", gotNames, tt.want) + t.Errorf("SelectPodScrapes() got = %v, want %v", gotNames, tt.want) } }) } diff --git a/controllers/factory/vmagent.go b/controllers/factory/vmagent.go index 4d3b0ce7..ce402603 100644 --- a/controllers/factory/vmagent.go +++ b/controllers/factory/vmagent.go @@ -161,12 +161,16 @@ func newDeployForVMAgent(cr *victoriametricsv1beta1.VMAgent, c *conf.BaseOperato cr = cr.DeepCopy() //inject default - if cr.Spec.Image == nil { - cr.Spec.Image = &c.VMAgentDefault.Image + if cr.Spec.Image.Repository == "" { + cr.Spec.Image.Repository = c.VMAgentDefault.Image } - if cr.Spec.Version == "" { - cr.Spec.Version = c.VMAgentDefault.Version + if cr.Spec.Image.Tag == "" { + cr.Spec.Image.Tag = c.VMAgentDefault.Version } + if cr.Spec.Image.PullPolicy == "" { + cr.Spec.Image.PullPolicy = corev1.PullIfNotPresent + } + if cr.Spec.Port == "" { cr.Spec.Port = c.VMAgentDefault.Port } @@ -427,7 +431,8 @@ func makeSpecForVMAgent(cr *victoriametricsv1beta1.VMAgent, c *conf.BaseOperator operatorContainers := append([]corev1.Container{ { Name: "vmagent", - Image: fmt.Sprintf("%s:%s", *cr.Spec.Image, cr.Spec.Version), + Image: fmt.Sprintf("%s:%s", cr.Spec.Image.Repository, cr.Spec.Image.Tag), + ImagePullPolicy: cr.Spec.Image.PullPolicy, Ports: ports, Args: args, Env: envs, @@ -519,11 +524,11 @@ func addAddtionalScrapeConfigOwnership(cr *victoriametricsv1beta1.VMAgent, rclie } func CreateOrUpdateTlsAssets(ctx context.Context, cr *victoriametricsv1beta1.VMAgent, rclient client.Client) error { - monitors, err := SelectServiceMonitors(ctx, cr, rclient) + scrapes, err := SelectServiceScrapes(ctx, cr, rclient) if err != nil { - return fmt.Errorf("cannot select service monitors for tls Assets: %w", err) + return fmt.Errorf("cannot select service scrapes for tls Assets: %w", err) } - assets, err := loadTLSAssets(ctx, rclient, cr, monitors) + assets, err := loadTLSAssets(ctx, rclient, cr, scrapes) if err != nil { return fmt.Errorf("cannot load tls assets: %w", err) } @@ -560,7 +565,7 @@ func CreateOrUpdateTlsAssets(ctx context.Context, cr *victoriametricsv1beta1.VMA return rclient.Update(ctx, tlsAssetsSecret) } -func loadTLSAssets(ctx context.Context, rclient client.Client, cr *victoriametricsv1beta1.VMAgent, monitors map[string]*victoriametricsv1beta1.VMServiceScrape) (map[string]string, error) { +func loadTLSAssets(ctx context.Context, rclient client.Client, cr *victoriametricsv1beta1.VMAgent, scrapes map[string]*victoriametricsv1beta1.VMServiceScrape) (map[string]string, error) { assets := map[string]string{} nsSecretCache := make(map[string]*corev1.Secret) nsConfigMapCache := make(map[string]*corev1.ConfigMap) @@ -628,7 +633,7 @@ func loadTLSAssets(ctx context.Context, rclient client.Client, cr *victoriametri assets[rw.TLSConfig.BuildAssetPath(cr.Namespace, selector.Name, selector.Key)] = asset } } - for _, mon := range monitors { + for _, mon := range scrapes { for _, ep := range mon.Spec.Endpoints { if ep.TLSConfig == nil { continue diff --git a/controllers/factory/vmagent_test.go b/controllers/factory/vmagent_test.go index 7032d231..7d9878e0 100644 --- a/controllers/factory/vmagent_test.go +++ b/controllers/factory/vmagent_test.go @@ -59,7 +59,7 @@ func TestCreateOrUpdateVMAgent(t *testing.T) { RemoteWrite: []victoriametricsv1beta1.VMAgentRemoteWriteSpec{ {URL: "http://remote-write"}, }, - ServiceMonitorSelector: &metav1.LabelSelector{}, + ServiceScrapeSelector: &metav1.LabelSelector{}, }, }, }, @@ -155,7 +155,7 @@ func TestCreateOrUpdateVMAgent(t *testing.T) { {URL: "http://remote-write4", TLSConfig: &victoriametricsv1beta1.TLSConfig{CertFile: "/tmp/cert1", KeyFile: "/tmp/key1", CAFile: "/tmp/ca"}}, }, - ServiceMonitorSelector: &metav1.LabelSelector{}, + ServiceScrapeSelector: &metav1.LabelSelector{}, }, }, }, diff --git a/controllers/factory/vmalert.go b/controllers/factory/vmalert.go index 55d1dfd0..6139cbe6 100644 --- a/controllers/factory/vmalert.go +++ b/controllers/factory/vmalert.go @@ -142,12 +142,16 @@ func CreateOrUpdateVMAlert(ctx context.Context, cr *victoriametricsv1beta1.VMAle func newDeployForVMAlert(cr *victoriametricsv1beta1.VMAlert, c *conf.BaseOperatorConf, ruleConfigMapNames []string, remoteSecrets map[string]BasicAuthCredentials) (*appsv1.Deployment, error) { cr = cr.DeepCopy() - if cr.Spec.Image == nil { - cr.Spec.Image = &c.VMAlertDefault.Image + if cr.Spec.Image.Repository == "" { + cr.Spec.Image.Repository = c.VMAlertDefault.Image } - if cr.Spec.Version == "" { - cr.Spec.Version = c.VMAgentDefault.Version + if cr.Spec.Image.Tag == "" { + cr.Spec.Image.Tag = c.VMAgentDefault.Version } + if cr.Spec.Image.PullPolicy == "" { + cr.Spec.Image.PullPolicy = corev1.PullIfNotPresent + } + if cr.Spec.Resources.Requests == nil { cr.Spec.Resources.Requests = corev1.ResourceList{} } @@ -493,7 +497,8 @@ func vmAlertSpecGen(cr *victoriametricsv1beta1.VMAlert, c *conf.BaseOperatorConf { Args: args, Name: "vmalert", - Image: *cr.Spec.Image + ":" + cr.Spec.Version, + Image: fmt.Sprintf("%s:%s", cr.Spec.Image.Repository, cr.Spec.Image.Tag), + ImagePullPolicy: cr.Spec.Image.PullPolicy, Ports: ports, VolumeMounts: volumeMounts, LivenessProbe: livenessProbe, diff --git a/controllers/factory/vmcluster.go b/controllers/factory/vmcluster.go index 972ca189..14cfbb56 100644 --- a/controllers/factory/vmcluster.go +++ b/controllers/factory/vmcluster.go @@ -74,7 +74,7 @@ func CreateOrUpdateVMCluster(ctx context.Context, cr *v1beta1.VMCluster, rclient reason = "failed to create vmStorage service" return status, err } - if !c.DisableSelfServiceMonitorCreation { + if !c.DisableSelfServiceScrapeCreation { err := CreateVMServiceScrapeFromService(ctx, rclient, storageSvc, "http") if err != nil { log.Error(err, "cannot create VMServiceScrape for vmStorage") @@ -107,7 +107,7 @@ func CreateOrUpdateVMCluster(ctx context.Context, cr *v1beta1.VMCluster, rclient reason = "failed to create vmSelect service" return status, err } - if !c.DisableSelfServiceMonitorCreation { + if !c.DisableSelfServiceScrapeCreation { err := CreateVMServiceScrapeFromService(ctx, rclient, selectSvc, "http") if err != nil { log.Error(err, "cannot create VMServiceScrape for vmSelect") @@ -145,7 +145,7 @@ func CreateOrUpdateVMCluster(ctx context.Context, cr *v1beta1.VMCluster, rclient reason = "failed to create vmInsert service" return status, err } - if !c.DisableSelfServiceMonitorCreation { + if !c.DisableSelfServiceScrapeCreation { err := CreateVMServiceScrapeFromService(ctx, rclient, insertSvc) if err != nil { log.Error(err, "cannot create VMServiceScrape for vmInsert") diff --git a/controllers/factory/vmsingle.go b/controllers/factory/vmsingle.go index fc1ff3f9..ae8568ee 100644 --- a/controllers/factory/vmsingle.go +++ b/controllers/factory/vmsingle.go @@ -122,15 +122,18 @@ func CreateOrUpdateVMSingle(ctx context.Context, cr *victoriametricsv1beta1.VMSi func newDeployForVMSingle(cr *victoriametricsv1beta1.VMSingle, c *conf.BaseOperatorConf) (*appsv1.Deployment, error) { cr = cr.DeepCopy() - if cr.Spec.Image == nil { - cr.Spec.Image = &c.VMSingleDefault.Image + if cr.Spec.Image.Repository == "" { + cr.Spec.Image.Repository = c.VMSingleDefault.Image } - if cr.Spec.Version == "" { - cr.Spec.Version = c.VMSingleDefault.Version + if cr.Spec.Image.Tag == "" { + cr.Spec.Image.Tag = c.VMSingleDefault.Version } if cr.Spec.Port == "" { cr.Spec.Port = c.VMSingleDefault.Port } + if cr.Spec.Image.PullPolicy == "" { + cr.Spec.Image.PullPolicy = corev1.PullIfNotPresent + } if cr.Spec.Resources.Requests == nil { cr.Spec.Resources.Requests = corev1.ResourceList{} @@ -311,7 +314,7 @@ func makeSpecForVMSingle(cr *victoriametricsv1beta1.VMSingle, c *conf.BaseOperat operatorContainers := append([]corev1.Container{ { Name: "vmsignle", - Image: fmt.Sprintf("%s:%s", *cr.Spec.Image, cr.Spec.Version), + Image: fmt.Sprintf("%s:%s", cr.Spec.Image.Repository, cr.Spec.Image.Tag), Ports: ports, Args: args, VolumeMounts: vmMounts, @@ -320,6 +323,7 @@ func makeSpecForVMSingle(cr *victoriametricsv1beta1.VMSingle, c *conf.BaseOperat Resources: cr.Spec.Resources, Env: envs, TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError, + ImagePullPolicy: cr.Spec.Image.PullPolicy, }, }, additionalContainers...) diff --git a/controllers/vmagent_controller.go b/controllers/vmagent_controller.go index 3fb5aa4b..7ac7a35c 100644 --- a/controllers/vmagent_controller.go +++ b/controllers/vmagent_controller.go @@ -84,7 +84,7 @@ func (r *VMAgentReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { } //create vmservicescrape for object by default - if !r.BaseConf.DisableSelfServiceMonitorCreation { + if !r.BaseConf.DisableSelfServiceScrapeCreation { err := factory.CreateVMServiceScrapeFromService(ctx, r, svc) if err != nil { reqLogger.Error(err, "cannot create serviceScrape for vmagent") diff --git a/controllers/vmalert_controller.go b/controllers/vmalert_controller.go index d92e2970..48edcca9 100644 --- a/controllers/vmalert_controller.go +++ b/controllers/vmalert_controller.go @@ -76,7 +76,7 @@ func (r *VMAlertReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { } //create vmservicescrape for object by default - if !r.BaseConf.DisableSelfServiceMonitorCreation { + if !r.BaseConf.DisableSelfServiceScrapeCreation { err := factory.CreateVMServiceScrapeFromService(ctx, r, svc) if err != nil { reqLogger.Error(err, "cannot create serviceScrape for vmalert") diff --git a/controllers/vmsingle_controller.go b/controllers/vmsingle_controller.go index cbbd0d15..55f1b870 100644 --- a/controllers/vmsingle_controller.go +++ b/controllers/vmsingle_controller.go @@ -79,7 +79,7 @@ func (r *VMSingleReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { } //create vmservicescrape for object by default - if !r.BaseConf.DisableSelfServiceMonitorCreation { + if !r.BaseConf.DisableSelfServiceScrapeCreation { err := factory.CreateVMServiceScrapeFromService(ctx, r, svc) if err != nil { reqLogger.Error(err, "cannot create serviceScrape for vmsingle") diff --git a/docs/additional-scrape.MD b/docs/additional-scrape.MD index ed03bd25..3e1b9e7e 100644 --- a/docs/additional-scrape.MD +++ b/docs/additional-scrape.MD @@ -39,7 +39,7 @@ kind: VMAgent metadata: name: example-vmagent spec: - serviceMonitorSelector: {} + serviceScrapeSelector: {} replicas: 1 serviceAccountName: vmagent additionalScrapeConfigs: diff --git a/docs/api.MD b/docs/api.MD index c6e8013a..71017d79 100644 --- a/docs/api.MD +++ b/docs/api.MD @@ -53,6 +53,7 @@ This Document documents the types introduced by the Victoria Metrics Operator to * [VMPodScrapeList](#vmpodscrapelist) * [VMPodScrapeSpec](#vmpodscrapespec) * [Image](#image) +* [VMBackup](#vmbackup) * [VMCluster](#vmcluster) * [VMClusterList](#vmclusterlist) * [VMClusterSpec](#vmclusterspec) @@ -91,11 +92,7 @@ VMAlertmanagerSpec is a specification of the desired behavior of the VMAlertmana | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the alertmanager pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | -| image | Image if specified has precedence over baseImage, tag and sha combinations. | *string | false | -| version | Version the cluster should be on. | string | false | -| tag | Tag of VMAlertmanager container image to be deployed. Defaults to the value of `version`. Version is ignored if Tag is set. | string | false | -| sha | SHA of VMAlertmanager container image to be deployed. Defaults to the value of `version`. Similar to a tag, but the SHA explicitly deploys an immutable container image. Version and Tag are ignored if SHA is set. | string | false | -| baseImage | BaseImage that is used to deploy pods, without tag. | string | false | +| image | Image - docker image settings for VMAlertmanager if no specified operator uses default config version | [Image](#image) | false | | imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMAlertmanager object, which shall be mounted into the VMAlertmanager Pods. The Secrets are mounted into /etc/alertmanager/secrets/ | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMAlertmanager object, which shall be mounted into the VMAlertmanager Pods. The ConfigMaps are mounted into /etc/alertmanager/configmaps/. | []string | false | @@ -194,9 +191,8 @@ VMAgentSpec defines the desired state of VMAgent | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the vmagent pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | -| image | Image - victoria metrics agent base image if not specified - use default from operator config | *string | false | -| version | Version for VMAgent. | string | false | -| imagePullSecrets | ImagePullSecrets optional list of references to secrets in the same namespace to use for pulling prometheus and vmagent images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | +| image | Image - docker image settings for VMAgent if no specified operator uses default config version | [Image](#image) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the vmagent object, which shall be mounted into the vmagent Pods. will be mounted at path /etc/vmagent/secrets | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the vmagent object, which shall be mounted into the vmagent Pods. will be mounted at path /etc/vmagent/configs | []string | false | | logLevel | LogLevel for VMAgent to be configured with. INFO, WARN, ERROR, FATAL, PANIC | string | false | @@ -216,21 +212,20 @@ VMAgentSpec defines the desired state of VMAgent | dnsPolicy | DNSPolicy set DNS policy for the pod | [v1.DNSPolicy](https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#pod-v1-core) | false | | scrapeInterval | ScrapeInterval defines how often scrape targets by default | string | false | | aPIServerConfig | APIServerConfig allows specifying a host and auth methods to access apiserver. If left empty, VMAgent is assumed to run inside of the cluster and will discover API servers automatically and use the pod's CA certificate and bearer token file at /var/run/secrets/kubernetes.io/serviceaccount/. | *[APIServerConfig](#apiserverconfig) | false | -| overrideHonorLabels | OverrideHonorLabels if set to true overrides all user configured honor_labels. If HonorLabels is set in ServiceMonitor or PodMonitor to true, this overrides honor_labels to false. | bool | false | +| overrideHonorLabels | OverrideHonorLabels if set to true overrides all user configured honor_labels. If HonorLabels is set in ServiceScrape or PodScrape to true, this overrides honor_labels to false. | bool | false | | overrideHonorTimestamps | OverrideHonorTimestamps allows to globally enforce honoring timestamps in all scrape configs. | bool | false | | ignoreNamespaceSelectors | IgnoreNamespaceSelectors if set to true will ignore NamespaceSelector settings from the podscrape and vmservicescrape configs, and they will only discover endpoints within their current namespace. Defaults to false. | bool | false | | enforcedNamespaceLabel | EnforcedNamespaceLabel enforces adding a namespace label of origin for each alert and metric that is user created. The label value will always be the namespace of the object that is being created. | string | false | | vmAgentExternalLabelName | VMAgentExternalLabelName Name of vmAgent external label used to denote vmAgent instance name. Defaults to the value of `prometheus`. External label will _not_ be added when value is set to empty string (`\"\"`). | *string | false | -| replicaExternalLabelName | ReplicaExternalLabelName Name of vmagent external label used to denote replica name. Defaults to the value of `prometheus_replica`. External label will _not_ be added when value is set to empty string (`\"\"`). | *string | false | | externalLabels | ExternalLabels The labels to add to any time series or alerts when communicating with external systems (federation, remote storage, etc). | map[string]string | false | | remoteWrite | RemoteWrite list of victoria metrics /some other remote write system for vm it must looks like: http://victoria-metrics-single:8429/api/v1/write or for cluster different url https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmagent#splitting-data-streams-among-multiple-systems | [][VMAgentRemoteWriteSpec](#vmagentremotewritespec) | true | | relabelConfig | RelabelConfig ConfigMap with global relabel config -remoteWrite.relabelConfig This relabeling is applied to all the collected metrics before sending them to remote storage. | *v1.ConfigMapKeySelector | false | -| serviceMonitorSelector | ServiceMonitorSelector defines ServiceMonitors to be selected for target discovery. if neither this nor podMonitorSelector are specified, configuration is unmanaged. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | -| serviceMonitorNamespaceSelector | ServiceMonitorNamespaceSelector Namespaces to be selected for ServiceMonitor discovery. If nil, only check own namespace. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | -| podMonitorSelector | PodMonitorSelector defines PodMonitors to be selected for target discovery. if neither this nor serviceMonitorSelector are specified, configuration is unmanaged. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | -| podMonitorNamespaceSelector | PodMonitorNamespaceSelector defines Namespaces to be selected for PodMonitor discovery. If nil, only check own namespace. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | +| serviceScrapeSelector | ServiceScrapeSelector defines ServiceScrapes to be selected for target discovery. if neither serviceScrapeNamespaceSelector nor serviceScrapeSelector are specified, configuration is unmanaged. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | +| serviceScrapeNamespaceSelector | ServiceScrapeNamespaceSelector Namespaces to be selected for ServiceMonitor discovery. If nil, only check own namespace. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | +| podScrapeSelector | PodScrapeSelector defines PodScrapes to be selected for target discovery. if neither PodScrapeNamespaceSelector this nor PodScrapeSelector are specified, configuration is unmanaged. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | +| podScrapeNamespaceSelector | PodScrapeNamespaceSelector defines Namespaces to be selected for PodMonitor discovery. If nil, only check own namespace. | *[metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | false | | additionalScrapeConfigs | AdditionalScrapeConfigs As scrape configs are appended, the user is responsible to make sure it is valid. Note that using this feature may expose the possibility to break upgrades of VMAgent. It is advised to review VMAgent release notes to ensure that no incompatible scrape configs are going to break VMAgent after the upgrade. | *[v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | -| arbitraryFSAccessThroughSMs | ArbitraryFSAccessThroughSMs configures whether configuration based on a service monitor can access arbitrary files on the file system of the VMAgent container e.g. bearer token files. | [ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig) | false | +| arbitraryFSAccessThroughSMs | ArbitraryFSAccessThroughSMs configures whether configuration based on a service scrape can access arbitrary files on the file system of the VMAgent container e.g. bearer token files. | [ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig) | false | | port | Port listen address | string | false | | extraArgs | ExtraArgs that will be passed to VMAgent pod for example remoteWrite.tmpDataPath: /tmp it would be converted to flag --remoteWrite.tmpDataPath=/tmp | map[string]string | false | | extraEnvs | ExtraEnvs that will be added to VMAgent pod | [][v1.EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvar-v1-core) | false | @@ -256,8 +251,8 @@ BasicAuth allow an endpoint to authenticate over basic authentication More info: | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | -| username | The secret in the service monitor namespace that contains the username for authentication. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | -| password | The secret in the service monitor namespace that contains the password for authentication. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | +| username | The secret in the service scrape namespace that contains the username for authentication. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | +| password | The secret in the service scrape namespace that contains the password for authentication. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | [Back to TOC](#table-of-contents) @@ -380,9 +375,8 @@ VMAlertSpec defines the desired state of VMAlert | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the VMAlert pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | -| image | Image victoria metrics alert base image | *string | false | -| version | Version the VMAlert should be on. | string | false | -| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling prometheus and VMAlert images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | +| image | Image - docker image settings for VMAlert if no specified operator uses default config version | [Image](#image) | false | +| imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMAlert object, which shall be mounted into the VMAlert Pods. The Secrets are mounted into /etc/vmalert/secrets/. | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMAlert object, which shall be mounted into the VMAlert Pods. The ConfigMaps are mounted into /etc/vmalert/configmaps/. | []string | false | | logFormat | LogFormat for VMAlert to be configured with. default or json | string | false | @@ -458,8 +452,7 @@ VMSingleSpec defines the desired state of VMSingle | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | | podMetadata | PodMetadata configures Labels and Annotations which are propagated to the VMSingle pods. | *[EmbeddedObjectMetadata](#embeddedobjectmetadata) | false | -| image | Image victoria metrics single base image | *string | false | -| version | Version of victoria metrics single | string | false | +| image | Image - docker image settings for VMSingle if no specified operator uses default config version | [Image](#image) | false | | imagePullSecrets | ImagePullSecrets An optional list of references to secrets in the same namespace to use for pulling images from registries see http://kubernetes.io/docs/user-guide/images#specifying-imagepullsecrets-on-a-pod | [][v1.LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#localobjectreference-v1-core) | false | | secrets | Secrets is a list of Secrets in the same namespace as the VMSingle object, which shall be mounted into the VMSingle Pods. | []string | false | | configMaps | ConfigMaps is a list of ConfigMaps in the same namespace as the VMSingle object, which shall be mounted into the VMSingle Pods. | []string | false | @@ -482,6 +475,7 @@ VMSingleSpec defines the desired state of VMSingle | port | Port listen port | string | false | | removePvcAfterDelete | RemovePvcAfterDelete - if true, controller adds ownership to pvc and after VMSingle objest deletion - pvc will be garbage collected by controller manager | bool | false | | retentionPeriod | RetentionPeriod in months | string | true | +| vmBackup | VMBackup configuration for backup | *[VMBackup](#vmbackup) | false | | extraArgs | ExtraArgs that will be passed to VMSingle pod for example remoteWrite.tmpDataPath: /tmp | map[string]string | false | | extraEnvs | ExtraEnvs that will be added to VMSingle pod | [][v1.EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvar-v1-core) | false | @@ -589,7 +583,7 @@ Endpoint defines a scrapeable endpoint serving Prometheus metrics. | scrapeTimeout | Timeout after which the scrape is ended | string | false | | tlsConfig | TLSConfig configuration to use when scraping the endpoint | *[TLSConfig](#tlsconfig) | false | | bearerTokenFile | File to read bearer token for scraping targets. | string | false | -| bearerTokenSecret | Secret to mount to read bearer token for scraping targets. The secret needs to be in the same namespace as the service monitor and accessible by the victoria-metrics operator. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | +| bearerTokenSecret | Secret to mount to read bearer token for scraping targets. The secret needs to be in the same namespace as the service scrape and accessible by the victoria-metrics operator. | [v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | | honorLabels | HonorLabels chooses the metric's labels on collisions with target labels. | bool | false | | honorTimestamps | HonorTimestamps controls whether vmagent respects the timestamps present in scraped data. | *bool | false | | basicAuth | BasicAuth allow an endpoint to authenticate over basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints | *[BasicAuth](#basicauth) | false | @@ -722,7 +716,7 @@ VMServiceScrapeSpec defines the desired state of VMServiceScrape | jobLabel | The label to use to retrieve the job name from. | string | false | | targetLabels | TargetLabels transfers labels on the Kubernetes Service onto the target. | []string | false | | podTargetLabels | PodTargetLabels transfers labels on the Kubernetes Pod onto the target. | []string | false | -| endpoints | A list of endpoints allowed as part of this ServiceMonitor. | [][Endpoint](#endpoint) | true | +| endpoints | A list of endpoints allowed as part of this ServiceScrape. | [][Endpoint](#endpoint) | true | | selector | Selector to select Endpoints objects. | [metav1.LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta) | true | | namespaceSelector | Selector to select which namespaces the Endpoints objects are discovered from. | [NamespaceSelector](#namespaceselector) | false | | sampleLimit | SampleLimit defines per-scrape limit on number of scraped samples that will be accepted. | uint64 | false | @@ -731,7 +725,7 @@ VMServiceScrapeSpec defines the desired state of VMServiceScrape ## ArbitraryFSAccessThroughSMsConfig -ArbitraryFSAccessThroughSMsConfig enables users to configure, whether a service monitor selected by the vmagent instance is allowed to use arbitrary files on the file system of the vmagent container. This is the case when e.g. a service scrape specifies a BearerTokenFile in an endpoint. A malicious user could create a service monitor selecting arbitrary secret files 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. +ArbitraryFSAccessThroughSMsConfig enables users to configure, whether a service scrape selected by the vmagent instance is allowed to use arbitrary files on the file system of the vmagent container. This is the case when e.g. a service scrape specifies a BearerTokenFile in an endpoint. A malicious user could create a service scrape selecting arbitrary secret files 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. | Field | Description | Scheme | Required | | ----- | ----------- | ------ | -------- | @@ -810,6 +804,29 @@ Image defines docker image settings [Back to TOC](#table-of-contents) +## VMBackup + + + +| Field | Description | Scheme | Required | +| ----- | ----------- | ------ | -------- | +| concurrency | Defines number of concurrent workers. Higher concurrency may reduce backup duration (default 10) | *int32 | false | +| destintaion | Defines destination for backup | string | false | +| customS3Endpoint | Custom S3 endpoint for use with S3-compatible storages (e.g. MinIO). S3 is used if not set | *string | false | +| credentialsSecret | CredentialsSecret is secret in the same namespace for access to remote storage The secret is mounted into /etc/vm/creds. | *[v1.SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#secretkeyselector-v1-core) | false | +| disableHourly | Defines if hourly backups disabled (default false) | *bool | false | +| disableDaily | Defines if daily backups disabled (default false) | *bool | false | +| disableWeekly | Defines if weekly backups disabled (default false) | *bool | false | +| disableMonthly | Defines if monthly backups disabled (default false) | *bool | false | +| image | Image - docker image settings for VMBackuper | [Image](#image) | false | +| port | Port for health check connections | string | false | +| logFormat | LogFormat for VMSelect to be configured with. default or json | *string | false | +| logLevel | LogLevel for VMSelect to be configured with. | *string | false | +| resources | Resources container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ if not defined default resources from operator config will be used | [v1.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#resourcerequirements-v1-core) | false | +| extraArgs | extra args like maxBytesPerSecond default 0 | map[string]string | false | + +[Back to TOC](#table-of-contents) + ## VMCluster VMCluster represents a Victoria-Metrics database cluster @@ -962,6 +979,7 @@ VMClusterStatus defines the observed state of VMCluster | port | Port for health check connetions | string | false | | vmInsertPort | VMInsertPort for VMInsert connections | string | false | | vmSelectPort | VMSelectPort for VMSelect connections | string | false | +| vmBackup | VMBackup configuration for backup | *[VMBackup](#vmbackup) | false | | extraArgs | | map[string]string | false | | extraEnvs | ExtraEnvs that will be added to VMSelect pod | [][v1.EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvar-v1-core) | false | diff --git a/docs/high-availability.MD b/docs/high-availability.MD index 8c93a2e3..ca95a977 100644 --- a/docs/high-availability.MD +++ b/docs/high-availability.MD @@ -9,16 +9,50 @@ To run VMAgent in a highly available manner you have to configure deduplication Then increase replicas for VMAgent. +create `VMSingle` with dedup flag +```yaml +cat < 1` + +```yaml +cat << 'EOF' | kubectl apply -f - +apiVersion: operator.victoriametrics.com/v1beta1 +kind: VMRule +metadata: + name: example-vmrule-reload-config + labels: + project: devops +spec: + groups: + - name: vmalert + rules: + - alert: vmalert config reload error + expr: delta(vmalert_config_last_reload_errors_total[5m]) > 0 + for: 10s + labels: + severity: major + job: "{{ $labels.job }}" + annotations: + value: "{{ $value }}" + description: 'error reloading vmalert config, reload count for 5 min {{ $value }}' +EOF +``` + + Ensure, that new alert was started: + ```bash +kubectl logs vmalert-example-vmalert-6f8748c6f9-hcfrr vmalert +2020-08-03T09:07:49.772Z info VictoriaMetrics/app/vmalert/web.go:45 api config reload was called, sending sighup +2020-08-03T09:07:49.772Z info VictoriaMetrics/app/vmalert/main.go:115 SIGHUP received. Going to reload rules ["/etc/vmalert/config/vm-example-vmalert-rulefiles-0/*.yaml"] ... +2020-08-03T09:07:49.772Z info VictoriaMetrics/app/vmalert/manager.go:83 reading rules configuration file from "/etc/vmalert/config/vm-example-vmalert-rulefiles-0/*.yaml" +2020-08-03T09:07:49.773Z info VictoriaMetrics/app/vmalert/group.go:169 group "vmAlertGroup": received stop signal +2020-08-03T09:07:49.773Z info VictoriaMetrics/app/vmalert/main.go:124 Rules reloaded successfully from ["/etc/vmalert/config/vm-example-vmalert-rulefiles-0/*.yaml"] +2020-08-03T09:07:49.773Z info VictoriaMetrics/app/vmalert/group.go:153 group "vmalert" started with interval 30s + +``` + + Let's trigger it by adding some incorrect rule + +```yaml +cat << 'EOF' | kubectl apply -f - +apiVersion: operator.victoriametrics.com/v1beta1 +kind: VMRule +metadata: + name: example-vmrule-incorrect-rule + labels: + project: devops +spec: + groups: + - name: incorrect rule + rules: + - alert: vmalert bad config + expr: bad expression + for: 10s + labels: + severity: major + annotations: + value: "{{ $badValue | bad function }}" +EOF +``` + +`VMAlert` will report incorrect rule config and fire alert: +```bash +2020-08-03T09:11:40.672Z info VictoriaMetrics/app/vmalert/main.go:115 SIGHUP received. Going to reload rules ["/etc/vmalert/config/vm-example-vmalert-rulefiles-0/*.yaml"] ... +2020-08-03T09:11:40.672Z info VictoriaMetrics/app/vmalert/manager.go:83 reading rules configuration file from "/etc/vmalert/config/vm-example-vmalert-rulefiles-0/*.yaml" +2020-08-03T09:11:40.673Z error VictoriaMetrics/app/vmalert/main.go:119 error while reloading rules: cannot parse configuration file: invalid group "incorrect rule" in file "/etc/vmalert/config/vm-example-vmalert-rulefiles-0/default-example-vmrule-incorrect-rule.yaml": invalid rule "incorrect rule"."vmalert bad config": invalid expression: unparsed data left: "expression" +``` + +Clean up incorrect rule: +```bash +kubectl delete vmrule example-vmrule-incorrect-rule ``` diff --git a/docs/relabeling.MD b/docs/relabeling.MD new file mode 100644 index 00000000..e7a348c6 --- /dev/null +++ b/docs/relabeling.MD @@ -0,0 +1,63 @@ +## VMAgent relabel + + +`VMAgent` supports global relabeling for all metrics and per remoteWrite target relabel config. + + It also has some extra options, you can check it [docs](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmagent/README.md#relabeling) + + First, You have to create `Confimap` with relabeling configuration + + ```yaml +cat << EOF | kubectl apply -f - +apiVersion: v1 +kind: ConfigMap +metadata: + name: vmagent-relabel +data: + global-relabel.yaml: | + - target_label: bar + - source_labels: [aa] + separator: "foobar" + regex: "foo.+bar" + target_label: aaa + replacement: "xxx" + - action: keep + source_labels: [aaa] + - action: drop + source_labels: [aaa] + target-1-relabel.yaml: | + - action: keep_if_equal + source_labels: [foo, bar] + - action: drop_if_equal + source_labels: [foo, bar] +EOF +``` + +Second, add `relabelConfig` to `VMagent` spec for global relabeling with name of `Configmap` - `vmagent-relabel` and key `global-relabel.yaml`. + For relabeling per remoteWrite target, add `urlRelabelConfig` name of `Configmap` - `vmagent-relabel` and key `target-1-relabel.yaml` to one of remoteWrite target for relabeling only +for those target. + +```yaml +cat <