From d3c98ae529fee23ccc92c6722ca2141406a3dc40 Mon Sep 17 00:00:00 2001 From: Israel Blancas Date: Mon, 21 Aug 2023 14:26:07 +0200 Subject: [PATCH] Create Service Monitors for the Prometheus exporters (#1983) * Create Service Monitors for the Prometheus exporters * Remove testing changes Signed-off-by: Israel Blancas * Remove pull policy Signed-off-by: Israel Blancas * Apply changes requested in PR * Fix E2E test Signed-off-by: Israel Blancas * Update E2E test to use the enableMetrics flag Signed-off-by: Israel Blancas * Use the enable metrics to create the SM or not Signed-off-by: Israel Blancas * Update field description Signed-off-by: Israel Blancas * Add missing docs Signed-off-by: Israel Blancas * Remove config Signed-off-by: Israel Blancas * Ensue the ServiceMonitor matches a specific OpenTelemetry Collector instance Signed-off-by: Israel Blancas * Update generated files Signed-off-by: Israel Blancas * Fix comment Signed-off-by: Israel Blancas --------- Signed-off-by: Israel Blancas --- ...ice-monitors-for-prometheus-exporters.yaml | 16 ++ apis/v1alpha1/opentelemetrycollector_types.go | 2 +- ...emetry-operator.clusterserviceversion.yaml | 6 +- ...ntelemetry.io_opentelemetrycollectors.yaml | 6 +- ...ntelemetry.io_opentelemetrycollectors.yaml | 6 +- ...emetry-operator.clusterserviceversion.yaml | 6 +- docs/api.md | 2 +- go.mod | 1 + go.sum | 4 +- .../collector/adapters/config_to_ports.go | 97 +++++++++++- .../adapters/config_to_ports_test.go | 4 +- .../collector/adapters/config_validate.go | 42 +++--- internal/manifests/collector/container.go | 65 +------- .../manifests/collector/container_test.go | 44 +++--- .../collector/parser/exporter/exporter.go | 139 ++++++++++++++++++ .../parser/exporter/exporter_prometheus.go | 76 ++++++++++ .../parser/{ => receiver}/receiver.go | 4 +- .../{ => receiver}/receiver_aws-xray.go | 2 +- .../{ => receiver}/receiver_aws-xray_test.go | 2 +- .../parser/{ => receiver}/receiver_carbon.go | 2 +- .../{ => receiver}/receiver_carbon_test.go | 2 +- .../{ => receiver}/receiver_collectd.go | 2 +- .../{ => receiver}/receiver_collectd_test.go | 2 +- .../{ => receiver}/receiver_fluent-forward.go | 2 +- .../receiver_fluent-forward_test.go | 2 +- .../parser/{ => receiver}/receiver_generic.go | 2 +- .../{ => receiver}/receiver_generic_test.go | 36 ++--- .../{ => receiver}/receiver_influxdb.go | 2 +- .../{ => receiver}/receiver_influxdb_test.go | 2 +- .../parser/{ => receiver}/receiver_jaeger.go | 2 +- .../{ => receiver}/receiver_jaeger_test.go | 2 +- .../parser/{ => receiver}/receiver_oc.go | 2 +- .../parser/{ => receiver}/receiver_oc_test.go | 2 +- .../parser/{ => receiver}/receiver_otlp.go | 2 +- .../{ => receiver}/receiver_otlp_test.go | 2 +- .../parser/{ => receiver}/receiver_sapm.go | 2 +- .../{ => receiver}/receiver_sapm_test.go | 2 +- .../{ => receiver}/receiver_signalfx.go | 2 +- .../{ => receiver}/receiver_signalfx_test.go | 2 +- .../{ => receiver}/receiver_skywalking.go | 2 +- .../receiver_skywalking_test.go | 2 +- .../{ => receiver}/receiver_splunk-hec.go | 2 +- .../receiver_splunk-hec_test.go | 2 +- .../parser/{ => receiver}/receiver_statsd.go | 2 +- .../{ => receiver}/receiver_statsd_test.go | 2 +- .../parser/{ => receiver}/receiver_test.go | 2 +- .../{ => receiver}/receiver_wavefront.go | 2 +- .../{ => receiver}/receiver_wavefront_test.go | 2 +- .../{ => receiver}/receiver_zipkin-scribe.go | 2 +- .../receiver_zipkin-scribe_test.go | 2 +- .../parser/{ => receiver}/receiver_zipkin.go | 2 +- .../{ => receiver}/receiver_zipkin_test.go | 2 +- internal/manifests/collector/service.go | 6 +- .../manifests/collector/servicemonitor.go | 56 ++++++- .../collector/servicemonitor_test.go | 21 +++ .../testdata/prometheus-exporter.yaml | 19 +++ pkg/collector/reconcile/servicemonitor.go | 10 +- .../00-install.yaml | 4 + .../01-assert.yaml | 65 ++++++++ .../01-install.yaml | 29 ++++ .../02-assert.yaml | 42 ++++++ .../02-install.yaml} | 14 +- .../03-assert.yaml | 21 +++ .../03-install.yaml | 26 ++++ .../04-error.yaml | 19 +++ .../04-install.yaml | 26 ++++ .../05-assert.yaml | 21 +++ .../05-error.yaml | 22 +++ .../05-install.yaml | 32 ++++ .../06-assert.yaml | 20 +++ .../06-install.yaml | 29 ++++ .../07-delete.yaml | 8 + .../07-error.yaml | 5 + .../00-assert.yaml | 10 -- 74 files changed, 927 insertions(+), 202 deletions(-) create mode 100755 .chloggen/1963-create-service-monitors-for-prometheus-exporters.yaml create mode 100644 internal/manifests/collector/parser/exporter/exporter.go create mode 100644 internal/manifests/collector/parser/exporter/exporter_prometheus.go rename internal/manifests/collector/parser/{ => receiver}/receiver.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_aws-xray.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_aws-xray_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_carbon.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_carbon_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_collectd.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_collectd_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_fluent-forward.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_fluent-forward_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_generic.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_generic_test.go (67%) rename internal/manifests/collector/parser/{ => receiver}/receiver_influxdb.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_influxdb_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_jaeger.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_jaeger_test.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_oc.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_oc_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_otlp.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_otlp_test.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_sapm.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_sapm_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_signalfx.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_signalfx_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_skywalking.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_skywalking_test.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_splunk-hec.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_splunk-hec_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_statsd.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_statsd_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_test.go (99%) rename internal/manifests/collector/parser/{ => receiver}/receiver_wavefront.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_wavefront_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_zipkin-scribe.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_zipkin-scribe_test.go (97%) rename internal/manifests/collector/parser/{ => receiver}/receiver_zipkin.go (98%) rename internal/manifests/collector/parser/{ => receiver}/receiver_zipkin_test.go (97%) create mode 100644 internal/manifests/collector/testdata/prometheus-exporter.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/00-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-assert.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-assert.yaml rename tests/e2e-prometheuscr/{gather-metrics-from-operands/00-install.yaml => create-sm-prometheus-exporters/02-install.yaml} (64%) create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-assert.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-error.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-assert.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-error.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-assert.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-install.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-delete.yaml create mode 100644 tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-error.yaml delete mode 100644 tests/e2e-prometheuscr/gather-metrics-from-operands/00-assert.yaml diff --git a/.chloggen/1963-create-service-monitors-for-prometheus-exporters.yaml b/.chloggen/1963-create-service-monitors-for-prometheus-exporters.yaml new file mode 100755 index 0000000000..5ca0eddad7 --- /dev/null +++ b/.chloggen/1963-create-service-monitors-for-prometheus-exporters.yaml @@ -0,0 +1,16 @@ +# 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. operator, target allocator, github action) +component: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Create ServiceMonitors when the Prometheus exporters are used. + +# One or more tracking issues related to the change +issues: [1963] + +# (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: \ No newline at end of file diff --git a/apis/v1alpha1/opentelemetrycollector_types.go b/apis/v1alpha1/opentelemetrycollector_types.go index 35fa89e36c..c95d64e436 100644 --- a/apis/v1alpha1/opentelemetrycollector_types.go +++ b/apis/v1alpha1/opentelemetrycollector_types.go @@ -426,7 +426,7 @@ type AutoscalerSpec struct { // MetricsConfigSpec defines a metrics config. type MetricsConfigSpec struct { - // EnableMetrics specifies if ServiceMonitors should be created for the OpenTelemetry Collector. + // EnableMetrics specifies if ServiceMonitor should be created for the OpenTelemetry Collector and Prometheus Exporters. // The operator.observability.prometheus feature gate must be enabled to use this feature. // // +optional diff --git a/bundle/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/manifests/opentelemetry-operator.clusterserviceversion.yaml index 39850294e7..64d5b2402d 100644 --- a/bundle/manifests/opentelemetry-operator.clusterserviceversion.yaml +++ b/bundle/manifests/opentelemetry-operator.clusterserviceversion.yaml @@ -83,9 +83,9 @@ spec: - description: Metrics defines the metrics configuration for operands. displayName: Metrics Config path: observability.metrics - - description: EnableMetrics specifies if ServiceMonitors should be created - for the OpenTelemetry Collector. The operator.observability.prometheus feature - gate must be enabled to use this feature. + - description: EnableMetrics specifies if ServiceMonitor should be created for + the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.prometheus + feature gate must be enabled to use this feature. displayName: Create ServiceMonitors for OpenTelemetry Collector path: observability.metrics.enableMetrics version: v1alpha1 diff --git a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml index 60be57f87b..c0b671a75c 100644 --- a/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml +++ b/bundle/manifests/opentelemetry.io_opentelemetrycollectors.yaml @@ -3690,9 +3690,9 @@ spec: description: Metrics defines the metrics configuration for operands. properties: enableMetrics: - description: EnableMetrics specifies if ServiceMonitors should - be created for the OpenTelemetry Collector. The operator.observability.prometheus - feature gate must be enabled to use this feature. + description: EnableMetrics specifies if ServiceMonitor should + be created for the OpenTelemetry Collector and Prometheus + Exporters. The operator.observability. type: boolean type: object type: object diff --git a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml index 11a8739756..708270faae 100644 --- a/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml +++ b/config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml @@ -3687,9 +3687,9 @@ spec: description: Metrics defines the metrics configuration for operands. properties: enableMetrics: - description: EnableMetrics specifies if ServiceMonitors should - be created for the OpenTelemetry Collector. The operator.observability.prometheus - feature gate must be enabled to use this feature. + description: EnableMetrics specifies if ServiceMonitor should + be created for the OpenTelemetry Collector and Prometheus + Exporters. The operator.observability. type: boolean type: object type: object diff --git a/config/manifests/bases/opentelemetry-operator.clusterserviceversion.yaml b/config/manifests/bases/opentelemetry-operator.clusterserviceversion.yaml index c762dd3bfb..cfeef3041d 100644 --- a/config/manifests/bases/opentelemetry-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/opentelemetry-operator.clusterserviceversion.yaml @@ -63,9 +63,9 @@ spec: - description: Metrics defines the metrics configuration for operands. displayName: Metrics Config path: observability.metrics - - description: EnableMetrics specifies if ServiceMonitors should be created - for the OpenTelemetry Collector. The operator.observability.prometheus feature - gate must be enabled to use this feature. + - description: EnableMetrics specifies if ServiceMonitor should be created for + the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.prometheus + feature gate must be enabled to use this feature. displayName: Create ServiceMonitors for OpenTelemetry Collector path: observability.metrics.enableMetrics version: v1alpha1 diff --git a/docs/api.md b/docs/api.md index 3142057b8f..ad00221c45 100644 --- a/docs/api.md +++ b/docs/api.md @@ -11410,7 +11410,7 @@ Metrics defines the metrics configuration for operands. enableMetrics boolean - EnableMetrics specifies if ServiceMonitors should be created for the OpenTelemetry Collector. The operator.observability.prometheus feature gate must be enabled to use this feature.
+ EnableMetrics specifies if ServiceMonitor should be created for the OpenTelemetry Collector and Prometheus Exporters. The operator.observability.
false diff --git a/go.mod b/go.mod index 07015b297c..db19580b03 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 go.opentelemetry.io/collector/featuregate v0.77.0 + go.opentelemetry.io/collector/semconv v0.82.0 go.opentelemetry.io/otel v1.16.0 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.28.0 diff --git a/go.sum b/go.sum index 6db68e53d1..71848726a7 100644 --- a/go.sum +++ b/go.sum @@ -311,7 +311,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= @@ -526,6 +526,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector/featuregate v0.77.0 h1:m1/IzaXoQh6SgF6CM80vrBOCf5zSJ2GVISfA27fYzGU= go.opentelemetry.io/collector/featuregate v0.77.0/go.mod h1:/kVAsGUCyJXIDSgHftCN63QiwAEVHRLX2Kh/S+dqgHY= +go.opentelemetry.io/collector/semconv v0.82.0 h1:WUeT2a+uZjI6kLvwcBaJnGvo7KSQ/9dIFRcxOQdXucc= +go.opentelemetry.io/collector/semconv v0.82.0/go.mod h1:TlYPtzvsXyHOgr5eATi43qEMqwSmIziivJB2uctKswo= go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index 530898e5ed..6b11f3c3c7 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -24,17 +24,91 @@ import ( "github.com/mitchellh/mapstructure" corev1 "k8s.io/api/core/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser" + exporterParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/exporter" + receiverParser "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver" ) var ( + // ErrNoExporters indicates that there are no exporters in the configuration. + ErrNoExporters = errors.New("no exporters available as part of the configuration") + // ErrNoReceivers indicates that there are no receivers in the configuration. ErrNoReceivers = errors.New("no receivers available as part of the configuration") // ErrReceiversNotAMap indicates that the receivers property isn't a map of values. ErrReceiversNotAMap = errors.New("receivers property in the configuration doesn't contain valid receivers") + + // ErrExportersNotAMap indicates that the exporters property isn't a map of values. + ErrExportersNotAMap = errors.New("exporters property in the configuration doesn't contain valid exporters") ) +// ConfigToExporterPorts converts the incoming configuration object into a set of service ports required by the exporters. +func ConfigToExporterPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { + // now, we gather which ports we might need to open + // for that, we get all the exporters and check their `endpoint` properties, + // extracting the port from it. The port name has to be a "DNS_LABEL", so, we try to make it follow the pattern: + // ${instance.Name}-${exporter.name}-${exporter.qualifier} + // the exporter-name is typically the node name from the exporters map + // the exporter-qualifier is what comes after the slash in the exporter name, but typically nil + // examples: + // ```yaml + // exporters: + // exampleexporter: + // endpoint: 0.0.0.0:12345 + // exampleexporter/settings: + // endpoint: 0.0.0.0:12346 + // in this case, we have two ports, named: "exampleexporter" and "exampleexporter-settings" + exportersProperty, ok := config["exporters"] + if !ok { + return nil, ErrNoExporters + } + expEnabled := GetEnabledExporters(logger, config) + if expEnabled == nil { + return nil, ErrExportersNotAMap + } + exporters, ok := exportersProperty.(map[interface{}]interface{}) + if !ok { + return nil, ErrExportersNotAMap + } + + ports := []corev1.ServicePort{} + for key, val := range exporters { + // This check will pass only the enabled exporters, + // then only the related ports will be opened. + if !expEnabled[key] { + continue + } + exporter, ok := val.(map[interface{}]interface{}) + if !ok { + logger.Info("exporter doesn't seem to be a map of properties", "exporter", key) + exporter = map[interface{}]interface{}{} + } + + exprtName := key.(string) + exprtParser, err := exporterParser.For(logger, exprtName, exporter) + if err != nil { + logger.V(2).Info("no parser found for '%s'", exprtName) + continue + } + + exprtPorts, err := exprtParser.Ports() + if err != nil { + logger.Error(err, "parser for '%s' has returned an error: %w", exprtName, err) + continue + } + + if len(exprtPorts) > 0 { + ports = append(ports, exprtPorts...) + } + } + + sort.Slice(ports, func(i, j int) bool { + return ports[i].Name < ports[j].Name + }) + + return ports, nil +} + // ConfigToReceiverPorts converts the incoming configuration object into a set of service ports required by the receivers. func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { // now, we gather which ports we might need to open @@ -78,7 +152,7 @@ func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{ } rcvrName := key.(string) - rcvrParser := parser.For(logger, rcvrName, receiver) + rcvrParser := receiverParser.For(logger, rcvrName, receiver) rcvrPorts, err := rcvrParser.Ports() if err != nil { @@ -101,6 +175,25 @@ func ConfigToReceiverPorts(logger logr.Logger, config map[interface{}]interface{ return ports, nil } +func ConfigToPorts(logger logr.Logger, config map[interface{}]interface{}) []corev1.ServicePort { + ports, err := ConfigToReceiverPorts(logger, config) + if err != nil { + logger.Error(err, "there was a problem while getting the ports from the receivers") + } + + exporterPorts, err := ConfigToExporterPorts(logger, config) + if err != nil { + logger.Error(err, "there was a problem while getting the ports from the exporters") + } + ports = append(ports, exporterPorts...) + + sort.Slice(ports, func(i, j int) bool { + return ports[i].Name < ports[j].Name + }) + + return ports +} + // ConfigToMetricsPort gets the port number for the metrics endpoint from the collector config if it has been set. func ConfigToMetricsPort(logger logr.Logger, config map[interface{}]interface{}) (int32, error) { // we don't need to unmarshal the whole config, just follow the keys down to diff --git a/internal/manifests/collector/adapters/config_to_ports_test.go b/internal/manifests/collector/adapters/config_to_ports_test.go index 5f1bd1fab2..07be4f0bae 100644 --- a/internal/manifests/collector/adapters/config_to_ports_test.go +++ b/internal/manifests/collector/adapters/config_to_ports_test.go @@ -26,7 +26,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver" ) var logger = logf.Log.WithName("unit-tests") @@ -179,7 +179,7 @@ func TestParserFailed(t *testing.T) { return nil, errors.New("mocked error") }, } - parser.Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ReceiverParser { + receiver.Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) receiver.ReceiverParser { return mockParser }) diff --git a/internal/manifests/collector/adapters/config_validate.go b/internal/manifests/collector/adapters/config_validate.go index 37c6e6ec98..221a4f21a6 100644 --- a/internal/manifests/collector/adapters/config_validate.go +++ b/internal/manifests/collector/adapters/config_validate.go @@ -21,25 +21,33 @@ import ( // Following Otel Doc: Configuring a receiver does not enable it. The receivers are enabled via pipelines within the service section. // GetEnabledReceivers returns all enabled receivers as a true flag set. If it can't find any receiver, it will return a nil interface. func GetEnabledReceivers(_ logr.Logger, config map[interface{}]interface{}) map[interface{}]bool { - cfgReceivers, ok := config["receivers"] + return getEnabledComponents(config, "receivers") +} + +func GetEnabledExporters(_ logr.Logger, config map[interface{}]interface{}) map[interface{}]bool { + return getEnabledComponents(config, "exporters") +} + +func getEnabledComponents(config map[interface{}]interface{}, componentType string) map[interface{}]bool { + cfgComponents, ok := config[componentType] if !ok { return nil } - receivers, ok := cfgReceivers.(map[interface{}]interface{}) + components, ok := cfgComponents.(map[interface{}]interface{}) if !ok { return nil } - availableReceivers := map[interface{}]bool{} + availableComponents := map[interface{}]bool{} - for recvID := range receivers { + for compID := range components { //Safe Cast - receiverID, withReceiver := recvID.(string) - if !withReceiver { + componentID, withComponent := compID.(string) + if !withComponent { return nil } - //Getting all receivers present in the receivers section and setting them to false. - availableReceivers[receiverID] = false + //Getting all components present in the components (exporters,receivers...) section and setting them to false. + availableComponents[componentID] = false } cfgService, withService := config["service"].(map[interface{}]interface{}) @@ -77,29 +85,29 @@ func GetEnabledReceivers(_ logr.Logger, config map[interface{}]interface{}) map[ return nil } for pipSpecID, pipSpecCfg := range pipelineDesc { - if pipSpecID.(string) == "receivers" { + if pipSpecID.(string) == componentType { receiversList, ok := pipSpecCfg.([]interface{}) if !ok { continue } // If receiversList is empty means that we haven't any enabled Receiver. if len(receiversList) == 0 { - availableReceivers = nil + availableComponents = nil } else { // All enabled receivers will be set as true - for _, recKey := range receiversList { + for _, comKey := range receiversList { //Safe Cast - receiverKey, ok := recKey.(string) + receiverKey, ok := comKey.(string) if !ok { return nil } - availableReceivers[receiverKey] = true + availableComponents[receiverKey] = true } } //Removing all non-enabled receivers - for recID, recKey := range availableReceivers { - if !(recKey) { - delete(availableReceivers, recID) + for comID, comKey := range availableComponents { + if !(comKey) { + delete(availableComponents, comID) } } } @@ -107,5 +115,5 @@ func GetEnabledReceivers(_ logr.Logger, config map[interface{}]interface{}) map[ } } } - return availableReceivers + return availableComponents } diff --git a/internal/manifests/collector/container.go b/internal/manifests/collector/container.go index f7e1e1b60b..b9e00d41ba 100644 --- a/internal/manifests/collector/container.go +++ b/internal/manifests/collector/container.go @@ -16,10 +16,7 @@ package collector import ( "fmt" - "net" "sort" - "strconv" - "strings" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" @@ -151,10 +148,8 @@ func getConfigContainerPorts(logger logr.Logger, cfg string) map[string]corev1.C logger.Error(err, "couldn't extract the configuration") return ports } - ps, err := adapters.ConfigToReceiverPorts(logger, c) - if err != nil { - logger.Error(err, "couldn't build container ports from configuration") - } else { + ps := adapters.ConfigToPorts(logger, c) + if len(ps) > 0 { for _, p := range ps { truncName := naming.Truncate(p.Name, maxPortLen) if p.Name != truncName { @@ -187,65 +182,9 @@ func getConfigContainerPorts(logger logr.Logger, cfg string) map[string]corev1.C Protocol: corev1.ProtocolTCP, } - promExporterPorts, errs := getPrometheusExporterPorts(c) - for _, err := range errs { - logger.V(2).Info("There was a problem getting the prometheus exporter port: %s", err) - } - for _, promPort := range promExporterPorts { - ports[promPort.Name] = promPort - } - return ports } -func getPrometheusExporterPort(exporterConfig map[interface{}]interface{}) (int32, error) { - var promPort int32 = 0 - if endpoint, ok := exporterConfig["endpoint"]; ok { - _, port, err := net.SplitHostPort(endpoint.(string)) - if err != nil { - return 0, err - } - i64, err := strconv.ParseInt(port, 10, 32) - if err != nil { - return 0, err - } - promPort = int32(i64) - } - return promPort, nil -} - -func getPrometheusExporterPorts(c map[interface{}]interface{}) ([]corev1.ContainerPort, []error) { - errors := make([]error, 0) - ports := make([]corev1.ContainerPort, 0) - if exporters, ok := c["exporters"]; ok && exporters != nil { - for e, exporterConfig := range exporters.(map[interface{}]interface{}) { - exporterName := e.(string) - // Note that receivers, processors, exporters and/or pipelines are defined via component identifiers in type[/name] format (e.g. otlp or otlp/2). Components of a given type can be defined more than once as long as the identifiers are unique. - if strings.Split(exporterName, "/")[0] == "prometheus" { - containerPort, err := getPrometheusExporterPort(exporterConfig.(map[interface{}]interface{})) - if err != nil { - errors = append(errors, - fmt.Errorf( - "there was a problem getting the port. Exporter %s", - exporterName, - ), - ) - } - ports = append(ports, - corev1.ContainerPort{ - Name: naming.PortName(exporterName, containerPort), - ContainerPort: containerPort, - Protocol: corev1.ProtocolTCP, - }, - ) - } - } - } else { - errors = append(errors, fmt.Errorf("no exporters specified in the configuration")) - } - return ports, errors -} - func portMapToList(portMap map[string]corev1.ContainerPort) []corev1.ContainerPort { ports := make([]corev1.ContainerPort, 0, len(portMap)) for _, p := range portMap { diff --git a/internal/manifests/collector/container_test.go b/internal/manifests/collector/container_test.go index b20c2bc995..cfb30c3f02 100644 --- a/internal/manifests/collector/container_test.go +++ b/internal/manifests/collector/container_test.go @@ -181,14 +181,19 @@ service: description: "prometheus exporter", specConfig: `exporters: prometheus: - endpoint: "0.0.0.0:9090"`, + endpoint: "0.0.0.0:9090" +service: + pipelines: + metrics: + exporters: [prometheus] +`, + specPorts: []corev1.ServicePort{}, expectedPorts: []corev1.ContainerPort{ metricContainerPort, { Name: "prometheus", ContainerPort: 9090, - Protocol: corev1.ProtocolTCP, }, }, }, @@ -198,19 +203,22 @@ service: prometheus/prod: endpoint: "0.0.0.0:9090" prometheus/dev: - endpoint: "0.0.0.0:9091"`, + endpoint: "0.0.0.0:9091" +service: + pipelines: + metrics: + exporters: [prometheus/prod, prometheus/dev] +`, specPorts: []corev1.ServicePort{}, expectedPorts: []corev1.ContainerPort{ metricContainerPort, - { - Name: "prometheus-prod", - ContainerPort: 9090, - Protocol: corev1.ProtocolTCP, - }, { Name: "prometheus-dev", ContainerPort: 9091, - Protocol: corev1.ProtocolTCP, + }, + { + Name: "prometheus-prod", + ContainerPort: 9090, }, }, }, @@ -230,19 +238,21 @@ service: prometheus/dev: endpoint: "0.0.0.0:9091" prometheusremotewrite/prometheus: - endpoint: http://prometheus-server.monitoring/api/v1/write`, + endpoint: http://prometheus-server.monitoring/api/v1/write +service: + pipelines: + metrics: + exporters: [prometheus/prod, prometheus/dev, prometheusremotewrite/prometheus]`, specPorts: []corev1.ServicePort{}, expectedPorts: []corev1.ContainerPort{ metricContainerPort, - { - Name: "prometheus-prod", - ContainerPort: 9090, - Protocol: corev1.ProtocolTCP, - }, { Name: "prometheus-dev", ContainerPort: 9091, - Protocol: corev1.ProtocolTCP, + }, + { + Name: "prometheus-prod", + ContainerPort: 9090, }, }, }, @@ -263,7 +273,7 @@ service: c := Container(cfg, logger, otelcol, true) // verify - assert.ElementsMatch(t, testCase.expectedPorts, c.Ports) + assert.ElementsMatch(t, testCase.expectedPorts, c.Ports, testCase.description) }) } } diff --git a/internal/manifests/collector/parser/exporter/exporter.go b/internal/manifests/collector/parser/exporter/exporter.go new file mode 100644 index 0000000000..ae0282f736 --- /dev/null +++ b/internal/manifests/collector/parser/exporter/exporter.go @@ -0,0 +1,139 @@ +// 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 parser is for parsing the OpenTelemetry Collector configuration. +package exporter + +import ( + "errors" + "fmt" + "regexp" + "strconv" + "strings" + + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + + "github.com/open-telemetry/opentelemetry-operator/internal/naming" +) + +// ExporterParser is an interface that should be implemented by all exporter parsers. +type ExporterParser interface { + // Ports returns the service ports parsed based on the exporter's configuration + Ports() ([]corev1.ServicePort, error) + + // ParserName returns the name of this parser + ParserName() string +} + +// Builder specifies the signature required for parser builders. +type Builder func(logr.Logger, string, map[interface{}]interface{}) ExporterParser + +// registry holds a record of all known parsers. +var registry = make(map[string]Builder) + +// BuilderFor returns a parser builder for the given exporter name. +func BuilderFor(name string) Builder { + return registry[exporterType(name)] +} + +// For returns a new parser for the given exporter name + config. +func For(logger logr.Logger, name string, config map[interface{}]interface{}) (ExporterParser, error) { + builder := BuilderFor(name) + if builder == nil { + return nil, fmt.Errorf("no builders for %s", name) + } + return builder(logger, name, config), nil +} + +// Register adds a new parser builder to the list of known builders. +func Register(name string, builder Builder) { + registry[name] = builder +} + +// IsRegistered checks whether a parser is registered with the given name. +func IsRegistered(name string) bool { + _, ok := registry[name] + return ok +} + +var ( + endpointKey = "endpoint" +) + +func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[interface{}]interface{}) *corev1.ServicePort { + endpoint := getAddressFromConfig(logger, name, endpointKey, config) + + switch e := endpoint.(type) { + case nil: + break + case string: + port, err := portFromEndpoint(e) + if err != nil { + logger.WithValues(endpointKey, e).Error(err, "couldn't parse the endpoint's port") + return nil + } + + return &corev1.ServicePort{ + Name: naming.PortName(name, port), + Port: port, + } + default: + logger.WithValues(endpointKey, endpoint).Error(fmt.Errorf("unrecognized type %T", endpoint), "exporter's endpoint isn't a string") + } + + return nil +} + +func getAddressFromConfig(logger logr.Logger, name, key string, config map[interface{}]interface{}) interface{} { + endpoint, ok := config[key] + if !ok { + logger.V(2).Info("%s exporter doesn't have an %s", name, key) + return nil + } + return endpoint +} + +func portFromEndpoint(endpoint string) (int32, error) { + var err error + var port int64 + + r := regexp.MustCompile(":[0-9]+") + + if r.MatchString(endpoint) { + port, err = strconv.ParseInt(strings.Replace(r.FindString(endpoint), ":", "", -1), 10, 32) + + if err != nil { + return 0, err + } + } + + if port == 0 { + return 0, errors.New("port should not be empty") + } + + return int32(port), err +} + +func exporterType(name string) string { + // exporters have a name like: + // - myexporter/custom + // - myexporter + // we extract the "myexporter" part and see if we have a parser for the exporter + if strings.Contains(name, "/") { + return name[:strings.Index(name, "/")] + } + + return name +} diff --git a/internal/manifests/collector/parser/exporter/exporter_prometheus.go b/internal/manifests/collector/parser/exporter/exporter_prometheus.go new file mode 100644 index 0000000000..cc9e17748b --- /dev/null +++ b/internal/manifests/collector/parser/exporter/exporter_prometheus.go @@ -0,0 +1,76 @@ +// 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 exporter + +import ( + "github.com/go-logr/logr" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + "github.com/open-telemetry/opentelemetry-operator/internal/naming" +) + +var _ ExporterParser = &PrometheusExporterParser{} + +const ( + parserNamePrometheus = "__prometheus" + defaultPrometheusPort = 8888 +) + +// PrometheusExporterParser parses the configuration for OTLP receivers. +type PrometheusExporterParser struct { + config map[interface{}]interface{} + logger logr.Logger + name string +} + +// NewPrometheusExporterParser builds a new parser for OTLP receivers. +func NewPrometheusExporterParser(logger logr.Logger, name string, config map[interface{}]interface{}) ExporterParser { + return &PrometheusExporterParser{ + logger: logger, + name: name, + config: config, + } +} + +// Ports returns all the service ports for all protocols in this parser. +func (o *PrometheusExporterParser) Ports() ([]corev1.ServicePort, error) { + ports := []corev1.ServicePort{} + if o.config == nil { + ports = append(ports, + corev1.ServicePort{ + Name: naming.PortName(o.name, defaultPrometheusPort), + Port: defaultPrometheusPort, + TargetPort: intstr.FromInt(int(defaultPrometheusPort)), + Protocol: corev1.ProtocolTCP, + }, + ) + } else { + ports = append( + ports, *singlePortFromConfigEndpoint(o.logger, o.name, o.config), + ) + } + + return ports, nil +} + +// ParserName returns the name of this parser. +func (o *PrometheusExporterParser) ParserName() string { + return parserNamePrometheus +} + +func init() { + Register("prometheus", NewPrometheusExporterParser) +} diff --git a/internal/manifests/collector/parser/receiver.go b/internal/manifests/collector/parser/receiver/receiver.go similarity index 98% rename from internal/manifests/collector/parser/receiver.go rename to internal/manifests/collector/parser/receiver/receiver.go index dcf7a6f55c..88c6b4bcf2 100644 --- a/internal/manifests/collector/parser/receiver.go +++ b/internal/manifests/collector/parser/receiver/receiver.go @@ -13,7 +13,7 @@ // limitations under the License. // Package parser is for parsing the OpenTelemetry Collector configuration. -package parser +package receiver import ( "errors" @@ -190,7 +190,7 @@ func portFromEndpoint(endpoint string) (int32, error) { } if port == 0 { - return 0, errors.New("Port should not be empty") + return 0, errors.New("port should not be empty") } return int32(port), err diff --git a/internal/manifests/collector/parser/receiver_aws-xray.go b/internal/manifests/collector/parser/receiver/receiver_aws-xray.go similarity index 98% rename from internal/manifests/collector/parser/receiver_aws-xray.go rename to internal/manifests/collector/parser/receiver/receiver_aws-xray.go index 6d8f92c7bb..f5569f247e 100644 --- a/internal/manifests/collector/parser/receiver_aws-xray.go +++ b/internal/manifests/collector/parser/receiver/receiver_aws-xray.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_aws-xray_test.go b/internal/manifests/collector/parser/receiver/receiver_aws-xray_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_aws-xray_test.go rename to internal/manifests/collector/parser/receiver/receiver_aws-xray_test.go index bbd752f080..5a99f9e893 100644 --- a/internal/manifests/collector/parser/receiver_aws-xray_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_aws-xray_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the AWS XRAY parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_carbon.go b/internal/manifests/collector/parser/receiver/receiver_carbon.go similarity index 98% rename from internal/manifests/collector/parser/receiver_carbon.go rename to internal/manifests/collector/parser/receiver/receiver_carbon.go index 26f073ebe8..45c3c04473 100644 --- a/internal/manifests/collector/parser/receiver_carbon.go +++ b/internal/manifests/collector/parser/receiver/receiver_carbon.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_carbon_test.go b/internal/manifests/collector/parser/receiver/receiver_carbon_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_carbon_test.go rename to internal/manifests/collector/parser/receiver/receiver_carbon_test.go index 22a5cb9273..370732182d 100644 --- a/internal/manifests/collector/parser/receiver_carbon_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_carbon_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Carbon parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_collectd.go b/internal/manifests/collector/parser/receiver/receiver_collectd.go similarity index 98% rename from internal/manifests/collector/parser/receiver_collectd.go rename to internal/manifests/collector/parser/receiver/receiver_collectd.go index 9426399a45..d18e6b72b2 100644 --- a/internal/manifests/collector/parser/receiver_collectd.go +++ b/internal/manifests/collector/parser/receiver/receiver_collectd.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_collectd_test.go b/internal/manifests/collector/parser/receiver/receiver_collectd_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_collectd_test.go rename to internal/manifests/collector/parser/receiver/receiver_collectd_test.go index fe63c75cf5..5e0e6d0121 100644 --- a/internal/manifests/collector/parser/receiver_collectd_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_collectd_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Collectd parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_fluent-forward.go b/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go similarity index 98% rename from internal/manifests/collector/parser/receiver_fluent-forward.go rename to internal/manifests/collector/parser/receiver/receiver_fluent-forward.go index 94170fa051..c55debd964 100644 --- a/internal/manifests/collector/parser/receiver_fluent-forward.go +++ b/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_fluent-forward_test.go b/internal/manifests/collector/parser/receiver/receiver_fluent-forward_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_fluent-forward_test.go rename to internal/manifests/collector/parser/receiver/receiver_fluent-forward_test.go index ee8959260f..af15006983 100644 --- a/internal/manifests/collector/parser/receiver_fluent-forward_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_fluent-forward_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the FluentForward parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_generic.go b/internal/manifests/collector/parser/receiver/receiver_generic.go similarity index 99% rename from internal/manifests/collector/parser/receiver_generic.go rename to internal/manifests/collector/parser/receiver/receiver_generic.go index 8ca401c87f..42d5975ec7 100644 --- a/internal/manifests/collector/parser/receiver_generic.go +++ b/internal/manifests/collector/parser/receiver/receiver_generic.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_generic_test.go b/internal/manifests/collector/parser/receiver/receiver_generic_test.go similarity index 67% rename from internal/manifests/collector/parser/receiver_generic_test.go rename to internal/manifests/collector/parser/receiver/receiver_generic_test.go index 7c99633d17..4b6580d29e 100644 --- a/internal/manifests/collector/parser/receiver_generic_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_generic_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser_test +package receiver_test import ( "testing" @@ -21,7 +21,7 @@ import ( "github.com/stretchr/testify/assert" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/receiver" ) var logger = logf.Log.WithName("unit-tests") @@ -29,7 +29,7 @@ var logger = logf.Log.WithName("unit-tests") func TestParseEndpoint(t *testing.T) { // prepare // there's no parser registered to handle "myreceiver", so, it falls back to the generic parser - builder := parser.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ + builder := receiver.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ "endpoint": "0.0.0.0:1234", }) @@ -45,7 +45,7 @@ func TestParseEndpoint(t *testing.T) { func TestFailedToParseEndpoint(t *testing.T) { // prepare // there's no parser registered to handle "myreceiver", so, it falls back to the generic parser - builder := parser.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ + builder := receiver.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ "endpoint": "0.0.0.0", }) @@ -59,27 +59,27 @@ func TestFailedToParseEndpoint(t *testing.T) { func TestDownstreamParsers(t *testing.T) { for _, tt := range []struct { - builder func(logr.Logger, string, map[interface{}]interface{}) parser.ReceiverParser + builder func(logr.Logger, string, map[interface{}]interface{}) receiver.ReceiverParser desc string receiverName string parserName string defaultPort int }{ - {parser.NewZipkinReceiverParser, "zipkin", "zipkin", "__zipkin", 9411}, - {parser.NewOpenCensusReceiverParser, "opencensus", "opencensus", "__opencensus", 55678}, + {receiver.NewZipkinReceiverParser, "zipkin", "zipkin", "__zipkin", 9411}, + {receiver.NewOpenCensusReceiverParser, "opencensus", "opencensus", "__opencensus", 55678}, // contrib receivers - {parser.NewCarbonReceiverParser, "carbon", "carbon", "__carbon", 2003}, - {parser.NewCollectdReceiverParser, "collectd", "collectd", "__collectd", 8081}, - {parser.NewSAPMReceiverParser, "sapm", "sapm", "__sapm", 7276}, - {parser.NewSignalFxReceiverParser, "signalfx", "signalfx", "__signalfx", 9943}, - {parser.NewWavefrontReceiverParser, "wavefront", "wavefront", "__wavefront", 2003}, - {parser.NewZipkinScribeReceiverParser, "zipkin-scribe", "zipkin-scribe", "__zipkinscribe", 9410}, - {parser.NewFluentForwardReceiverParser, "fluentforward", "fluentforward", "__fluentforward", 8006}, - {parser.NewStatsdReceiverParser, "statsd", "statsd", "__statsd", 8125}, - {parser.NewInfluxdbReceiverParser, "influxdb", "influxdb", "__influxdb", 8086}, - {parser.NewSplunkHecReceiverParser, "splunk-hec", "splunk-hec", "__splunk_hec", 8088}, - {parser.NewAWSXrayReceiverParser, "awsxray", "awsxray", "__awsxray", 2000}, + {receiver.NewCarbonReceiverParser, "carbon", "carbon", "__carbon", 2003}, + {receiver.NewCollectdReceiverParser, "collectd", "collectd", "__collectd", 8081}, + {receiver.NewSAPMReceiverParser, "sapm", "sapm", "__sapm", 7276}, + {receiver.NewSignalFxReceiverParser, "signalfx", "signalfx", "__signalfx", 9943}, + {receiver.NewWavefrontReceiverParser, "wavefront", "wavefront", "__wavefront", 2003}, + {receiver.NewZipkinScribeReceiverParser, "zipkin-scribe", "zipkin-scribe", "__zipkinscribe", 9410}, + {receiver.NewFluentForwardReceiverParser, "fluentforward", "fluentforward", "__fluentforward", 8006}, + {receiver.NewStatsdReceiverParser, "statsd", "statsd", "__statsd", 8125}, + {receiver.NewInfluxdbReceiverParser, "influxdb", "influxdb", "__influxdb", 8086}, + {receiver.NewSplunkHecReceiverParser, "splunk-hec", "splunk-hec", "__splunk_hec", 8088}, + {receiver.NewAWSXrayReceiverParser, "awsxray", "awsxray", "__awsxray", 2000}, } { t.Run(tt.receiverName, func(t *testing.T) { t.Run("builds successfully", func(t *testing.T) { diff --git a/internal/manifests/collector/parser/receiver_influxdb.go b/internal/manifests/collector/parser/receiver/receiver_influxdb.go similarity index 98% rename from internal/manifests/collector/parser/receiver_influxdb.go rename to internal/manifests/collector/parser/receiver/receiver_influxdb.go index 55e393f2ff..d2e9cc3e58 100644 --- a/internal/manifests/collector/parser/receiver_influxdb.go +++ b/internal/manifests/collector/parser/receiver/receiver_influxdb.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_influxdb_test.go b/internal/manifests/collector/parser/receiver/receiver_influxdb_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_influxdb_test.go rename to internal/manifests/collector/parser/receiver/receiver_influxdb_test.go index 8597204488..94f596ee06 100644 --- a/internal/manifests/collector/parser/receiver_influxdb_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_influxdb_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Influxdb parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_jaeger.go b/internal/manifests/collector/parser/receiver/receiver_jaeger.go similarity index 99% rename from internal/manifests/collector/parser/receiver_jaeger.go rename to internal/manifests/collector/parser/receiver/receiver_jaeger.go index fc5a7e1534..26329a6ec9 100644 --- a/internal/manifests/collector/parser/receiver_jaeger.go +++ b/internal/manifests/collector/parser/receiver/receiver_jaeger.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "fmt" diff --git a/internal/manifests/collector/parser/receiver_jaeger_test.go b/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go similarity index 99% rename from internal/manifests/collector/parser/receiver_jaeger_test.go rename to internal/manifests/collector/parser/receiver/receiver_jaeger_test.go index 9bcdb4cb08..84f343a2cf 100644 --- a/internal/manifests/collector/parser/receiver_jaeger_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "testing" diff --git a/internal/manifests/collector/parser/receiver_oc.go b/internal/manifests/collector/parser/receiver/receiver_oc.go similarity index 98% rename from internal/manifests/collector/parser/receiver_oc.go rename to internal/manifests/collector/parser/receiver/receiver_oc.go index 5deb0fe5fc..c2515a0ad4 100644 --- a/internal/manifests/collector/parser/receiver_oc.go +++ b/internal/manifests/collector/parser/receiver/receiver_oc.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_oc_test.go b/internal/manifests/collector/parser/receiver/receiver_oc_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_oc_test.go rename to internal/manifests/collector/parser/receiver/receiver_oc_test.go index b14b4f9b10..74b6062427 100644 --- a/internal/manifests/collector/parser/receiver_oc_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_oc_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the OpenCensus parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_otlp.go b/internal/manifests/collector/parser/receiver/receiver_otlp.go similarity index 99% rename from internal/manifests/collector/parser/receiver_otlp.go rename to internal/manifests/collector/parser/receiver/receiver_otlp.go index e2e0e46a30..471ca10c8c 100644 --- a/internal/manifests/collector/parser/receiver_otlp.go +++ b/internal/manifests/collector/parser/receiver/receiver_otlp.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "fmt" diff --git a/internal/manifests/collector/parser/receiver_otlp_test.go b/internal/manifests/collector/parser/receiver/receiver_otlp_test.go similarity index 99% rename from internal/manifests/collector/parser/receiver_otlp_test.go rename to internal/manifests/collector/parser/receiver/receiver_otlp_test.go index 7d2ed16490..4f5e4bcb1d 100644 --- a/internal/manifests/collector/parser/receiver_otlp_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_otlp_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "testing" diff --git a/internal/manifests/collector/parser/receiver_sapm.go b/internal/manifests/collector/parser/receiver/receiver_sapm.go similarity index 98% rename from internal/manifests/collector/parser/receiver_sapm.go rename to internal/manifests/collector/parser/receiver/receiver_sapm.go index a9b8b574c5..e0a3756abb 100644 --- a/internal/manifests/collector/parser/receiver_sapm.go +++ b/internal/manifests/collector/parser/receiver/receiver_sapm.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_sapm_test.go b/internal/manifests/collector/parser/receiver/receiver_sapm_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_sapm_test.go rename to internal/manifests/collector/parser/receiver/receiver_sapm_test.go index 6a0c3de594..0940086266 100644 --- a/internal/manifests/collector/parser/receiver_sapm_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_sapm_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the SAPM parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_signalfx.go b/internal/manifests/collector/parser/receiver/receiver_signalfx.go similarity index 98% rename from internal/manifests/collector/parser/receiver_signalfx.go rename to internal/manifests/collector/parser/receiver/receiver_signalfx.go index f4140c4701..a3ecc6873a 100644 --- a/internal/manifests/collector/parser/receiver_signalfx.go +++ b/internal/manifests/collector/parser/receiver/receiver_signalfx.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_signalfx_test.go b/internal/manifests/collector/parser/receiver/receiver_signalfx_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_signalfx_test.go rename to internal/manifests/collector/parser/receiver/receiver_signalfx_test.go index cd196ee5d0..eaee10189f 100644 --- a/internal/manifests/collector/parser/receiver_signalfx_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_signalfx_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the SignalFx parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_skywalking.go b/internal/manifests/collector/parser/receiver/receiver_skywalking.go similarity index 99% rename from internal/manifests/collector/parser/receiver_skywalking.go rename to internal/manifests/collector/parser/receiver/receiver_skywalking.go index b888edc247..5bee2cb03e 100644 --- a/internal/manifests/collector/parser/receiver_skywalking.go +++ b/internal/manifests/collector/parser/receiver/receiver_skywalking.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "fmt" diff --git a/internal/manifests/collector/parser/receiver_skywalking_test.go b/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go similarity index 99% rename from internal/manifests/collector/parser/receiver_skywalking_test.go rename to internal/manifests/collector/parser/receiver/receiver_skywalking_test.go index 46d60cd846..e373e16d8e 100644 --- a/internal/manifests/collector/parser/receiver_skywalking_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "testing" diff --git a/internal/manifests/collector/parser/receiver_splunk-hec.go b/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go similarity index 98% rename from internal/manifests/collector/parser/receiver_splunk-hec.go rename to internal/manifests/collector/parser/receiver/receiver_splunk-hec.go index 09f75a123e..aa7b478bf0 100644 --- a/internal/manifests/collector/parser/receiver_splunk-hec.go +++ b/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_splunk-hec_test.go b/internal/manifests/collector/parser/receiver/receiver_splunk-hec_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_splunk-hec_test.go rename to internal/manifests/collector/parser/receiver/receiver_splunk-hec_test.go index 3ffc6c0ee0..e6f99f7852 100644 --- a/internal/manifests/collector/parser/receiver_splunk-hec_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_splunk-hec_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Splunk Hec parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_statsd.go b/internal/manifests/collector/parser/receiver/receiver_statsd.go similarity index 98% rename from internal/manifests/collector/parser/receiver_statsd.go rename to internal/manifests/collector/parser/receiver/receiver_statsd.go index 0ad153c9e7..725fb27270 100644 --- a/internal/manifests/collector/parser/receiver_statsd.go +++ b/internal/manifests/collector/parser/receiver/receiver_statsd.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_statsd_test.go b/internal/manifests/collector/parser/receiver/receiver_statsd_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_statsd_test.go rename to internal/manifests/collector/parser/receiver/receiver_statsd_test.go index 0ab1519352..338971ba44 100644 --- a/internal/manifests/collector/parser/receiver_statsd_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_statsd_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Statsd parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_test.go b/internal/manifests/collector/parser/receiver/receiver_test.go similarity index 99% rename from internal/manifests/collector/parser/receiver_test.go rename to internal/manifests/collector/parser/receiver/receiver_test.go index d7e39e0411..c972f7cd23 100644 --- a/internal/manifests/collector/parser/receiver_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "testing" diff --git a/internal/manifests/collector/parser/receiver_wavefront.go b/internal/manifests/collector/parser/receiver/receiver_wavefront.go similarity index 98% rename from internal/manifests/collector/parser/receiver_wavefront.go rename to internal/manifests/collector/parser/receiver/receiver_wavefront.go index 00c3f17e10..658d192c2a 100644 --- a/internal/manifests/collector/parser/receiver_wavefront.go +++ b/internal/manifests/collector/parser/receiver/receiver_wavefront.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_wavefront_test.go b/internal/manifests/collector/parser/receiver/receiver_wavefront_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_wavefront_test.go rename to internal/manifests/collector/parser/receiver/receiver_wavefront_test.go index 6bea4d91e7..0dd31b9470 100644 --- a/internal/manifests/collector/parser/receiver_wavefront_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_wavefront_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Wavefront parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_zipkin-scribe.go b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go similarity index 98% rename from internal/manifests/collector/parser/receiver_zipkin-scribe.go rename to internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go index 1c6fa3631c..c45968b1db 100644 --- a/internal/manifests/collector/parser/receiver_zipkin-scribe.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_zipkin-scribe_test.go b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_zipkin-scribe_test.go rename to internal/manifests/collector/parser/receiver/receiver_zipkin-scribe_test.go index dc057612b5..6475eb02fc 100644 --- a/internal/manifests/collector/parser/receiver_zipkin-scribe_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the ZipkinScribe parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/parser/receiver_zipkin.go b/internal/manifests/collector/parser/receiver/receiver_zipkin.go similarity index 98% rename from internal/manifests/collector/parser/receiver_zipkin.go rename to internal/manifests/collector/parser/receiver/receiver_zipkin.go index d96d951e09..412a8b6cf7 100644 --- a/internal/manifests/collector/parser/receiver_zipkin.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver import ( "github.com/go-logr/logr" diff --git a/internal/manifests/collector/parser/receiver_zipkin_test.go b/internal/manifests/collector/parser/receiver/receiver_zipkin_test.go similarity index 97% rename from internal/manifests/collector/parser/receiver_zipkin_test.go rename to internal/manifests/collector/parser/receiver/receiver_zipkin_test.go index 87bfecc082..8f1af43c5e 100644 --- a/internal/manifests/collector/parser/receiver_zipkin_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin_test.go @@ -12,6 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -package parser +package receiver // all tests for the Zipkin parser are currently part of the test TestDownstreamParsers diff --git a/internal/manifests/collector/service.go b/internal/manifests/collector/service.go index 84a6284a25..518a0d3b94 100644 --- a/internal/manifests/collector/service.go +++ b/internal/manifests/collector/service.go @@ -100,11 +100,7 @@ func Service(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelemet return nil } - ports, err := adapters.ConfigToReceiverPorts(logger, configFromString) - if err != nil { - logger.Error(err, "couldn't build the service for this instance") - return nil - } + ports := adapters.ConfigToPorts(logger, configFromString) if len(otelcol.Spec.Ports) > 0 { // we should add all the ports from the CR diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index 387836c4c1..4c5ed9b78d 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -16,6 +16,7 @@ package collector import ( "fmt" + "strings" "github.com/go-logr/logr" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" @@ -23,12 +24,21 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/internal/config" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) -// ServiceMonitor returns the service account for the given instance. +// ServiceMonitor returns the service monitor for the given instance. func ServiceMonitor(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) (*monitoringv1.ServiceMonitor, error) { - return &monitoringv1.ServiceMonitor{ + if !otelcol.Spec.Observability.Metrics.EnableMetrics { + logger.V(2).Info("Metrics disabled for this OTEL Collector", + "otelcol.name", otelcol.Name, + "otelcol.namespace", otelcol.Namespace, + ) + return nil, nil + } + + sm := monitoringv1.ServiceMonitor{ ObjectMeta: metav1.ObjectMeta{ Namespace: otelcol.Namespace, Name: naming.ServiceMonitor(otelcol.Name), @@ -39,17 +49,51 @@ func ServiceMonitor(cfg config.Config, logger logr.Logger, otelcol v1alpha1.Open }, }, Spec: monitoringv1.ServiceMonitorSpec{ - Endpoints: []monitoringv1.Endpoint{{ - Port: "monitoring", - }}, + Endpoints: []monitoringv1.Endpoint{}, NamespaceSelector: monitoringv1.NamespaceSelector{ MatchNames: []string{otelcol.Namespace}, }, Selector: metav1.LabelSelector{ MatchLabels: map[string]string{ "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otelcol.Namespace, otelcol.Name), }, }, }, - }, nil + } + + endpoints := []monitoringv1.Endpoint{ + { + Port: "monitoring", + }, + } + + sm.Spec.Endpoints = append(endpoints, endpointsFromConfig(logger, otelcol)...) + return &sm, nil +} + +func endpointsFromConfig(logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) []monitoringv1.Endpoint { + c, err := adapters.ConfigFromString(otelcol.Spec.Config) + if err != nil { + logger.V(2).Error(err, "Error while parsing the configuration") + return []monitoringv1.Endpoint{} + } + + exporterPorts, err := adapters.ConfigToExporterPorts(logger, c) + if err != nil { + logger.Error(err, "couldn't build service monitors from configuration") + return []monitoringv1.Endpoint{} + } + + endpoints := []monitoringv1.Endpoint{} + + for _, port := range exporterPorts { + if strings.Contains(port.Name, "prometheus") { + e := monitoringv1.Endpoint{ + Port: port.Name, + } + endpoints = append(endpoints, e) + } + } + return endpoints } diff --git a/internal/manifests/collector/servicemonitor_test.go b/internal/manifests/collector/servicemonitor_test.go index 85ed4d9392..9c1605c951 100644 --- a/internal/manifests/collector/servicemonitor_test.go +++ b/internal/manifests/collector/servicemonitor_test.go @@ -15,6 +15,7 @@ package collector import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -25,5 +26,25 @@ func TestDesiredServiceMonitors(t *testing.T) { actual, err := ServiceMonitor(params.Config, params.Log, params.Instance) assert.NoError(t, err) + assert.Nil(t, actual) + + params.Instance.Spec.Observability.Metrics.EnableMetrics = true + actual, err = ServiceMonitor(params.Config, params.Log, params.Instance) + assert.NoError(t, err) + assert.NotNil(t, actual) + assert.Equal(t, fmt.Sprintf("%s-collector", params.Instance.Name), actual.Name) + assert.Equal(t, params.Instance.Namespace, actual.Namespace) + assert.Equal(t, "monitoring", actual.Spec.Endpoints[0].Port) + + params, err = newParams("", "testdata/prometheus-exporter.yaml") + assert.NoError(t, err) + params.Instance.Spec.Observability.Metrics.EnableMetrics = true + actual, err = ServiceMonitor(params.Config, params.Log, params.Instance) + assert.NoError(t, err) assert.NotNil(t, actual) + assert.Equal(t, fmt.Sprintf("%s-collector", params.Instance.Name), actual.Name) + assert.Equal(t, params.Instance.Namespace, actual.Namespace) + assert.Equal(t, "monitoring", actual.Spec.Endpoints[0].Port) + assert.Equal(t, "prometheus-dev", actual.Spec.Endpoints[1].Port) + assert.Equal(t, "prometheus-prod", actual.Spec.Endpoints[2].Port) } diff --git a/internal/manifests/collector/testdata/prometheus-exporter.yaml b/internal/manifests/collector/testdata/prometheus-exporter.yaml new file mode 100644 index 0000000000..546d900f74 --- /dev/null +++ b/internal/manifests/collector/testdata/prometheus-exporter.yaml @@ -0,0 +1,19 @@ +receivers: + otlp: + protocols: + grpc: + http: + +exporters: + prometheus/prod: + endpoint: 0.0.0.0:8884 + + prometheus/dev: + endpoint: 0.0.0.0:8885 + +service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/dev, prometheus/prod] diff --git a/pkg/collector/reconcile/servicemonitor.go b/pkg/collector/reconcile/servicemonitor.go index ac72318267..2edee33a1b 100644 --- a/pkg/collector/reconcile/servicemonitor.go +++ b/pkg/collector/reconcile/servicemonitor.go @@ -33,14 +33,18 @@ import ( // ServiceMonitors reconciles the service monitor(s) required for the instance in the current context. func ServiceMonitors(ctx context.Context, params manifests.Params) error { - if !params.Instance.Spec.Observability.Metrics.EnableMetrics || !featuregate.PrometheusOperatorIsAvailable.IsEnabled() { + if !featuregate.PrometheusOperatorIsAvailable.IsEnabled() { return nil } var desired []*monitoringv1.ServiceMonitor - if sm, err := collector.ServiceMonitor(params.Config, params.Log, params.Instance); err != nil { + + sm, err := collector.ServiceMonitor(params.Config, params.Log, params.Instance) + if err != nil { return err - } else { + } + + if sm != nil { desired = append(desired, sm) } diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/00-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/00-install.yaml new file mode 100644 index 0000000000..0121963c69 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/00-install.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: create-sm-prometheus diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-assert.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-assert.yaml new file mode 100644 index 0000000000..0a3c07d13b --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-assert.yaml @@ -0,0 +1,65 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-dev + - port: prometheus-prod + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/instance: create-sm-prometheus.simplest +--- +apiVersion: v1 +kind: Service +metadata: + name: simplest-collector + namespace: create-sm-prometheus +spec: + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + targetPort: 4317 + - appProtocol: http + name: otlp-http + port: 4318 + protocol: TCP + targetPort: 4318 + - name: prometheus-dev + port: 8885 + protocol: TCP + targetPort: 8885 + - name: prometheus-prod + port: 8884 + protocol: TCP + targetPort: 8884 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector-monitoring + app.kubernetes.io/part-of: opentelemetry + name: simplest-collector-monitoring + namespace: create-sm-prometheus +spec: + ports: + - name: monitoring + port: 8888 + protocol: TCP + targetPort: 8888 diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-install.yaml new file mode 100644 index 0000000000..b03318eb4c --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/01-install.yaml @@ -0,0 +1,29 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: simplest + namespace: create-sm-prometheus +spec: + observability: + metrics: + enableMetrics: true + config: | + receivers: + otlp: + protocols: + grpc: + http: + + exporters: + prometheus/prod: + endpoint: 0.0.0.0:8884 + + prometheus/dev: + endpoint: 0.0.0.0:8885 + + service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/dev, prometheus/prod] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-assert.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-assert.yaml new file mode 100644 index 0000000000..b79840724e --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-assert.yaml @@ -0,0 +1,42 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-prod + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/instance: create-sm-prometheus.simplest +--- +apiVersion: v1 +kind: Service +metadata: + name: simplest-collector + namespace: create-sm-prometheus +spec: + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + targetPort: 4317 + - appProtocol: http + name: otlp-http + port: 4318 + protocol: TCP + targetPort: 4318 + - name: prometheus-prod + port: 8884 + protocol: TCP + targetPort: 8884 \ No newline at end of file diff --git a/tests/e2e-prometheuscr/gather-metrics-from-operands/00-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-install.yaml similarity index 64% rename from tests/e2e-prometheuscr/gather-metrics-from-operands/00-install.yaml rename to tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-install.yaml index dffa7a0500..e275da42eb 100644 --- a/tests/e2e-prometheuscr/gather-metrics-from-operands/00-install.yaml +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/02-install.yaml @@ -2,27 +2,25 @@ apiVersion: opentelemetry.io/v1alpha1 kind: OpenTelemetryCollector metadata: name: simplest + namespace: create-sm-prometheus spec: observability: metrics: enableMetrics: true config: | receivers: - jaeger: - protocols: - grpc: otlp: protocols: grpc: http: - processors: exporters: - logging: + prometheus/prod: + endpoint: 0.0.0.0:8884 service: pipelines: - traces: - receivers: [jaeger,otlp] + metrics: + receivers: [otlp] processors: [] - exporters: [logging] + exporters: [prometheus/prod] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-assert.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-assert.yaml new file mode 100644 index 0000000000..6590ac3935 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-assert.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: Service +metadata: + name: simplest-collector + namespace: create-sm-prometheus +spec: + ports: + - appProtocol: grpc + name: otlp-grpc + port: 4317 + protocol: TCP + targetPort: 4317 + - appProtocol: http + name: otlp-http + port: 4318 + protocol: TCP + targetPort: 4318 + - name: prometheus-prod + port: 9091 + protocol: TCP + targetPort: 9091 diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-install.yaml new file mode 100644 index 0000000000..fe782b4d33 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/03-install.yaml @@ -0,0 +1,26 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: simplest + namespace: create-sm-prometheus +spec: + observability: + metrics: + enableMetrics: true + config: | + receivers: + otlp: + protocols: + grpc: + http: + + exporters: + prometheus/prod: + endpoint: 0.0.0.0:9091 + + service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/prod] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-error.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-error.yaml new file mode 100644 index 0000000000..61ad50e38b --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-error.yaml @@ -0,0 +1,19 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-prod + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-install.yaml new file mode 100644 index 0000000000..5578a7da8e --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/04-install.yaml @@ -0,0 +1,26 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: simplest + namespace: create-sm-prometheus +spec: + observability: + metrics: + enableMetrics: false + config: | + receivers: + otlp: + protocols: + grpc: + http: + + exporters: + prometheus/prod: + endpoint: 0.0.0.0:9091 + + service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/prod] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-assert.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-assert.yaml new file mode 100644 index 0000000000..f56ec033cd --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-assert.yaml @@ -0,0 +1,21 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-dev + - port: prometheus-prod + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/instance: create-sm-prometheus.simplest diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-error.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-error.yaml new file mode 100644 index 0000000000..ecb59ba1fd --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-error.yaml @@ -0,0 +1,22 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-dev + - port: prometheus-prod + - port: prometheusremotewrite/prometheus + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/instance: create-sm-prometheus.simplest diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-install.yaml new file mode 100644 index 0000000000..8e300294e5 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/05-install.yaml @@ -0,0 +1,32 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: simplest + namespace: create-sm-prometheus +spec: + observability: + metrics: + enableMetrics: true + config: | + receivers: + otlp: + protocols: + grpc: + http: + + exporters: + prometheus/prod: + endpoint: 0.0.0.0:8884 + + prometheus/dev: + endpoint: 0.0.0.0:8885 + + prometheusremotewrite/prometheus: + endpoint: http://prometheus-server.monitoring/api/v1/write + + service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/dev, prometheus/prod, prometheusremotewrite/prometheus] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-assert.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-assert.yaml new file mode 100644 index 0000000000..8df94a5984 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-assert.yaml @@ -0,0 +1,20 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app.kubernetes.io/instance: create-sm-prometheus.simplest + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: simplest-collector + name: simplest-collector + namespace: create-sm-prometheus +spec: + endpoints: + - port: monitoring + - port: prometheus-dev + namespaceSelector: + matchNames: + - create-sm-prometheus + selector: + matchLabels: + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/instance: create-sm-prometheus.simplest diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-install.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-install.yaml new file mode 100644 index 0000000000..028458da18 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/06-install.yaml @@ -0,0 +1,29 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: simplest + namespace: create-sm-prometheus +spec: + observability: + metrics: + enableMetrics: true + config: | + receivers: + otlp: + protocols: + grpc: + http: + + exporters: + prometheus/prod: + endpoint: 0.0.0.0:8884 + + prometheus/dev: + endpoint: 0.0.0.0:8885 + + service: + pipelines: + metrics: + receivers: [otlp] + processors: [] + exporters: [prometheus/dev] diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-delete.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-delete.yaml new file mode 100644 index 0000000000..76798588bb --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-delete.yaml @@ -0,0 +1,8 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: + - apiVersion: opentelemetry.io/v1alpha1 + kind: OpenTelemetryCollector + metadata: + name: simplest + namespace: create-sm-prometheus \ No newline at end of file diff --git a/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-error.yaml b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-error.yaml new file mode 100644 index 0000000000..263dbb3c64 --- /dev/null +++ b/tests/e2e-prometheuscr/create-sm-prometheus-exporters/07-error.yaml @@ -0,0 +1,5 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: simplest-collector + namespace: create-sm-prometheus diff --git a/tests/e2e-prometheuscr/gather-metrics-from-operands/00-assert.yaml b/tests/e2e-prometheuscr/gather-metrics-from-operands/00-assert.yaml deleted file mode 100644 index 586d61e942..0000000000 --- a/tests/e2e-prometheuscr/gather-metrics-from-operands/00-assert.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: simplest-collector -spec: - endpoints: - - port: monitoring - selector: - matchLabels: - app.kubernetes.io/managed-by: opentelemetry-operator