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] 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