diff --git a/.chloggen/3370-create-dynamic-sm.yaml b/.chloggen/3370-create-dynamic-sm.yaml new file mode 100755 index 0000000000..4f6264744a --- /dev/null +++ b/.chloggen/3370-create-dynamic-sm.yaml @@ -0,0 +1,19 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Programmatically create the `ServiceMonitor` for the operator metrics endpoint, ensuring correct namespace handling and dynamic configuration. + +# One or more tracking issues related to the change +issues: [3370] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: | + Previously, the `ServiceMonitor` was created statically from a manifest file, causing failures when the + operator was deployed in a non-default namespace. This enhancement ensures automatic adjustment of the + `serverName` and seamless metrics scraping. diff --git a/bundle/openshift/manifests/opentelemetry-operator-controller-manager-metrics-service_v1_service.yaml b/bundle/openshift/manifests/opentelemetry-operator-controller-manager-metrics-service_v1_service.yaml index 66b0879b4d..8bf0b4ac62 100644 --- a/bundle/openshift/manifests/opentelemetry-operator-controller-manager-metrics-service_v1_service.yaml +++ b/bundle/openshift/manifests/opentelemetry-operator-controller-manager-metrics-service_v1_service.yaml @@ -1,9 +1,13 @@ apiVersion: v1 kind: Service metadata: + annotations: + service.beta.openshift.io/serving-cert-secret-name: opentelemetry-operator-metrics creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager name: opentelemetry-operator-controller-manager-metrics-service spec: @@ -13,7 +17,9 @@ spec: protocol: TCP targetPort: https selector: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager status: loadBalancer: {} diff --git a/bundle/openshift/manifests/opentelemetry-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml b/bundle/openshift/manifests/opentelemetry-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml index 18a824a57f..d55f7e74ae 100644 --- a/bundle/openshift/manifests/opentelemetry-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml +++ b/bundle/openshift/manifests/opentelemetry-operator-metrics-reader_rbac.authorization.k8s.io_v1_clusterrole.yaml @@ -3,7 +3,9 @@ kind: ClusterRole metadata: creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator name: opentelemetry-operator-metrics-reader rules: - nonResourceURLs: diff --git a/bundle/openshift/manifests/opentelemetry-operator-prometheus-rules_monitoring.coreos.com_v1_prometheusrule.yaml b/bundle/openshift/manifests/opentelemetry-operator-prometheus-rules_monitoring.coreos.com_v1_prometheusrule.yaml new file mode 100644 index 0000000000..88441a6cad --- /dev/null +++ b/bundle/openshift/manifests/opentelemetry-operator-prometheus-rules_monitoring.coreos.com_v1_prometheusrule.yaml @@ -0,0 +1,24 @@ +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator + name: opentelemetry-operator-prometheus-rules +spec: + groups: + - name: opentelemetry-operator-monitoring.rules + rules: + - expr: sum by (type) (opentelemetry_collector_receivers) + record: type:opentelemetry_collector_receivers:sum + - expr: sum by (type) (opentelemetry_collector_exporters) + record: type:opentelemetry_collector_exporters:sum + - expr: sum by (type) (opentelemetry_collector_processors) + record: type:opentelemetry_collector_processors:sum + - expr: sum by (type) (opentelemetry_collector_extensions) + record: type:opentelemetry_collector_extensions:sum + - expr: sum by (type) (opentelemetry_collector_connectors) + record: type:opentelemetry_collector_connectors:sum + - expr: sum by (type) (opentelemetry_collector_info) + record: type:opentelemetry_collector_info:sum \ No newline at end of file diff --git a/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml b/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml new file mode 100644 index 0000000000..cfa9e4fba8 --- /dev/null +++ b/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_role.yaml @@ -0,0 +1,22 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator + name: opentelemetry-operator-prometheus +rules: +- apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - list + - watch diff --git a/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml b/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml new file mode 100644 index 0000000000..c12a15a043 --- /dev/null +++ b/bundle/openshift/manifests/opentelemetry-operator-prometheus_rbac.authorization.k8s.io_v1_rolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + annotations: + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator + name: opentelemetry-operator-prometheus +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: opentelemetry-operator-prometheus +subjects: +- kind: ServiceAccount + name: prometheus-k8s + namespace: openshift-monitoring diff --git a/bundle/openshift/manifests/opentelemetry-operator-webhook-service_v1_service.yaml b/bundle/openshift/manifests/opentelemetry-operator-webhook-service_v1_service.yaml index d40a336940..d4e920de6f 100644 --- a/bundle/openshift/manifests/opentelemetry-operator-webhook-service_v1_service.yaml +++ b/bundle/openshift/manifests/opentelemetry-operator-webhook-service_v1_service.yaml @@ -3,7 +3,9 @@ kind: Service metadata: creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator name: opentelemetry-operator-webhook-service spec: ports: @@ -11,7 +13,9 @@ spec: protocol: TCP targetPort: 9443 selector: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager status: loadBalancer: {} diff --git a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml index f248186c9a..b5b5cce672 100644 --- a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml +++ b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml @@ -99,7 +99,7 @@ metadata: categories: Logging & Tracing,Monitoring certified: "false" containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator - createdAt: "2024-10-16T10:10:50Z" + createdAt: "2024-10-18T17:14:07Z" description: Provides the OpenTelemetry components, including the Collector operators.operatorframework.io/builder: operator-sdk-v1.29.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -453,20 +453,26 @@ spec: serviceAccountName: opentelemetry-operator-controller-manager deployments: - label: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager name: opentelemetry-operator-controller-manager spec: replicas: 1 selector: matchLabels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager strategy: {} template: metadata: labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator control-plane: controller-manager spec: containers: @@ -477,9 +483,9 @@ spec: - --zap-time-encoding=rfc3339nano - --enable-nginx-instrumentation=true - --enable-go-instrumentation=true - - --enable-multi-instrumentation=true - --openshift-create-dashboard=true - --feature-gates=+operator.observability.prometheus + - --enable-cr-metrics=true env: - name: SERVICE_ACCOUNT_NAME valueFrom: @@ -516,6 +522,10 @@ spec: - --upstream=http://127.0.0.1:8080/ - --logtostderr=true - --v=0 + - --tls-cert-file=/var/run/tls/server/tls.crt + - --tls-private-key-file=/var/run/tls/server/tls.key + - --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256 + - --tls-min-version=VersionTLS12 image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1 name: kube-rbac-proxy ports: @@ -529,9 +539,16 @@ spec: requests: cpu: 5m memory: 64Mi + volumeMounts: + - mountPath: /var/run/tls/server + name: opentelemetry-operator-metrics-cert serviceAccountName: opentelemetry-operator-controller-manager terminationGracePeriodSeconds: 10 volumes: + - name: opentelemetry-operator-metrics-cert + secret: + defaultMode: 420 + secretName: opentelemetry-operator-metrics - name: cert secret: defaultMode: 420 diff --git a/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml b/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml index 7e59a81d68..7f48d2175a 100644 --- a/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml +++ b/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml @@ -5,7 +5,9 @@ metadata: controller-gen.kubebuilder.io/version: v0.16.1 creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator name: instrumentations.opentelemetry.io spec: group: opentelemetry.io diff --git a/bundle/openshift/manifests/opentelemetry.io_opampbridges.yaml b/bundle/openshift/manifests/opentelemetry.io_opampbridges.yaml index 306375654e..2638a8e751 100644 --- a/bundle/openshift/manifests/opentelemetry.io_opampbridges.yaml +++ b/bundle/openshift/manifests/opentelemetry.io_opampbridges.yaml @@ -6,7 +6,9 @@ metadata: controller-gen.kubebuilder.io/version: v0.16.1 creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator name: opampbridges.opentelemetry.io spec: group: opentelemetry.io diff --git a/bundle/openshift/manifests/opentelemetry.io_opentelemetrycollectors.yaml b/bundle/openshift/manifests/opentelemetry.io_opentelemetrycollectors.yaml index 594e0f4aea..e7bfb4accd 100644 --- a/bundle/openshift/manifests/opentelemetry.io_opentelemetrycollectors.yaml +++ b/bundle/openshift/manifests/opentelemetry.io_opentelemetrycollectors.yaml @@ -6,7 +6,9 @@ metadata: controller-gen.kubebuilder.io/version: v0.16.1 creationTimestamp: null labels: + app.kubernetes.io/managed-by: operator-lifecycle-manager app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator name: opentelemetrycollectors.opentelemetry.io spec: conversion: diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index b5d04b59ae..2475c8ee5b 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -18,8 +18,6 @@ bases: - ../manager - ../webhook - ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus patchesStrategicMerge: # Protect the /metrics endpoint by putting it behind auth. diff --git a/config/overlays/openshift/kustomization.yaml b/config/overlays/openshift/kustomization.yaml index ddd0d3b29b..77cb3c0c53 100644 --- a/config/overlays/openshift/kustomization.yaml +++ b/config/overlays/openshift/kustomization.yaml @@ -1,6 +1,13 @@ resources: - ../../default +labels: +- pairs: + app.kubernetes.io/name: opentelemetry-operator + app.kubernetes.io/part-of: opentelemetry-operator + app.kubernetes.io/managed-by: operator-lifecycle-manager + includeSelectors: true + patches: - target: group: apps @@ -8,3 +15,7 @@ patches: kind: Deployment name: controller-manager path: manager-patch.yaml + +patchesStrategicMerge: +- metrics_service_tls_patch.yaml +- manager_auth_proxy_tls_patch.yaml \ No newline at end of file diff --git a/config/overlays/openshift/manager-patch.yaml b/config/overlays/openshift/manager-patch.yaml index 2fb76bd889..57b097ca29 100644 --- a/config/overlays/openshift/manager-patch.yaml +++ b/config/overlays/openshift/manager-patch.yaml @@ -7,6 +7,6 @@ - --zap-time-encoding=rfc3339nano - --enable-nginx-instrumentation=true - '--enable-go-instrumentation=true' - - '--enable-multi-instrumentation=true' - '--openshift-create-dashboard=true' - '--feature-gates=+operator.observability.prometheus' + - '--enable-cr-metrics=true' \ No newline at end of file diff --git a/config/overlays/openshift/manager_auth_proxy_tls_patch.yaml b/config/overlays/openshift/manager_auth_proxy_tls_patch.yaml new file mode 100644 index 0000000000..077fa74ea6 --- /dev/null +++ b/config/overlays/openshift/manager_auth_proxy_tls_patch.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager # without this line, kustomize reorders the containers, making kube-rbac-proxy the default container + - name: kube-rbac-proxy + args: + - "--secure-listen-address=0.0.0.0:8443" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=0" + - "--tls-cert-file=/var/run/tls/server/tls.crt" + - "--tls-private-key-file=/var/run/tls/server/tls.key" + - "--tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA256" + - "--tls-min-version=VersionTLS12" + volumeMounts: + - mountPath: /var/run/tls/server + name: opentelemetry-operator-metrics-cert + volumes: + - name: opentelemetry-operator-metrics-cert + secret: + defaultMode: 420 + # secret generated by the 'service.beta.openshift.io/serving-cert-secret-name' annotation on the metrics-service + secretName: opentelemetry-operator-metrics diff --git a/config/overlays/openshift/metrics_service_tls_patch.yaml b/config/overlays/openshift/metrics_service_tls_patch.yaml new file mode 100644 index 0000000000..7505c7894a --- /dev/null +++ b/config/overlays/openshift/metrics_service_tls_patch.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + service.beta.openshift.io/serving-cert-secret-name: opentelemetry-operator-metrics + name: controller-manager-metrics-service + namespace: system diff --git a/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml deleted file mode 100644 index ed137168a1..0000000000 --- a/config/prometheus/kustomization.yaml +++ /dev/null @@ -1,2 +0,0 @@ -resources: -- monitor.yaml diff --git a/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml deleted file mode 100644 index 6e5f438a21..0000000000 --- a/config/prometheus/monitor.yaml +++ /dev/null @@ -1,26 +0,0 @@ - -# Prometheus Monitor Service (Metrics) -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - app.kubernetes.io/name: opentelemetry-operator - control-plane: controller-manager - name: controller-manager-metrics-monitor - namespace: system -spec: - endpoints: - - path: /metrics - port: https - scheme: https - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - tlsConfig: - insecureSkipVerify: false - ca: - secret: - key: ca.crt - name: opentelemetry-operator-controller-manager-service-cert - selector: - matchLabels: - app.kubernetes.io/name: opentelemetry-operator - control-plane: controller-manager diff --git a/internal/operator-metrics/metrics.go b/internal/operator-metrics/metrics.go new file mode 100644 index 0000000000..093ea3aa8d --- /dev/null +++ b/internal/operator-metrics/metrics.go @@ -0,0 +1,104 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package operatormetrics + +import ( + "context" + "fmt" + "os" + + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var namespaceFile = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" + +type OperatorMetrics struct { + kubeClient client.Client +} + +func NewOperatorMetrics(config *rest.Config, scheme *runtime.Scheme) (OperatorMetrics, error) { + kubeClient, err := client.New(config, client.Options{Scheme: scheme}) + if err != nil { + return OperatorMetrics{}, err + } + + return OperatorMetrics{ + kubeClient: kubeClient, + }, nil +} + +func (d OperatorMetrics) Start(ctx context.Context) error { + rawNamespace, err := os.ReadFile(namespaceFile) + if err != nil { + return fmt.Errorf("error reading namespace file: %w", err) + } + + namespace := string(rawNamespace) + + serviceName := fmt.Sprintf("opentelemetry-operator-controller-manager-metrics-service.%s.svc", namespace) + + sm := monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: "opentelemetry-operator-metrics-monitor", + Namespace: namespace, + Labels: map[string]string{ + "app.kubernetes.io/name": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry-operator", + "control-plane": "controller-manager", + }, + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/name": "opentelemetry-operator", + }, + }, + Endpoints: []monitoringv1.Endpoint{ + { + BearerTokenFile: "/var/run/secrets/kubernetes.io/serviceaccount/token", + Interval: "30s", + Path: "/metrics", + Scheme: "https", + ScrapeTimeout: "10s", + TargetPort: &intstr.IntOrString{IntVal: 8443}, + TLSConfig: &monitoringv1.TLSConfig{ + CAFile: "/etc/prometheus/configmaps/serving-certs-ca-bundle/service-ca.crt", + SafeTLSConfig: monitoringv1.SafeTLSConfig{ + ServerName: &serviceName, + }, + }, + }, + }, + }, + } + + err = d.kubeClient.Create(ctx, &sm) + if err != nil { + return fmt.Errorf("error creating service monitor: %w", err) + } + + <-ctx.Done() + + return d.kubeClient.Delete(ctx, &sm) +} + +func (d OperatorMetrics) NeedLeaderElection() bool { + return true +} diff --git a/internal/operator-metrics/metrics_test.go b/internal/operator-metrics/metrics_test.go new file mode 100644 index 0000000000..d6292019af --- /dev/null +++ b/internal/operator-metrics/metrics_test.go @@ -0,0 +1,68 @@ +package operatormetrics + +import ( + "context" + "os" + "testing" + + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" +) + +func TestNewOperatorMetrics(t *testing.T) { + config := &rest.Config{} + scheme := runtime.NewScheme() + + om, err := NewOperatorMetrics(config, scheme) + assert.NoError(t, err) + assert.NotNil(t, om.kubeClient) +} + +func TestOperatorMetrics_Start(t *testing.T) { + scheme := runtime.NewScheme() + err := monitoringv1.AddToScheme(scheme) + require.NoError(t, err) + + fakeClient := fake.NewClientBuilder().WithScheme(scheme).Build() + + om := OperatorMetrics{ + kubeClient: fakeClient, + } + + tmpfile, err := os.CreateTemp("", "namespace") + require.NoError(t, err) + defer os.Remove(tmpfile.Name()) + + _, err = tmpfile.Write([]byte("test-namespace")) + require.NoError(t, err) + err = tmpfile.Close() + require.NoError(t, err) + + oldNamespaceFile := namespaceFile + namespaceFile = tmpfile.Name() + defer func() { namespaceFile = oldNamespaceFile }() + + ctx, cancel := context.WithCancel(context.Background()) + errChan := make(chan error) + + go func() { + errChan <- om.Start(ctx) + }() + + cancel() + + err = <-errChan + assert.NoError(t, err) + + var sm monitoringv1.ServiceMonitor + err = fakeClient.Get(context.Background(), client.ObjectKey{ + Name: "opentelemetry-operator-metrics-monitor", + Namespace: "test-namespace", + }, &sm) + assert.Error(t, err) +} diff --git a/main.go b/main.go index 8d37edce7d..d52abb382b 100644 --- a/main.go +++ b/main.go @@ -58,6 +58,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/internal/fips" collectorManifests "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector" openshiftDashboards "github.com/open-telemetry/opentelemetry-operator/internal/openshift/dashboards" + operatormetrics "github.com/open-telemetry/opentelemetry-operator/internal/operator-metrics" "github.com/open-telemetry/opentelemetry-operator/internal/rbac" "github.com/open-telemetry/opentelemetry-operator/internal/version" "github.com/open-telemetry/opentelemetry-operator/internal/webhook/podmutation" @@ -435,6 +436,16 @@ func main() { setupLog.Error(err, "Error init CRD metrics") } + if cfg.PrometheusCRAvailability() == prometheus.Available { + operatorMetrics, opError := operatormetrics.NewOperatorMetrics(mgr.GetConfig(), scheme) + if opError != nil { + setupLog.Error(opError, "Failed to create the operator metrics SM") + } + err = mgr.Add(operatorMetrics) + if err != nil { + setupLog.Error(err, "Failed to add the operator metrics SM") + } + } } bv := func(collector otelv1beta1.OpenTelemetryCollector) admission.Warnings {