From 4b3763caed1b3cba3f5688ba11f990dce4cb7f6a Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 6 Nov 2024 17:53:30 +0100 Subject: [PATCH 01/20] update mco api Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../multiclusterobservability_types.go | 57 +++++++++++++++++++ ...bility-operator.clusterserviceversion.yaml | 2 +- ...gement.io_multiclusterobservabilities.yaml | 32 +++++++++++ ...gement.io_multiclusterobservabilities.yaml | 32 +++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go b/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go index 5d074e09b..bc47ab830 100644 --- a/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go +++ b/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go @@ -68,6 +68,16 @@ type PlatformLogsCollectionSpec struct { Enabled bool `json:"enabled,omitempty"` } +// MetricsCollectionSpec defines the spec for the addon to collect and forward metrics +// from fleet managed clusters. +type MetricsCollectionSpec struct { + // Enabled defines a flag to enable/disable the platform metrics collection. + // + // +optional + // +kubebuilder:validation:Optional + Enabled bool `json:"enabled,omitempty"` +} + // PlatformLogsSpec defines the spec for the addon to collect, forward and store logs // from fleet managed clusters. type PlatformLogsSpec struct { @@ -79,6 +89,17 @@ type PlatformLogsSpec struct { Collection PlatformLogsCollectionSpec `json:"collection,omitempty"` } +// PlatformMetricsSpec defines the spec for the addon to collect, forward and store metrics +// from fleet managed clusters. +type PlatformMetricsSpec struct { + // Collection defines the spec for the addon to collect and forward metrics + // from fleet managed clusters. + // + // +optional + // +kubebuilder:validation:Optional + Collection MetricsCollectionSpec `json:"collection,omitempty"` +} + // PlatformCapabilitiesSpec defines the observability capabilities managed by the addon // for platform components. type PlatformCapabilitiesSpec struct { @@ -88,6 +109,13 @@ type PlatformCapabilitiesSpec struct { // +optional // +kubebuilder:validation:Optional Logs PlatformLogsSpec `json:"logs,omitempty"` + + // Metrics defines the configuration spec for collecting and storing metrics from + // platform components running on fleet managed clusters. + // + // +optional + // +kubebuilder:validation:Optional + Metrics PlatformMetricsSpec `json:"metrics,omitempty"` } // ClusterLogForwarderSpec defines the spec for the addon to collect and forward logs @@ -110,6 +138,16 @@ type UserWorkloadLogsCollectionSpec struct { ClusterLogForwarder ClusterLogForwarderSpec `json:"clusterLogForwarder,omitempty"` } +// UserWorkloadLogsSpec defines the spec for the addon to collect,forward and store logs +// from user workloads hosted on fleet managed clusters. +type UserWorkloadMetricsCollectionSpec struct { + // Enabled defines a flag to enable/disable the platform metrics collection. + // + // +optional + // +kubebuilder:validation:Optional + Enabled bool `json:"enabled,omitempty"` +} + // UserWorkloadLogsSpec defines the spec for the addon to collect,forward and store logs // from user workloads hosted on fleet managed clusters. type UserWorkloadLogsSpec struct { @@ -121,6 +159,17 @@ type UserWorkloadLogsSpec struct { Collection UserWorkloadLogsCollectionSpec `json:"collection,omitempty"` } +// UserWorkloadMetricsSpec defines the spec for the addon to collect, forward and store metrics +// from user workloads hosted on fleet managed clusters. +type UserWorkloadMetricsSpec struct { + // Collection defines the spec for the addon to collect and forward metrics + // from user workloads hosted on fleet managed clusters. + // + // +optional + // +kubebuilder:validation:Optional + Collection UserWorkloadMetricsCollectionSpec `json:"collection,omitempty"` +} + // OpenTelemetryCollectorSpec defines the spec for the addon to collect and forward observability signals // using the OpenTelemetryCollector custom resource. type OpenTelemetryCollectorSpec struct { @@ -176,6 +225,14 @@ type UserWorkloadCapabilitiesSpec struct { // +optional // +kubebuilder:validation:Optional Logs UserWorkloadLogsSpec `json:"logs,omitempty"` + + // Metrics defines the spec for the addon to collect, forward and store metrics + // from user workloads hosted on fleet managed clusters. + // + // +optional + // +kubebuilder:validation:Optional + Metrics UserWorkloadMetricsSpec `json:"metrics,omitempty"` + // Traces defines the spec for the addon to collect, forward and store traces // from user workloads hosted on fleet managed clusters. // diff --git a/operators/multiclusterobservability/bundle/manifests/multicluster-observability-operator.clusterserviceversion.yaml b/operators/multiclusterobservability/bundle/manifests/multicluster-observability-operator.clusterserviceversion.yaml index 7a3c5347c..42836354a 100644 --- a/operators/multiclusterobservability/bundle/manifests/multicluster-observability-operator.clusterserviceversion.yaml +++ b/operators/multiclusterobservability/bundle/manifests/multicluster-observability-operator.clusterserviceversion.yaml @@ -49,7 +49,7 @@ metadata: } ] capabilities: Basic Install - createdAt: "2024-09-23T12:07:01Z" + createdAt: "2024-11-06T16:52:14Z" operators.operatorframework.io/builder: operator-sdk-v1.34.2 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 name: multicluster-observability-operator.v0.1.0 diff --git a/operators/multiclusterobservability/bundle/manifests/observability.open-cluster-management.io_multiclusterobservabilities.yaml b/operators/multiclusterobservability/bundle/manifests/observability.open-cluster-management.io_multiclusterobservabilities.yaml index 3e0adaed7..7bc25232a 100644 --- a/operators/multiclusterobservability/bundle/manifests/observability.open-cluster-management.io_multiclusterobservabilities.yaml +++ b/operators/multiclusterobservability/bundle/manifests/observability.open-cluster-management.io_multiclusterobservabilities.yaml @@ -10036,6 +10036,22 @@ spec: type: boolean type: object type: object + metrics: + description: |- + Metrics defines the configuration spec for collecting and storing metrics from + platform components running on fleet managed clusters. + properties: + collection: + description: |- + Collection defines the spec for the addon to collect and forward metrics + from fleet managed clusters. + properties: + enabled: + description: Enabled defines a flag to enable/disable + the platform metrics collection. + type: boolean + type: object + type: object type: object userWorkloads: description: |- @@ -10066,6 +10082,22 @@ spec: type: object type: object type: object + metrics: + description: |- + Metrics defines the spec for the addon to collect, forward and store metrics + from user workloads hosted on fleet managed clusters. + properties: + collection: + description: |- + Collection defines the spec for the addon to collect and forward metrics + from user workloads hosted on fleet managed clusters. + properties: + enabled: + description: Enabled defines a flag to enable/disable + the platform metrics collection. + type: boolean + type: object + type: object traces: description: |- Traces defines the spec for the addon to collect, forward and store traces diff --git a/operators/multiclusterobservability/config/crd/bases/observability.open-cluster-management.io_multiclusterobservabilities.yaml b/operators/multiclusterobservability/config/crd/bases/observability.open-cluster-management.io_multiclusterobservabilities.yaml index 19b8365dc..9663dffdb 100644 --- a/operators/multiclusterobservability/config/crd/bases/observability.open-cluster-management.io_multiclusterobservabilities.yaml +++ b/operators/multiclusterobservability/config/crd/bases/observability.open-cluster-management.io_multiclusterobservabilities.yaml @@ -10020,6 +10020,22 @@ spec: type: boolean type: object type: object + metrics: + description: |- + Metrics defines the configuration spec for collecting and storing metrics from + platform components running on fleet managed clusters. + properties: + collection: + description: |- + Collection defines the spec for the addon to collect and forward metrics + from fleet managed clusters. + properties: + enabled: + description: Enabled defines a flag to enable/disable + the platform metrics collection. + type: boolean + type: object + type: object type: object userWorkloads: description: |- @@ -10050,6 +10066,22 @@ spec: type: object type: object type: object + metrics: + description: |- + Metrics defines the spec for the addon to collect, forward and store metrics + from user workloads hosted on fleet managed clusters. + properties: + collection: + description: |- + Collection defines the spec for the addon to collect and forward metrics + from user workloads hosted on fleet managed clusters. + properties: + enabled: + description: Enabled defines a flag to enable/disable + the platform metrics collection. + type: boolean + type: object + type: object traces: description: |- Traces defines the spec for the addon to collect, forward and store traces From 7f72d35d2470cfe1cce43e5922661cc4a00638aa Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:08:29 +0100 Subject: [PATCH 02/20] add supported and default configs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index 19b2dfce6..e790adf59 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -29,6 +29,15 @@ spec: # Describes the default Instrumentation type applied to all managed clusters. - group: opentelemetry.io resource: instrumentations + # Metrics forwarding configuration types. + - group: monitoring.coreos.com + resource: prometheusagents + - group: monitoring.coreos.com + resource: scrapeconfigs + - group: monitoring.coreos.com + resource: prometheusrules + - group: "" + resource: configmaps # For the proxy sidecar configuration of the prometheus agent installStrategy: type: Placements placements: @@ -47,3 +56,38 @@ spec: resource: instrumentations name: instance namespace: open-cluster-management-observability + # Default metrics forwarding configuration for the ACM platform metrics collector + - group: monitoring.coreos.com + resource: prometheusagents + name: acm-platform-metrics-collector-default + namespace: open-cluster-management-observability + - group: "" + resource: configmaps + name: acm-platform-metrics-collector-default-envoy-config + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: scrapeconfigs + name: platform-metrics-default + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: prometheusrules + name: platform-rules-default + namespace: open-cluster-management-observability + # Default metrics forwarding configuration for the ACM user workload metrics collector + - group: monitoring.coreos.com + resource: prometheusagents + name: acm-user-workload-metrics-collector-default + namespace: open-cluster-management-observability + - group: "" + resource: configmaps + name: acm-user-workload-metrics-collector-default-envoy-config + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: scrapeconfigs + name: user-workload-metrics-default + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: prometheusrules + name: user-workload-rules-default + namespace: open-cluster-management-observability + From f36a552fa7e7fc92db07ed7842edfce91f70b434 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:09:03 +0100 Subject: [PATCH 03/20] add customized variables Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../pkg/config/config.go | 2 ++ .../pkg/rendering/renderer_mcoa.go | 28 ++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/operators/multiclusterobservability/pkg/config/config.go b/operators/multiclusterobservability/pkg/config/config.go index 5c8443544..0a87b1731 100644 --- a/operators/multiclusterobservability/pkg/config/config.go +++ b/operators/multiclusterobservability/pkg/config/config.go @@ -229,6 +229,7 @@ const ( ClusterLogForwarderCRDName = "clusterlogforwarders.observability.openshift.io" OpenTelemetryCollectorCRDName = "opentelemetrycollectors.opentelemetry.io" InstrumentationCRDName = "instrumentations.opentelemetry.io" + PrometheusAgentCRDName = "prometheusagents.v1alpha1.monitoring.coreos.com" ) var ( @@ -236,6 +237,7 @@ var ( ClusterLogForwarderCRDName: "v1", OpenTelemetryCollectorCRDName: "v1beta1", InstrumentationCRDName: "v1alpha1", + PrometheusAgentCRDName: "v1alpha1", } ) diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 165dac218..5ed11366c 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -5,6 +5,7 @@ package rendering import ( + "context" "fmt" appsv1 "k8s.io/api/apps/v1" @@ -25,10 +26,13 @@ const ( cmaoKind = "ClusterManagementAddOn" // AODC CustomizedVariable Names - namePlatformLogsCollection = "platformLogsCollection" - nameUserWorkloadLogsCollection = "userWorkloadLogsCollection" - nameUserWorkloadTracesCollection = "userWorkloadTracesCollection" - nameUserWorkloadInstrumentation = "userWorkloadInstrumentation" + namePlatformLogsCollection = "platformLogsCollection" + namePlatformMetricsCollection = "platformMetricsCollection" + nameUserWorkloadLogsCollection = "userWorkloadLogsCollection" + nameUserWorkloadTracesCollection = "userWorkloadTracesCollection" + nameUserWorkloadInstrumentation = "userWorkloadInstrumentation" + nameUserWorkloadMetricsCollection = "userWorkloadMetricsCollection" + nameSignalsHubEndpoint = "signalsHubEndpoint" ) type MCOARendererOptions struct { @@ -195,6 +199,10 @@ func (r *MCORenderer) renderAddonDeploymentConfig( fqdn := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.ClusterLogForwarderCRDName) appendCustomVar(aodc, namePlatformLogsCollection, fqdn) } + if cs.Platform.Metrics.Collection.Enabled { + fqdn := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.PrometheusAgentCRDName) + appendCustomVar(aodc, namePlatformMetricsCollection, fqdn) + } } if cs.UserWorkloads != nil { @@ -202,6 +210,10 @@ func (r *MCORenderer) renderAddonDeploymentConfig( fqdn := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.ClusterLogForwarderCRDName) appendCustomVar(aodc, nameUserWorkloadLogsCollection, fqdn) } + if cs.UserWorkloads.Metrics.Collection.Enabled { + fqdn := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.PrometheusAgentCRDName) + appendCustomVar(aodc, nameUserWorkloadMetricsCollection, fqdn) + } if cs.UserWorkloads.Traces.Collection.Collector.Enabled { fqdn := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.OpenTelemetryCollectorCRDName) appendCustomVar(aodc, nameUserWorkloadTracesCollection, fqdn) @@ -212,6 +224,14 @@ func (r *MCORenderer) renderAddonDeploymentConfig( } } + if (cs.Platform != nil && cs.Platform.Metrics.Collection.Enabled) || (cs.UserWorkloads != nil && cs.UserWorkloads.Metrics.Collection.Enabled) { + obsAPIURL, err := mcoconfig.GetObsAPIExternalURL(context.TODO(), r.kubeClient, namespace) + if err != nil { + return nil, fmt.Errorf("failed to get the Observatorium API URL: %w", err) + } + appendCustomVar(aodc, nameSignalsHubEndpoint, obsAPIURL.Host) + } + u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(aodc) if err != nil { return nil, err From 9e0f78f08cf6c620ca556eb5c4156a5190540ec9 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Thu, 7 Nov 2024 15:05:11 +0100 Subject: [PATCH 04/20] fix test Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- operators/multiclusterobservability/pkg/config/config_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/operators/multiclusterobservability/pkg/config/config_test.go b/operators/multiclusterobservability/pkg/config/config_test.go index 9952b5694..524f620a3 100644 --- a/operators/multiclusterobservability/pkg/config/config_test.go +++ b/operators/multiclusterobservability/pkg/config/config_test.go @@ -809,6 +809,7 @@ func TestGetMCOASupportedCRDNames(t *testing.T) { "clusterlogforwarders.observability.openshift.io", "opentelemetrycollectors.opentelemetry.io", "instrumentations.opentelemetry.io", + "prometheusagents.v1alpha1.monitoring.coreos.com", } result := GetMCOASupportedCRDNames() From b75d7ac2e784c807f616165870ab4cbedd8f8d91 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:53:07 +0100 Subject: [PATCH 05/20] add metrics in mcoa enabled Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../multiclusterobservability_types.go | 6 +- .../pkg/rendering/renderer_mcoa.go | 3 +- .../pkg/rendering/renderer_mcoa_test.go | 57 +++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go b/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go index bc47ab830..ad679a15d 100644 --- a/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go +++ b/operators/multiclusterobservability/api/v1beta2/multiclusterobservability_types.go @@ -68,9 +68,9 @@ type PlatformLogsCollectionSpec struct { Enabled bool `json:"enabled,omitempty"` } -// MetricsCollectionSpec defines the spec for the addon to collect and forward metrics +// PlatformMetricsCollectionSpec defines the spec for the addon to collect and forward metrics // from fleet managed clusters. -type MetricsCollectionSpec struct { +type PlatformMetricsCollectionSpec struct { // Enabled defines a flag to enable/disable the platform metrics collection. // // +optional @@ -97,7 +97,7 @@ type PlatformMetricsSpec struct { // // +optional // +kubebuilder:validation:Optional - Collection MetricsCollectionSpec `json:"collection,omitempty"` + Collection PlatformMetricsCollectionSpec `json:"collection,omitempty"` } // PlatformCapabilitiesSpec defines the observability capabilities managed by the addon diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 5ed11366c..2bb312476 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -295,12 +295,13 @@ func MCOAEnabled(cr *obv1beta2.MultiClusterObservability) bool { } mcoaEnabled := false if cr.Spec.Capabilities.Platform != nil { - mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.Platform.Logs.Collection.Enabled + mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.Platform.Logs.Collection.Enabled || cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled } if cr.Spec.Capabilities.UserWorkloads != nil { mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.UserWorkloads.Logs.Collection.ClusterLogForwarder.Enabled mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled + mcoaEnabled = mcoaEnabled || cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled } return mcoaEnabled } diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go index 720f314e3..bf6d10cd7 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go @@ -133,6 +133,11 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { Enabled: true, }, }, + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, }, UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ Logs: mcov1beta2.UserWorkloadLogsSpec{ @@ -142,6 +147,11 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { }, }, }, + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, Traces: mcov1beta2.UserWorkloadTracesSpec{ Collection: mcov1beta2.OpenTelemetryCollectionSpec{ Collector: mcov1beta2.OpenTelemetryCollectorSpec{ @@ -169,12 +179,15 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { clfV1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.ClusterLogForwarderCRDName) otelV1beta1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.OpenTelemetryCollectorCRDName) instrV1alpha1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.InstrumentationCRDName) + promV1alpha1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.PrometheusAgentCRDName) assert.Len(t, got.Spec.CustomizedVariables, 5) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: namePlatformLogsCollection, Value: clfV1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadLogsCollection, Value: clfV1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadTracesCollection, Value: otelV1beta1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadInstrumentation, Value: instrV1alpha1}) + assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: namePlatformMetricsCollection, Value: promV1alpha1}) + assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadMetricsCollection, Value: promV1alpha1}) } func TestMCOAEnabled(t *testing.T) { @@ -228,6 +241,40 @@ func TestMCOAEnabled(t *testing.T) { }, expected: true, }, + { + name: "Platform metrics collection enabled", + cr: &mcov1beta2.MultiClusterObservability{ + Spec: mcov1beta2.MultiClusterObservabilitySpec{ + Capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + }, + }, + expected: true, + }, + { + name: "User workloads metrics collection enabled", + cr: &mcov1beta2.MultiClusterObservability{ + Spec: mcov1beta2.MultiClusterObservabilitySpec{ + Capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + }, + }, + expected: true, + }, { name: "User workloads traces collection enabled", cr: &mcov1beta2.MultiClusterObservability{ @@ -261,6 +308,11 @@ func TestMCOAEnabled(t *testing.T) { Enabled: false, }, }, + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: false, + }, + }, }, UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ Logs: mcov1beta2.UserWorkloadLogsSpec{ @@ -270,6 +322,11 @@ func TestMCOAEnabled(t *testing.T) { }, }, }, + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: false, + }, + }, Traces: mcov1beta2.UserWorkloadTracesSpec{ Collection: mcov1beta2.OpenTelemetryCollectionSpec{ Collector: mcov1beta2.OpenTelemetryCollectorSpec{ From bcb0d7b7ea43de2c12dd4fc938d2f25cce8b59e4 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:53:09 +0100 Subject: [PATCH 06/20] fix crd name Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- operators/multiclusterobservability/pkg/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/pkg/config/config.go b/operators/multiclusterobservability/pkg/config/config.go index 0a87b1731..c663b857d 100644 --- a/operators/multiclusterobservability/pkg/config/config.go +++ b/operators/multiclusterobservability/pkg/config/config.go @@ -229,7 +229,7 @@ const ( ClusterLogForwarderCRDName = "clusterlogforwarders.observability.openshift.io" OpenTelemetryCollectorCRDName = "opentelemetrycollectors.opentelemetry.io" InstrumentationCRDName = "instrumentations.opentelemetry.io" - PrometheusAgentCRDName = "prometheusagents.v1alpha1.monitoring.coreos.com" + PrometheusAgentCRDName = "prometheusagents.monitoring.coreos.com" ) var ( From 4f10a3147e08a1f87b9fc1df11967b6aa393e0dc Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:52:32 +0100 Subject: [PATCH 07/20] update mcoa role Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../base/multicluster-observability-addon/cluster_role.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml index 7f8e3e900..a5ee8a036 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml @@ -68,3 +68,7 @@ - apiGroups: ["opentelemetry.io"] resources: ["opentelemetrycollectors", "instrumentations"] verbs: ["get", "list", "watch"] + # Role for addon to perform prometheus specific actions + - apiGroups: ["monitoring.coreos.com"] + resources: ["prometheuses", "scraperconfigs", "prometheusrules"] + verbs: ["get", "list", "watch"] From 4ce02a26ff2713857cff2e8d6e9e2fdbdb98cbb2 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:00:16 +0100 Subject: [PATCH 08/20] fix role Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../base/multicluster-observability-addon/cluster_role.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml index a5ee8a036..434d76baf 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml @@ -70,5 +70,5 @@ verbs: ["get", "list", "watch"] # Role for addon to perform prometheus specific actions - apiGroups: ["monitoring.coreos.com"] - resources: ["prometheuses", "scraperconfigs", "prometheusrules"] + resources: ["prometheusagents", "scraperconfigs", "prometheusrules"] verbs: ["get", "list", "watch"] From a5798556ee4498414d1295f8ee216ed5eb5bd213 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:14:25 +0100 Subject: [PATCH 09/20] fix role typo Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../base/multicluster-observability-addon/cluster_role.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml index 434d76baf..5574ac3c0 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml @@ -70,5 +70,5 @@ verbs: ["get", "list", "watch"] # Role for addon to perform prometheus specific actions - apiGroups: ["monitoring.coreos.com"] - resources: ["prometheusagents", "scraperconfigs", "prometheusrules"] + resources: ["prometheusagents", "scrapeconfigs", "prometheusrules"] verbs: ["get", "list", "watch"] From 18bb47027b8bf48c0c89b52c3b499f838fb4f96a Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:50:39 +0100 Subject: [PATCH 10/20] add write perms for cfg resources Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../base/multicluster-observability-addon/cluster_role.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml index 5574ac3c0..183aad27d 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_role.yaml @@ -71,4 +71,4 @@ # Role for addon to perform prometheus specific actions - apiGroups: ["monitoring.coreos.com"] resources: ["prometheusagents", "scrapeconfigs", "prometheusrules"] - verbs: ["get", "list", "watch"] + verbs: ["get", "list", "watch", "create", "update", "delete"] From aefd504d1cf8a6a5bdc264c77a0162d7f548decb Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:48:56 +0100 Subject: [PATCH 11/20] fix tests Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../pkg/config/config_test.go | 2 +- .../pkg/rendering/renderer_mcoa_test.go | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/operators/multiclusterobservability/pkg/config/config_test.go b/operators/multiclusterobservability/pkg/config/config_test.go index 524f620a3..2efe5e25e 100644 --- a/operators/multiclusterobservability/pkg/config/config_test.go +++ b/operators/multiclusterobservability/pkg/config/config_test.go @@ -809,7 +809,7 @@ func TestGetMCOASupportedCRDNames(t *testing.T) { "clusterlogforwarders.observability.openshift.io", "opentelemetrycollectors.opentelemetry.io", "instrumentations.opentelemetry.io", - "prometheusagents.v1alpha1.monitoring.coreos.com", + "prometheusagents.monitoring.coreos.com", } result := GetMCOASupportedCRDNames() diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go index bf6d10cd7..df5ab7456 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go @@ -10,6 +10,7 @@ import ( "testing" mcov1beta2 "github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/api/v1beta2" + "github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/pkg/config" mcoconfig "github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/pkg/config" "github.com/stolostron/multicluster-observability-operator/operators/multiclusterobservability/pkg/rendering/templates" templatesutil "github.com/stolostron/multicluster-observability-operator/operators/pkg/rendering/templates" @@ -21,6 +22,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" + "sigs.k8s.io/controller-runtime/pkg/client/fake" kustomizeres "sigs.k8s.io/kustomize/api/resource" ) @@ -164,9 +166,21 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { }, }, }, + AdvancedConfig: &mcov1beta2.AdvancedConfig{ + CustomObservabilityHubURL: "https://observability-hub", + }, }, } - renderer := &MCORenderer{cr: mco} + + config.SetMonitoringCRName("multicluster-observability") + scheme := runtime.NewScheme() + assert.NoError(t, mcov1beta2.AddToScheme(scheme)) + fakeClient := fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(mco). + Build() + + renderer := &MCORenderer{cr: mco, kubeClient: fakeClient} uobj, err := renderer.renderAddonDeploymentConfig(aodc, "test", map[string]string{"key": "value"}) assert.NoError(t, err) @@ -181,13 +195,14 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { instrV1alpha1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.InstrumentationCRDName) promV1alpha1 := mcoconfig.GetMCOASupportedCRDFQDN(mcoconfig.PrometheusAgentCRDName) - assert.Len(t, got.Spec.CustomizedVariables, 5) + assert.Len(t, got.Spec.CustomizedVariables, 8) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: namePlatformLogsCollection, Value: clfV1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadLogsCollection, Value: clfV1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadTracesCollection, Value: otelV1beta1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadInstrumentation, Value: instrV1alpha1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: namePlatformMetricsCollection, Value: promV1alpha1}) assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameUserWorkloadMetricsCollection, Value: promV1alpha1}) + assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameSignalsHubEndpoint, Value: "observability-hub"}) } func TestMCOAEnabled(t *testing.T) { From 413717f66ca68042399e165f4292318607b22ee6 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:50:54 +0100 Subject: [PATCH 12/20] remove default configs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 48 +------------------ 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index e790adf59..3b78fde42 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -43,51 +43,5 @@ spec: placements: - name: global namespace: open-cluster-management-global-set - configs: - - group: observability.openshift.io - resource: clusterlogforwarders - name: instance - namespace: open-cluster-management-observability - - group: opentelemetry.io - resource: opentelemetrycollectors - name: instance - namespace: open-cluster-management-observability - - group: opentelemetry.io - resource: instrumentations - name: instance - namespace: open-cluster-management-observability - # Default metrics forwarding configuration for the ACM platform metrics collector - - group: monitoring.coreos.com - resource: prometheusagents - name: acm-platform-metrics-collector-default - namespace: open-cluster-management-observability - - group: "" - resource: configmaps - name: acm-platform-metrics-collector-default-envoy-config - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: scrapeconfigs - name: platform-metrics-default - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: prometheusrules - name: platform-rules-default - namespace: open-cluster-management-observability - # Default metrics forwarding configuration for the ACM user workload metrics collector - - group: monitoring.coreos.com - resource: prometheusagents - name: acm-user-workload-metrics-collector-default - namespace: open-cluster-management-observability - - group: "" - resource: configmaps - name: acm-user-workload-metrics-collector-default-envoy-config - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: scrapeconfigs - name: user-workload-metrics-default - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: prometheusrules - name: user-workload-rules-default - namespace: open-cluster-management-observability + configs: {} From c1e846fc02200bf91f0fba436e384689e583ac62 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Mon, 25 Nov 2024 11:50:21 +0100 Subject: [PATCH 13/20] dynamic supported configs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 18 --- .../pkg/rendering/renderer_mcoa.go | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+), 18 deletions(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index 3b78fde42..843483b84 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -20,24 +20,6 @@ spec: defaultConfig: name: multicluster-observability-addon namespace: open-cluster-management-observability - # Describes the default log forwarding outputs for each log type applied to all managed clusters. - - group: observability.openshift.io - resource: clusterlogforwarders - # Describes the default OpenTelemetryCollector type applied to all managed clusters. - - group: opentelemetry.io - resource: opentelemetrycollectors - # Describes the default Instrumentation type applied to all managed clusters. - - group: opentelemetry.io - resource: instrumentations - # Metrics forwarding configuration types. - - group: monitoring.coreos.com - resource: prometheusagents - - group: monitoring.coreos.com - resource: scrapeconfigs - - group: monitoring.coreos.com - resource: prometheusrules - - group: "" - resource: configmaps # For the proxy sidecar configuration of the prometheus agent installStrategy: type: Placements placements: diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 2bb312476..577905e91 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + prometheusalpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -168,6 +170,119 @@ func (r *MCORenderer) renderClusterManagementAddOn( } u.SetLabels(cLabels) + cma := &addonapiv1alpha1.ClusterManagementAddOn{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, cma); err != nil { + return nil, err + } + + // Add default platform configs + if r.cr.Spec.Capabilities.Platform != nil { + if r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "observability.openshift.io", + Resource: "clusterlogforwarders", + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + } + + if r.cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.PrometheusAgentName, + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "acm-platform-metrics-collector-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Resource: "configmaps", + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "acm-platform-metrics-collector-default-envoy-config", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.ScrapeConfigName, + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "platform-metrics-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusv1.SchemeGroupVersion.Group, + Resource: prometheusv1.PrometheusRuleName, + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "platform-rules-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + } + + } + + if r.cr.Spec.Capabilities.UserWorkloads != nil { + if r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.PrometheusAgentName, + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "acm-user-workload-metrics-collector-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Resource: "configmaps", + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "acm-user-workload-metrics-collector-default-envoy-config", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + } + + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "opentelemetrycollectors", + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + } + + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "instrumentations", + }, + DefaultConfig: &addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }) + } + } return u, nil } From ed6bc299a3fe2af8b9562aed680f5804c0beefa9 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:50:33 +0100 Subject: [PATCH 14/20] fix Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../pkg/rendering/renderer_mcoa.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 577905e91..77ef30fb8 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -283,6 +283,12 @@ func (r *MCORenderer) renderClusterManagementAddOn( }) } } + + u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(cma) + if err != nil { + return nil, err + } + return u, nil } From 037b48e75c3adbf684be2e8784feb2de64817cde Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:54:58 +0100 Subject: [PATCH 15/20] fix Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index 843483b84..12b31ef2a 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -25,5 +25,5 @@ spec: placements: - name: global namespace: open-cluster-management-global-set - configs: {} + configs: [] From b3545a064f97c83f30d0912bf5b70c8ad9e7ac49 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Mon, 25 Nov 2024 15:12:19 +0100 Subject: [PATCH 16/20] fix Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../multiclusterobservability/pkg/rendering/renderer_mcoa.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 77ef30fb8..a7151b6e5 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -176,7 +176,7 @@ func (r *MCORenderer) renderClusterManagementAddOn( } // Add default platform configs - if r.cr.Spec.Capabilities.Platform != nil { + if r.cr.Spec.Capabilities != nil && r.cr.Spec.Capabilities.Platform != nil { if r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled { cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ @@ -234,7 +234,7 @@ func (r *MCORenderer) renderClusterManagementAddOn( } - if r.cr.Spec.Capabilities.UserWorkloads != nil { + if r.cr.Spec.Capabilities != nil && r.cr.Spec.Capabilities.UserWorkloads != nil { if r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled { cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ From 275a0369c68194be1ca6d6e92b68525cf3ecb7ee Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 27 Nov 2024 09:47:36 +0100 Subject: [PATCH 17/20] fix supported configs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../pkg/rendering/renderer_mcoa.go | 158 ++++++-------- .../pkg/rendering/renderer_mcoa_test.go | 204 ++++++++++++++++++ 2 files changed, 267 insertions(+), 95 deletions(-) diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index a7151b6e5..5270b7adc 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -7,6 +7,8 @@ package rendering import ( "context" "fmt" + "sort" + "strings" prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" prometheusalpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" @@ -175,113 +177,79 @@ func (r *MCORenderer) renderClusterManagementAddOn( return nil, err } - // Add default platform configs - if r.cr.Spec.Capabilities != nil && r.cr.Spec.Capabilities.Platform != nil { - if r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "observability.openshift.io", - Resource: "clusterlogforwarders", - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "instance", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) - } - - if r.cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusalpha1.SchemeGroupVersion.Group, - Resource: prometheusalpha1.PrometheusAgentName, - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "acm-platform-metrics-collector-default", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Resource: "configmaps", - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "acm-platform-metrics-collector-default-envoy-config", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusalpha1.SchemeGroupVersion.Group, - Resource: prometheusalpha1.ScrapeConfigName, + if r.cr.Spec.Capabilities != nil { + if (r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled) || + (r.cr.Spec.Capabilities.UserWorkloads != nil && r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled) { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.PrometheusAgentName, + }, }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "platform-metrics-default", - Namespace: mcoconfig.GetDefaultNamespace(), + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Resource: "configmaps", + }, }, - }) - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusv1.SchemeGroupVersion.Group, - Resource: prometheusv1.PrometheusRuleName, + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.ScrapeConfigName, + }, }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "platform-rules-default", - Namespace: mcoconfig.GetDefaultNamespace(), + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusv1.SchemeGroupVersion.Group, + Resource: prometheusv1.PrometheusRuleName, + }, }, - }) + }...) } - } - - if r.cr.Spec.Capabilities != nil && r.cr.Spec.Capabilities.UserWorkloads != nil { - if r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusalpha1.SchemeGroupVersion.Group, - Resource: prometheusalpha1.PrometheusAgentName, - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "acm-user-workload-metrics-collector-default", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Resource: "configmaps", - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "acm-user-workload-metrics-collector-default-envoy-config", - Namespace: mcoconfig.GetDefaultNamespace(), + if (r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled) || + (r.cr.Spec.Capabilities.UserWorkloads != nil && r.cr.Spec.Capabilities.UserWorkloads.Logs.Collection.ClusterLogForwarder.Enabled) { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "observability.openshift.io", + Resource: "clusterlogforwarders", + }, }, - }) + }...) } - if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "opentelemetry.io", - Resource: "opentelemetrycollectors", - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "instance", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) + if r.cr.Spec.Capabilities.UserWorkloads != nil { + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "opentelemetrycollectors", + }, + }, + }...) + } + + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled { + cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "instrumentations", + }, + }, + }...) + } } - if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, addonapiv1alpha1.ConfigMeta{ - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "opentelemetry.io", - Resource: "instrumentations", - }, - DefaultConfig: &addonapiv1alpha1.ConfigReferent{ - Name: "instance", - Namespace: mcoconfig.GetDefaultNamespace(), - }, - }) + makeKey := func(cfg addonapiv1alpha1.ConfigMeta) string { + return fmt.Sprintf("%s/%s", cfg.Group, cfg.Resource) } + sort.Slice(cma.Spec.SupportedConfigs, func(i, j int) bool { + return strings.Compare(makeKey(cma.Spec.SupportedConfigs[i]), makeKey(cma.Spec.SupportedConfigs[j])) < 0 + }) + } u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(cma) diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go index df5ab7456..991d8a51e 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go @@ -21,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" + addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/client/fake" kustomizeres "sigs.k8s.io/kustomize/api/resource" @@ -205,6 +206,209 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameSignalsHubEndpoint, Value: "observability-hub"}) } +func TestMCORenderer_RenderClusterManagementAddOn(t *testing.T) { + tests := []struct { + name string + labels map[string]string + capabilities *mcov1beta2.CapabilitiesSpec + expectConfig func(*testing.T, *addonv1alpha1.ClusterManagementAddOn) + }{ + { + name: "add metrics configs when platform is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 5) + }, + }, + { + name: "add metrics configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 5) + }, + }, + { + name: "add metrics configs when both platform and user workloads are enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 5) + }, + }, + { + name: "add logs configs when platform is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Logs: mcov1beta2.PlatformLogsSpec{ + Collection: mcov1beta2.PlatformLogsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 2) + }, + }, + { + name: "add logs configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Logs: mcov1beta2.UserWorkloadLogsSpec{ + Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ + ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 2) + }, + }, + { + name: "add logs configs when both platform and user workloads are enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Logs: mcov1beta2.PlatformLogsSpec{ + Collection: mcov1beta2.PlatformLogsCollectionSpec{ + Enabled: true, + }, + }, + }, + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Logs: mcov1beta2.UserWorkloadLogsSpec{ + Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ + ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 2) + }, + }, + { + name: "add traces configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Traces: mcov1beta2.UserWorkloadTracesSpec{ + Collection: mcov1beta2.OpenTelemetryCollectionSpec{ + Collector: mcov1beta2.OpenTelemetryCollectorSpec{ + Enabled: true, + }, + Instrumentation: mcov1beta2.InstrumentationSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.SupportedConfigs, 3) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &MCORenderer{ + cr: &mcov1beta2.MultiClusterObservability{ + Spec: mcov1beta2.MultiClusterObservabilitySpec{ + Capabilities: tt.capabilities, + }, + }, + } + + // Add deployment config to reflect real input + baseCMA := &addonv1alpha1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "k1": "v1", + }, + }, + Spec: addonv1alpha1.ClusterManagementAddOnSpec{ + SupportedConfigs: []addonv1alpha1.ConfigMeta{ + { + ConfigGroupResource: addonv1alpha1.ConfigGroupResource{ + Group: "addon.open-cluster-management.io", + Resource: "addondeploymentconfigs", + }, + DefaultConfig: &addonv1alpha1.ConfigReferent{ + Name: "multicluster-observability-addon", + Namespace: "open-cluster-management-observability", + }, + }, + }, + }, + } + // to kustomize resource + baseCMAUnstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(baseCMA) + assert.NoError(t, err) + kres := &kustomizeres.Resource{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(baseCMAUnstructured, kres) + assert.NoError(t, err) + + res, err := r.renderClusterManagementAddOn(kres, "ns", map[string]string{"k2": "v2"}) + assert.NoError(t, err) + assert.NotNil(t, res) + + // check labels + assert.Len(t, res.GetLabels(), 2) + + // check supportedConfigs + cma := &addonapiv1alpha1.ClusterManagementAddOn{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(res.Object, cma) + assert.NoError(t, err) + + tt.expectConfig(t, cma) + + // Check duplicated supportedConfigs + dups := make(map[string]struct{}) + for _, cfg := range cma.Spec.SupportedConfigs { + key := cfg.ConfigGroupResource.Group + "/" + cfg.ConfigGroupResource.Resource + if _, ok := dups[key]; ok { + t.Errorf("duplicated supportedConfigs %s", key) + } + dups[key] = struct{}{} + } + }) + } +} + func TestMCOAEnabled(t *testing.T) { tests := []struct { name string From 217a16067c198af8ff8076df52716b699142b202 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Wed, 27 Nov 2024 17:32:39 +0100 Subject: [PATCH 18/20] revert dynamic supportedConfigs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 60 +++++- .../pkg/rendering/renderer_mcoa.go | 89 -------- .../pkg/rendering/renderer_mcoa_test.go | 204 ------------------ 3 files changed, 59 insertions(+), 294 deletions(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index 12b31ef2a..11bb45c4d 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -20,10 +20,68 @@ spec: defaultConfig: name: multicluster-observability-addon namespace: open-cluster-management-observability + # Describes the default log forwarding outputs for each log type applied to all managed clusters. + - group: observability.openshift.io + resource: clusterlogforwarders + # Describes the default OpenTelemetryCollector type applied to all managed clusters. + - group: opentelemetry.io + resource: opentelemetrycollectors + # Describes the default Instrumentation type applied to all managed clusters. + - group: opentelemetry.io + resource: instrumentations + # Metrics forwarding configuration types. + - group: monitoring.coreos.com + resource: prometheusagents + - group: monitoring.coreos.com + resource: scrapeconfigs + - group: monitoring.coreos.com + resource: prometheusrules + - group: "" + resource: configmaps # For the proxy sidecar configuration of the prometheus agent installStrategy: type: Placements placements: - name: global namespace: open-cluster-management-global-set - configs: [] + configs: + configs: + - group: observability.openshift.io + resource: clusterlogforwarders + name: instance + namespace: open-cluster-management-observability + - group: opentelemetry.io + resource: opentelemetrycollectors + name: instance + namespace: open-cluster-management-observability + - group: opentelemetry.io + resource: instrumentations + name: instance + namespace: open-cluster-management-observability + # Default metrics forwarding configuration for the ACM platform metrics collector + - group: monitoring.coreos.com + resource: prometheusagents + name: acm-platform-metrics-collector-default + namespace: open-cluster-management-observability + - group: "" + resource: configmaps + name: acm-platform-metrics-collector-default-envoy-config + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: scrapeconfigs + name: platform-metrics-default + namespace: open-cluster-management-observability + - group: monitoring.coreos.com + resource: prometheusrules + name: platform-rules-default + namespace: open-cluster-management-observability + # Default metrics forwarding configuration for the ACM user workload metrics collector + # There are no default configurations for the scrapeConfigs and prometheusRules + - group: monitoring.coreos.com + resource: prometheusagents + name: acm-user-workload-metrics-collector-default + namespace: open-cluster-management-observability + - group: "" + resource: configmaps + name: acm-user-workload-metrics-collector-default-envoy-config + namespace: open-cluster-management-observability diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 5270b7adc..2bb312476 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -7,11 +7,7 @@ package rendering import ( "context" "fmt" - "sort" - "strings" - prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - prometheusalpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -172,91 +168,6 @@ func (r *MCORenderer) renderClusterManagementAddOn( } u.SetLabels(cLabels) - cma := &addonapiv1alpha1.ClusterManagementAddOn{} - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, cma); err != nil { - return nil, err - } - - if r.cr.Spec.Capabilities != nil { - if (r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled) || - (r.cr.Spec.Capabilities.UserWorkloads != nil && r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled) { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusalpha1.SchemeGroupVersion.Group, - Resource: prometheusalpha1.PrometheusAgentName, - }, - }, - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Resource: "configmaps", - }, - }, - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusalpha1.SchemeGroupVersion.Group, - Resource: prometheusalpha1.ScrapeConfigName, - }, - }, - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: prometheusv1.SchemeGroupVersion.Group, - Resource: prometheusv1.PrometheusRuleName, - }, - }, - }...) - } - - if (r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled) || - (r.cr.Spec.Capabilities.UserWorkloads != nil && r.cr.Spec.Capabilities.UserWorkloads.Logs.Collection.ClusterLogForwarder.Enabled) { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "observability.openshift.io", - Resource: "clusterlogforwarders", - }, - }, - }...) - } - - if r.cr.Spec.Capabilities.UserWorkloads != nil { - if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "opentelemetry.io", - Resource: "opentelemetrycollectors", - }, - }, - }...) - } - - if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled { - cma.Spec.SupportedConfigs = append(cma.Spec.SupportedConfigs, []addonapiv1alpha1.ConfigMeta{ - { - ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ - Group: "opentelemetry.io", - Resource: "instrumentations", - }, - }, - }...) - } - } - - makeKey := func(cfg addonapiv1alpha1.ConfigMeta) string { - return fmt.Sprintf("%s/%s", cfg.Group, cfg.Resource) - } - sort.Slice(cma.Spec.SupportedConfigs, func(i, j int) bool { - return strings.Compare(makeKey(cma.Spec.SupportedConfigs[i]), makeKey(cma.Spec.SupportedConfigs[j])) < 0 - }) - - } - - u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(cma) - if err != nil { - return nil, err - } - return u, nil } diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go index 991d8a51e..df5ab7456 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go @@ -21,7 +21,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" - addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/client/fake" kustomizeres "sigs.k8s.io/kustomize/api/resource" @@ -206,209 +205,6 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameSignalsHubEndpoint, Value: "observability-hub"}) } -func TestMCORenderer_RenderClusterManagementAddOn(t *testing.T) { - tests := []struct { - name string - labels map[string]string - capabilities *mcov1beta2.CapabilitiesSpec - expectConfig func(*testing.T, *addonv1alpha1.ClusterManagementAddOn) - }{ - { - name: "add metrics configs when platform is enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - Platform: &mcov1beta2.PlatformCapabilitiesSpec{ - Metrics: mcov1beta2.PlatformMetricsSpec{ - Collection: mcov1beta2.PlatformMetricsCollectionSpec{ - Enabled: true, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 5) - }, - }, - { - name: "add metrics configs when user workloads is enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ - Metrics: mcov1beta2.UserWorkloadMetricsSpec{ - Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ - Enabled: true, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 5) - }, - }, - { - name: "add metrics configs when both platform and user workloads are enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - Platform: &mcov1beta2.PlatformCapabilitiesSpec{ - Metrics: mcov1beta2.PlatformMetricsSpec{ - Collection: mcov1beta2.PlatformMetricsCollectionSpec{ - Enabled: true, - }, - }, - }, - UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ - Metrics: mcov1beta2.UserWorkloadMetricsSpec{ - Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ - Enabled: true, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 5) - }, - }, - { - name: "add logs configs when platform is enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - Platform: &mcov1beta2.PlatformCapabilitiesSpec{ - Logs: mcov1beta2.PlatformLogsSpec{ - Collection: mcov1beta2.PlatformLogsCollectionSpec{ - Enabled: true, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 2) - }, - }, - { - name: "add logs configs when user workloads is enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ - Logs: mcov1beta2.UserWorkloadLogsSpec{ - Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ - ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ - Enabled: true, - }, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 2) - }, - }, - { - name: "add logs configs when both platform and user workloads are enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - Platform: &mcov1beta2.PlatformCapabilitiesSpec{ - Logs: mcov1beta2.PlatformLogsSpec{ - Collection: mcov1beta2.PlatformLogsCollectionSpec{ - Enabled: true, - }, - }, - }, - UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ - Logs: mcov1beta2.UserWorkloadLogsSpec{ - Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ - ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ - Enabled: true, - }, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 2) - }, - }, - { - name: "add traces configs when user workloads is enabled", - capabilities: &mcov1beta2.CapabilitiesSpec{ - UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ - Traces: mcov1beta2.UserWorkloadTracesSpec{ - Collection: mcov1beta2.OpenTelemetryCollectionSpec{ - Collector: mcov1beta2.OpenTelemetryCollectorSpec{ - Enabled: true, - }, - Instrumentation: mcov1beta2.InstrumentationSpec{ - Enabled: true, - }, - }, - }, - }, - }, - expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { - assert.Len(t, cma.Spec.SupportedConfigs, 3) - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - r := &MCORenderer{ - cr: &mcov1beta2.MultiClusterObservability{ - Spec: mcov1beta2.MultiClusterObservabilitySpec{ - Capabilities: tt.capabilities, - }, - }, - } - - // Add deployment config to reflect real input - baseCMA := &addonv1alpha1.ClusterManagementAddOn{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - "k1": "v1", - }, - }, - Spec: addonv1alpha1.ClusterManagementAddOnSpec{ - SupportedConfigs: []addonv1alpha1.ConfigMeta{ - { - ConfigGroupResource: addonv1alpha1.ConfigGroupResource{ - Group: "addon.open-cluster-management.io", - Resource: "addondeploymentconfigs", - }, - DefaultConfig: &addonv1alpha1.ConfigReferent{ - Name: "multicluster-observability-addon", - Namespace: "open-cluster-management-observability", - }, - }, - }, - }, - } - // to kustomize resource - baseCMAUnstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(baseCMA) - assert.NoError(t, err) - kres := &kustomizeres.Resource{} - err = runtime.DefaultUnstructuredConverter.FromUnstructured(baseCMAUnstructured, kres) - assert.NoError(t, err) - - res, err := r.renderClusterManagementAddOn(kres, "ns", map[string]string{"k2": "v2"}) - assert.NoError(t, err) - assert.NotNil(t, res) - - // check labels - assert.Len(t, res.GetLabels(), 2) - - // check supportedConfigs - cma := &addonapiv1alpha1.ClusterManagementAddOn{} - err = runtime.DefaultUnstructuredConverter.FromUnstructured(res.Object, cma) - assert.NoError(t, err) - - tt.expectConfig(t, cma) - - // Check duplicated supportedConfigs - dups := make(map[string]struct{}) - for _, cfg := range cma.Spec.SupportedConfigs { - key := cfg.ConfigGroupResource.Group + "/" + cfg.ConfigGroupResource.Resource - if _, ok := dups[key]; ok { - t.Errorf("duplicated supportedConfigs %s", key) - } - dups[key] = struct{}{} - } - }) - } -} - func TestMCOAEnabled(t *testing.T) { tests := []struct { name string From 0de6631d8bc1a7d2c4cde25fdffab4d0e2a96ba1 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Thu, 28 Nov 2024 16:08:44 +0100 Subject: [PATCH 19/20] fix Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index 11bb45c4d..f1bb2801e 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -44,7 +44,6 @@ spec: - name: global namespace: open-cluster-management-global-set configs: - configs: - group: observability.openshift.io resource: clusterlogforwarders name: instance From 57e2104fe62716221f4487c1e4d20bda267d1457 Mon Sep 17 00:00:00 2001 From: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> Date: Fri, 29 Nov 2024 08:46:30 +0100 Subject: [PATCH 20/20] only enabled configs Signed-off-by: Thibault Mange <22740367+thibaultmg@users.noreply.github.com> --- .../cluster_management_addon.yaml | 44 +--- .../pkg/rendering/renderer_mcoa.go | 117 ++++++++++ .../pkg/rendering/renderer_mcoa_test.go | 199 ++++++++++++++++++ 3 files changed, 317 insertions(+), 43 deletions(-) diff --git a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml index f1bb2801e..22ac71c0d 100644 --- a/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml +++ b/operators/multiclusterobservability/manifests/base/multicluster-observability-addon/cluster_management_addon.yaml @@ -36,51 +36,9 @@ spec: resource: scrapeconfigs - group: monitoring.coreos.com resource: prometheusrules - - group: "" - resource: configmaps # For the proxy sidecar configuration of the prometheus agent installStrategy: type: Placements placements: - name: global namespace: open-cluster-management-global-set - configs: - - group: observability.openshift.io - resource: clusterlogforwarders - name: instance - namespace: open-cluster-management-observability - - group: opentelemetry.io - resource: opentelemetrycollectors - name: instance - namespace: open-cluster-management-observability - - group: opentelemetry.io - resource: instrumentations - name: instance - namespace: open-cluster-management-observability - # Default metrics forwarding configuration for the ACM platform metrics collector - - group: monitoring.coreos.com - resource: prometheusagents - name: acm-platform-metrics-collector-default - namespace: open-cluster-management-observability - - group: "" - resource: configmaps - name: acm-platform-metrics-collector-default-envoy-config - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: scrapeconfigs - name: platform-metrics-default - namespace: open-cluster-management-observability - - group: monitoring.coreos.com - resource: prometheusrules - name: platform-rules-default - namespace: open-cluster-management-observability - # Default metrics forwarding configuration for the ACM user workload metrics collector - # There are no default configurations for the scrapeConfigs and prometheusRules - - group: monitoring.coreos.com - resource: prometheusagents - name: acm-user-workload-metrics-collector-default - namespace: open-cluster-management-observability - - group: "" - resource: configmaps - name: acm-user-workload-metrics-collector-default-envoy-config - namespace: open-cluster-management-observability - + configs: [] diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go index 2bb312476..72c0449e1 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa.go @@ -8,6 +8,8 @@ import ( "context" "fmt" + prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + prometheusalpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -168,6 +170,121 @@ func (r *MCORenderer) renderClusterManagementAddOn( } u.SetLabels(cLabels) + cma := &addonapiv1alpha1.ClusterManagementAddOn{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, cma); err != nil { + return nil, err + } + + if r.cr.Spec.Capabilities != nil { + if len(cma.Spec.InstallStrategy.Placements) != 1 { + return nil, fmt.Errorf("expected exactly one placement, got %d", len(cma.Spec.InstallStrategy.Placements)) + } + globalConfigs := []addonapiv1alpha1.AddOnConfig{} + if r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Metrics.Collection.Enabled { + globalConfigs = append(globalConfigs, []addonapiv1alpha1.AddOnConfig{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.PrometheusAgentName, + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "acm-platform-metrics-collector-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.ScrapeConfigName, + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "platform-metrics-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusv1.SchemeGroupVersion.Group, + Resource: prometheusv1.PrometheusRuleName, + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "platform-rules-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + }...) + } + + if r.cr.Spec.Capabilities.UserWorkloads != nil && r.cr.Spec.Capabilities.UserWorkloads.Metrics.Collection.Enabled { + globalConfigs = append(globalConfigs, []addonapiv1alpha1.AddOnConfig{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: prometheusalpha1.SchemeGroupVersion.Group, + Resource: prometheusalpha1.PrometheusAgentName, + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "acm-user-workload-metrics-collector-default", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + }...) + } + + if r.cr.Spec.Capabilities.Platform != nil && r.cr.Spec.Capabilities.Platform.Logs.Collection.Enabled { + globalConfigs = append(globalConfigs, []addonapiv1alpha1.AddOnConfig{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "observability.openshift.io", + Resource: "clusterlogforwarders", + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + }...) + } + + if r.cr.Spec.Capabilities.UserWorkloads != nil { + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Collector.Enabled { + globalConfigs = append(globalConfigs, []addonapiv1alpha1.AddOnConfig{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "opentelemetrycollectors", + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + }...) + } + + if r.cr.Spec.Capabilities.UserWorkloads.Traces.Collection.Instrumentation.Enabled { + globalConfigs = append(globalConfigs, []addonapiv1alpha1.AddOnConfig{ + { + ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{ + Group: "opentelemetry.io", + Resource: "instrumentations", + }, + ConfigReferent: addonapiv1alpha1.ConfigReferent{ + Name: "instance", + Namespace: mcoconfig.GetDefaultNamespace(), + }, + }, + }...) + } + } + + cma.Spec.InstallStrategy.Placements[0].Configs = append(cma.Spec.InstallStrategy.Placements[0].Configs, globalConfigs...) + } + + u.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(cma) + if err != nil { + return nil, err + } + return u, nil } diff --git a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go index df5ab7456..795438f04 100644 --- a/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go +++ b/operators/multiclusterobservability/pkg/rendering/renderer_mcoa_test.go @@ -21,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" + addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1" "sigs.k8s.io/controller-runtime/pkg/client/fake" kustomizeres "sigs.k8s.io/kustomize/api/resource" @@ -205,6 +206,204 @@ func TestRenderAddonDeploymentConfig(t *testing.T) { assert.Contains(t, got.Spec.CustomizedVariables, addonv1alpha1.CustomizedVariable{Name: nameSignalsHubEndpoint, Value: "observability-hub"}) } +func TestMCORenderer_RenderClusterManagementAddOn(t *testing.T) { + tests := []struct { + name string + labels map[string]string + capabilities *mcov1beta2.CapabilitiesSpec + expectConfig func(*testing.T, *addonv1alpha1.ClusterManagementAddOn) + }{ + { + name: "add metrics configs when platform is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 3) + }, + }, + { + name: "add metrics configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 1) + }, + }, + { + name: "add metrics configs when both platform and user workloads are enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Metrics: mcov1beta2.PlatformMetricsSpec{ + Collection: mcov1beta2.PlatformMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Metrics: mcov1beta2.UserWorkloadMetricsSpec{ + Collection: mcov1beta2.UserWorkloadMetricsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 4) + }, + }, + { + name: "add logs configs when platform is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Logs: mcov1beta2.PlatformLogsSpec{ + Collection: mcov1beta2.PlatformLogsCollectionSpec{ + Enabled: true, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 1) + }, + }, + { + name: "add logs configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Logs: mcov1beta2.UserWorkloadLogsSpec{ + Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ + ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 0) + }, + }, + { + name: "add logs configs when both platform and user workloads are enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + Platform: &mcov1beta2.PlatformCapabilitiesSpec{ + Logs: mcov1beta2.PlatformLogsSpec{ + Collection: mcov1beta2.PlatformLogsCollectionSpec{ + Enabled: true, + }, + }, + }, + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Logs: mcov1beta2.UserWorkloadLogsSpec{ + Collection: mcov1beta2.UserWorkloadLogsCollectionSpec{ + ClusterLogForwarder: mcov1beta2.ClusterLogForwarderSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 1) + }, + }, + { + name: "add traces configs when user workloads is enabled", + capabilities: &mcov1beta2.CapabilitiesSpec{ + UserWorkloads: &mcov1beta2.UserWorkloadCapabilitiesSpec{ + Traces: mcov1beta2.UserWorkloadTracesSpec{ + Collection: mcov1beta2.OpenTelemetryCollectionSpec{ + Collector: mcov1beta2.OpenTelemetryCollectorSpec{ + Enabled: true, + }, + Instrumentation: mcov1beta2.InstrumentationSpec{ + Enabled: true, + }, + }, + }, + }, + }, + expectConfig: func(t *testing.T, cma *addonv1alpha1.ClusterManagementAddOn) { + assert.Len(t, cma.Spec.InstallStrategy.Placements[0].Configs, 2) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &MCORenderer{ + cr: &mcov1beta2.MultiClusterObservability{ + Spec: mcov1beta2.MultiClusterObservabilitySpec{ + Capabilities: tt.capabilities, + }, + }, + } + + // Add deployment config to reflect real input + baseCMA := &addonv1alpha1.ClusterManagementAddOn{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "k1": "v1", + }, + }, + Spec: addonv1alpha1.ClusterManagementAddOnSpec{ + InstallStrategy: addonv1alpha1.InstallStrategy{ + Placements: []addonv1alpha1.PlacementStrategy{ + { + Configs: []addonv1alpha1.AddOnConfig{}, + }, + }, + }, + }, + } + // to kustomize resource + baseCMAUnstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(baseCMA) + assert.NoError(t, err) + kres := &kustomizeres.Resource{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(baseCMAUnstructured, kres) + assert.NoError(t, err) + + res, err := r.renderClusterManagementAddOn(kres, "ns", map[string]string{"k2": "v2"}) + assert.NoError(t, err) + assert.NotNil(t, res) + + // check labels + assert.Len(t, res.GetLabels(), 2) + + // check supportedConfigs + cma := &addonapiv1alpha1.ClusterManagementAddOn{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(res.Object, cma) + assert.NoError(t, err) + + tt.expectConfig(t, cma) + + // Check duplicated supportedConfigs + dups := make(map[string]struct{}) + for _, cfg := range cma.Spec.SupportedConfigs { + key := cfg.ConfigGroupResource.Group + "/" + cfg.ConfigGroupResource.Resource + if _, ok := dups[key]; ok { + t.Errorf("duplicated supportedConfigs %s", key) + } + dups[key] = struct{}{} + } + }) + } +} + func TestMCOAEnabled(t *testing.T) { tests := []struct { name string