Repository: VictoriaMetrics/operator

Issue:
Custom Labels are overwritten with default Selector Labels
The problem is that the custom labels are overwritten with default Selector Labels in PodLabels and AllLabels methods during merging when conflicts happen in the function (https://github.com/kubernetes/apimachinery/blob/v0.32.3/pkg/labels/labels.go#L118) for VM components.
PR has been provided: https://github.com/VictoriaMetrics/operator/pull/1287

Hints from issue comments:
@f41gh7:   The purpose of Selectors Labels to identify set of resources that belong to particular object. Like Deployment has  pod selector labels to quickly identify Pods that belongs to it.

 In the same way operator uses Selector Labels to list resources created on behalf of CRD objects. For example, vmalert may have multiple ConfigMaps with configuration. If labels on configmap will mismatch selector labels, operator will no be able to list configmap and properly update it's content with new vmalert configuration.

Changing built-in values of Selector Labels is not possible. It'll introduce breaking changes and will make operator incompatible with previous versions.

 I think, we should document common selector labels added to created resources and document why it cannot be changed.@AndrewChubatiuk: added section about immutable labels to [docs](https://docs.victoriametrics.com/operator/configuration/#labels)

Solution patch:
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index d9398500..2f429ac3 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -25,6 +25,7 @@ aliases:
 
 * BUGFIX: [vmalertmanager](https://docs.victoriametrics.com/operator/resources/vmalertmanager/): check `mute_time_intervals` in subroutes: See [#1618](https://github.com/VictoriaMetrics/operator/issues/1618).
 * BUGFIX: [vmoperator](https://docs.victoriametrics.com/operator/): remove incorrect key argument in structured log for when the actual PVC storage size is larger than the currently configured size and properly indicate which is the new and which is the existing size: See PR [#1636](https://github.com/VictoriaMetrics/operator/pull/1636) for details.
+* BUGFIX: [converter](https://docs.victoriametrics.com/operator/integrations/prometheus/#objects-conversion): properly convert Prometheus ScrapeConfig `scrapeInterval` into VM ScrapeConfig `scrape_interval`. Before it was ignored. See [#1645](https://github.com/VictoriaMetrics/operator/issues/1645).
 
 * Dependency: [vmoperator](https://docs.victoriametrics.com/operator/): Updated default versions for VT apps to [v0.5.0](https://github.com/VictoriaMetrics/VictoriaTraces/releases/tag/v0.5.0) version.
 
diff --git a/docs/configuration.md b/docs/configuration.md
index 238050de..64a920f8 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -109,6 +109,19 @@ kubectl get deployment -n vm vm-operator \
 # VM_VMSINGLEDEFAULT_RESOURCE_LIMIT_CPU
 ```
 
+## Labels
+
+Each managed by operator CRs resource has a set of labels, which is a result of `spec.managedMetadata.labels` and predefined immutable labels merge.
+Immutable labels are needed to simplify dependent resources discovery and guarantee predictability in resources interconnection. List of immutable labels:
+
+* `app.kubernetes.io/name`
+* `app.kubernetes.io/instance`
+* `app.kubernetes.io/component`
+* `app.kubernetes.io/part-of`
+* `managed-by`
+
+In case if `spec.managedMetadata.labels` and immutable labels collision, least ones have higher priority.
+
 ## Flags
 
 Run this command to see all flags your operator supports:
diff --git a/internal/controller/operator/converter/v1alpha1/apis.go b/internal/controller/operator/converter/v1alpha1/apis.go
index 149d48c7..eb7b1805 100644
--- a/internal/controller/operator/converter/v1alpha1/apis.go
+++ b/internal/controller/operator/converter/v1alpha1/apis.go
@@ -145,6 +145,9 @@ func ConvertScrapeConfig(promscrapeConfig *promv1alpha1.ScrapeConfig, conf *conf
 	cs.Spec.RelabelConfigs = converter.ConvertRelabelConfig(promscrapeConfig.Spec.RelabelConfigs)
 	cs.Spec.MetricRelabelConfigs = converter.ConvertRelabelConfig(promscrapeConfig.Spec.MetricRelabelConfigs)
 	cs.Spec.Path = ptr.Deref(promscrapeConfig.Spec.MetricsPath, "")
+	if promscrapeConfig.Spec.ScrapeInterval != nil {
+		cs.Spec.ScrapeInterval = string(*promscrapeConfig.Spec.ScrapeInterval)
+	}
 
 	if promscrapeConfig.Spec.EnableCompression != nil {
 		cs.Spec.VMScrapeParams = &vmv1beta1.VMScrapeParams{



Test patch:
diff --git a/internal/controller/operator/converter/v1alpha1/apis_test.go b/internal/controller/operator/converter/v1alpha1/apis_test.go
index 36d8f0d0..361a14fe 100644
--- a/internal/controller/operator/converter/v1alpha1/apis_test.go
+++ b/internal/controller/operator/converter/v1alpha1/apis_test.go
@@ -131,7 +131,8 @@ func TestConvertScrapeConfig(t *testing.T) {
 					Username: corev1.SecretKeySelector{Key: "username"},
 					Password: corev1.SecretKeySelector{Key: "password"},
 				},
-				MetricsPath: ptr.To("/test"),
+				ScrapeInterval: promv1.DurationPointer("5m"),
+				MetricsPath:    ptr.To("/test"),
 				ProxyConfig: promv1.ProxyConfig{
 					ProxyURL: ptr.To("http://proxy.com"),
 				},
@@ -154,6 +155,7 @@ func TestConvertScrapeConfig(t *testing.T) {
 					HonorTimestamps: ptr.To(true),
 					VMScrapeParams:  &vmv1beta1.VMScrapeParams{DisableCompression: ptr.To(false)},
 					Path:            "/test",
+					ScrapeInterval:  "5m",
 				},
 				StaticConfigs: []vmv1beta1.StaticConfig{{
 					Targets: []string{"target-1", "target-2"},