From c94db2f353793ffb2d4e29d731089dd8df529d0a Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 12 Feb 2024 15:10:53 -0500 Subject: [PATCH 1/6] mostly working signatures --- internal/manifests/collector/podmonitor.go | 2 +- internal/manifests/collector/service_test.go | 8 +++++--- internal/manifests/collector/servicemonitor.go | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/manifests/collector/podmonitor.go b/internal/manifests/collector/podmonitor.go index f51c7c95b1..f097e8ea1e 100644 --- a/internal/manifests/collector/podmonitor.go +++ b/internal/manifests/collector/podmonitor.go @@ -81,7 +81,7 @@ func metricsEndpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemet // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 cfgStr, err := otelcol.Spec.Config.Yaml() if err != nil { - logger.V(2).Error(err, "Error while marshaling to YAML") + logger.V(2).Error(err, "Error while marshalling to YAML") return []monitoringv1.PodMetricsEndpoint{} } config, err := adapters.ConfigFromString(cfgStr) diff --git a/internal/manifests/collector/service_test.go b/internal/manifests/collector/service_test.go index ceb35fed81..1f72552b4d 100644 --- a/internal/manifests/collector/service_test.go +++ b/internal/manifests/collector/service_test.go @@ -203,9 +203,11 @@ func TestMonitoringService(t *testing.T) { Service: v1alpha2.Service{ Telemetry: &v1alpha2.AnyConfig{ Object: map[string]interface{}{ - "metrics": map[string]interface{}{ - "level": "detailed", - "address": "0.0.0.0:9090", + "service": map[string]interface{}{ + "metrics": map[string]interface{}{ + "level": "detailed", + "address": "0.0.0.0:9090", + }, }, }, }, diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index 02496e7898..aad920ceaa 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -77,7 +77,7 @@ func endpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemetryColle // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 cfgStr, err := otelcol.Spec.Config.Yaml() if err != nil { - logger.V(2).Error(err, "Error while marshaling to YAML") + logger.V(2).Error(err, "Error while marshalling to YAML") return []monitoringv1.Endpoint{} } c, err := adapters.ConfigFromString(cfgStr) From f50ef837831bf3ffad8b3f07b2ab16469534c395 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 12 Feb 2024 16:44:54 -0500 Subject: [PATCH 2/6] Clean up types to only marshal once --- internal/manifests/collector/service_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/internal/manifests/collector/service_test.go b/internal/manifests/collector/service_test.go index 1f72552b4d..ceb35fed81 100644 --- a/internal/manifests/collector/service_test.go +++ b/internal/manifests/collector/service_test.go @@ -203,11 +203,9 @@ func TestMonitoringService(t *testing.T) { Service: v1alpha2.Service{ Telemetry: &v1alpha2.AnyConfig{ Object: map[string]interface{}{ - "service": map[string]interface{}{ - "metrics": map[string]interface{}{ - "level": "detailed", - "address": "0.0.0.0:9090", - }, + "metrics": map[string]interface{}{ + "level": "detailed", + "address": "0.0.0.0:9090", }, }, }, From 07c0ee0999e2f5c1439af441e6c112d18ee11d02 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 12 Feb 2024 16:52:34 -0500 Subject: [PATCH 3/6] linting --- internal/manifests/collector/podmonitor.go | 2 +- internal/manifests/collector/servicemonitor.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/manifests/collector/podmonitor.go b/internal/manifests/collector/podmonitor.go index f097e8ea1e..f51c7c95b1 100644 --- a/internal/manifests/collector/podmonitor.go +++ b/internal/manifests/collector/podmonitor.go @@ -81,7 +81,7 @@ func metricsEndpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemet // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 cfgStr, err := otelcol.Spec.Config.Yaml() if err != nil { - logger.V(2).Error(err, "Error while marshalling to YAML") + logger.V(2).Error(err, "Error while marshaling to YAML") return []monitoringv1.PodMetricsEndpoint{} } config, err := adapters.ConfigFromString(cfgStr) diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index aad920ceaa..02496e7898 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -77,7 +77,7 @@ func endpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemetryColle // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 cfgStr, err := otelcol.Spec.Config.Yaml() if err != nil { - logger.V(2).Error(err, "Error while marshalling to YAML") + logger.V(2).Error(err, "Error while marshaling to YAML") return []monitoringv1.Endpoint{} } c, err := adapters.ConfigFromString(cfgStr) From a1bf2d3d8801539d1c8c9aae872575c45ff14618 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Tue, 13 Feb 2024 10:46:55 -0500 Subject: [PATCH 4/6] pause --- .../manifests/collector/adapters/config_to_ports.go | 5 +++-- .../manifests/collector/adapters/config_validate.go | 8 ++++++-- internal/manifests/collector/container.go | 11 +++-------- internal/manifests/collector/service.go | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index f0945389f8..103c51c7ce 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -25,6 +25,7 @@ import ( "github.com/mitchellh/mapstructure" corev1 "k8s.io/api/core/v1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "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" @@ -43,7 +44,7 @@ func (c ComponentType) String() string { } // ConfigToComponentPorts converts the incoming configuration object into a set of service ports required by the exporters. -func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { +func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config v1alpha2.Config) ([]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: @@ -122,7 +123,7 @@ func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config map[ return ports, nil } -func ConfigToPorts(logger logr.Logger, config map[interface{}]interface{}) ([]corev1.ServicePort, error) { +func ConfigToPorts(logger logr.Logger, config v1alpha2.Config) ([]corev1.ServicePort, error) { ports, err := ConfigToComponentPorts(logger, ComponentTypeReceiver, config) if err != nil { logger.Error(err, "there was a problem while getting the ports from the receivers") diff --git a/internal/manifests/collector/adapters/config_validate.go b/internal/manifests/collector/adapters/config_validate.go index ff0c86c9b8..87082b30e7 100644 --- a/internal/manifests/collector/adapters/config_validate.go +++ b/internal/manifests/collector/adapters/config_validate.go @@ -14,11 +14,15 @@ package adapters -import "fmt" +import ( + "fmt" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" +) // Following Otel Doc: Configuring a receiver does not enable it. The receivers are enabled via pipelines within the service section. // getEnabledComponents returns all enabled components as a true flag set. If it can't find any receiver, it will return a nil interface. -func getEnabledComponents(config map[interface{}]interface{}, componentType ComponentType) map[interface{}]bool { +func getEnabledComponents(config v1alpha2.Config, componentType ComponentType) map[interface{}]bool { componentTypePlural := fmt.Sprintf("%ss", componentType.String()) cfgComponents, ok := config[componentTypePlural] if !ok { diff --git a/internal/manifests/collector/container.go b/internal/manifests/collector/container.go index 00f6e2ee2b..2223eaaa29 100644 --- a/internal/manifests/collector/container.go +++ b/internal/manifests/collector/container.go @@ -49,7 +49,7 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha2.OpenTelem } // build container ports from service ports - ports, err := getConfigContainerPorts(logger, configYaml) + ports, err := getConfigContainerPorts(logger, otelcol) if err != nil { logger.Error(err, "container ports config") } @@ -168,14 +168,9 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha2.OpenTelem } } -func getConfigContainerPorts(logger logr.Logger, cfg string) (map[string]corev1.ContainerPort, error) { +func getConfigContainerPorts(logger logr.Logger, collector v1alpha2.OpenTelemetryCollector) (map[string]corev1.ContainerPort, error) { ports := map[string]corev1.ContainerPort{} - c, err := adapters.ConfigFromString(cfg) - if err != nil { - logger.Error(err, "couldn't extract the configuration") - return ports, err - } - ps, err := adapters.ConfigToPorts(logger, c) + ps, err := adapters.ConfigToPorts(logger, collector.Spec.Config) if err != nil { return ports, err } diff --git a/internal/manifests/collector/service.go b/internal/manifests/collector/service.go index 48b4d987d8..729bde46f5 100644 --- a/internal/manifests/collector/service.go +++ b/internal/manifests/collector/service.go @@ -111,7 +111,7 @@ func Service(params manifests.Params) (*corev1.Service, error) { return nil, err } - ports, err := adapters.ConfigToPorts(params.Log, configFromString) + ports, err := adapters.ConfigToPorts(params.Log, params.OtelCol.Spec.Config) if err != nil { return nil, err } From 7e80a33cb792cad4e80442670380f87bb781e7f0 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Wed, 14 Feb 2024 16:52:01 -0500 Subject: [PATCH 5/6] continue my warpath --- apis/v1alpha1/collector_webhook.go | 46 ++++--- apis/v1alpha2/config.go | 41 ++++-- apis/v1alpha2/config_test.go | 11 +- apis/v1alpha2/zz_generated.deepcopy.go | 57 ++++++++- bundle.Dockerfile | 1 - bundle/metadata/annotations.yaml | 3 - .../collector/adapters/config_to_ports.go | 115 ++++------------- .../adapters/config_to_ports_test.go | 120 +++++++----------- .../collector/adapters/config_to_probe.go | 65 +++------- .../adapters/config_to_probe_test.go | 75 +++++------ .../collector/adapters/config_to_rbac.go | 27 ++-- .../collector/adapters/config_to_rbac_test.go | 11 +- .../collector/adapters/config_validate.go | 108 +++++----------- .../adapters/config_validate_test.go | 15 ++- .../manifests/collector/annotations_test.go | 10 +- internal/manifests/collector/container.go | 28 ++-- internal/manifests/collector/ingress.go | 13 +- .../collector/parser/exporter/exporter.go | 6 +- .../parser/exporter/exporter_prometheus.go | 4 +- internal/manifests/collector/parser/parser.go | 5 +- .../collector/parser/processor/processor.go | 4 +- .../processor/processor_k8sattributes.go | 6 +- .../processor/processor_resourcedetection.go | 4 +- .../collector/parser/receiver/receiver.go | 12 +- .../parser/receiver/receiver_aws-xray.go | 2 +- .../parser/receiver/receiver_carbon.go | 2 +- .../parser/receiver/receiver_collectd.go | 2 +- .../receiver/receiver_fluent-forward.go | 2 +- .../parser/receiver/receiver_generic.go | 4 +- .../parser/receiver/receiver_generic_test.go | 12 +- .../parser/receiver/receiver_influxdb.go | 2 +- .../parser/receiver/receiver_jaeger.go | 10 +- .../parser/receiver/receiver_jaeger_test.go | 26 ++-- .../parser/receiver/receiver_loki.go | 10 +- .../parser/receiver/receiver_loki_test.go | 18 +-- .../collector/parser/receiver/receiver_oc.go | 2 +- .../parser/receiver/receiver_otlp.go | 10 +- .../parser/receiver/receiver_otlp_test.go | 18 +-- .../parser/receiver/receiver_sapm.go | 2 +- .../parser/receiver/receiver_signalfx.go | 2 +- .../parser/receiver/receiver_skywalking.go | 10 +- .../receiver/receiver_skywalking_test.go | 18 +-- .../parser/receiver/receiver_splunk-hec.go | 2 +- .../parser/receiver/receiver_statsd.go | 2 +- .../parser/receiver/receiver_test.go | 12 +- .../parser/receiver/receiver_wavefront.go | 2 +- .../parser/receiver/receiver_zipkin-scribe.go | 2 +- .../parser/receiver/receiver_zipkin.go | 2 +- internal/manifests/collector/podmonitor.go | 14 +- internal/manifests/collector/rbac.go | 23 +--- internal/manifests/collector/service.go | 26 +--- .../manifests/collector/servicemonitor.go | 15 +-- 52 files changed, 410 insertions(+), 629 deletions(-) diff --git a/apis/v1alpha1/collector_webhook.go b/apis/v1alpha1/collector_webhook.go index 97ee9cc3a4..f5ea9d435f 100644 --- a/apis/v1alpha1/collector_webhook.go +++ b/apis/v1alpha1/collector_webhook.go @@ -30,9 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" "github.com/open-telemetry/opentelemetry-operator/internal/config" - ta "github.com/open-telemetry/opentelemetry-operator/internal/manifests/targetallocator/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/rbac" - "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate" ) var ( @@ -359,28 +357,28 @@ func (c CollectorWebhook) validateTargetAllocatorConfig(ctx context.Context, r * if r.Spec.TargetAllocator.AllocationStrategy == OpenTelemetryTargetAllocatorAllocationStrategyPerNode && r.Spec.Mode != ModeDaemonSet { return nil, fmt.Errorf("target allocation strategy %s is only supported in OpenTelemetry Collector mode %s", OpenTelemetryTargetAllocatorAllocationStrategyPerNode, ModeDaemonSet) } - - // validate Prometheus config for target allocation - promCfg, err := ta.ConfigToPromConfig(r.Spec.Config) - if err != nil { - return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - } - err = ta.ValidatePromConfig(promCfg, r.Spec.TargetAllocator.Enabled, featuregate.EnableTargetAllocatorRewrite.IsEnabled()) - if err != nil { - return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - } - err = ta.ValidateTargetAllocatorConfig(r.Spec.TargetAllocator.PrometheusCR.Enabled, promCfg) - if err != nil { - return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - } - // if the prometheusCR is enabled, it needs a suite of permissions to function - if r.Spec.TargetAllocator.PrometheusCR.Enabled { - if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.GetNamespace(), r.Spec.TargetAllocator.ServiceAccount, targetAllocatorCRPolicyRules...); err != nil { - return nil, fmt.Errorf("unable to check rbac rules %w", err) - } else if allowed, deniedReviews := rbac.AllSubjectAccessReviewsAllowed(subjectAccessReviews); !allowed { - return warningsGroupedByResource(deniedReviews), nil - } - } + // TODO: Fix cycle + //// validate Prometheus config for target allocation + //promCfg, err := ta.ConfigToPromConfig(r.Spec.Config) + //if err != nil { + // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + //} + //err = ta.ValidatePromConfig(promCfg, r.Spec.TargetAllocator.Enabled, featuregate.EnableTargetAllocatorRewrite.IsEnabled()) + //if err != nil { + // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + //} + //err = ta.ValidateTargetAllocatorConfig(r.Spec.TargetAllocator.PrometheusCR.Enabled, promCfg) + //if err != nil { + // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + //} + //// if the prometheusCR is enabled, it needs a suite of permissions to function + //if r.Spec.TargetAllocator.PrometheusCR.Enabled { + // if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.GetNamespace(), r.Spec.TargetAllocator.ServiceAccount, targetAllocatorCRPolicyRules...); err != nil { + // return nil, fmt.Errorf("unable to check rbac rules %w", err) + // } else if allowed, deniedReviews := rbac.AllSubjectAccessReviewsAllowed(subjectAccessReviews); !allowed { + // return warningsGroupedByResource(deniedReviews), nil + // } + //} return nil, nil } diff --git a/apis/v1alpha2/config.go b/apis/v1alpha2/config.go index b437ac3f7f..28fc7978af 100644 --- a/apis/v1alpha2/config.go +++ b/apis/v1alpha2/config.go @@ -30,10 +30,10 @@ type AnyConfig struct { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AnyConfig) DeepCopyInto(out *AnyConfig) { - *out = *in - if in.Object != nil { - in, out := &in.Object, &out.Object +func (c *AnyConfig) DeepCopyInto(out *AnyConfig) { + *out = *c + if c.Object != nil { + in, out := &c.Object, &out.Object *out = make(map[string]interface{}, len(*in)) for key, val := range *in { (*out)[key] = val @@ -42,12 +42,12 @@ func (in *AnyConfig) DeepCopyInto(out *AnyConfig) { } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AnyConfig. -func (in *AnyConfig) DeepCopy() *AnyConfig { - if in == nil { +func (c *AnyConfig) DeepCopy() *AnyConfig { + if c == nil { return nil } out := new(AnyConfig) - in.DeepCopyInto(out) + c.DeepCopyInto(out) return out } @@ -98,10 +98,33 @@ func (c Config) Yaml() (string, error) { return buf.String(), nil } +// MetricsConfig comes from the collector +type MetricsConfig struct { + // Level is the level of telemetry metrics, the possible values are: + // - "none" indicates that no telemetry data should be collected; + // - "basic" is the recommended and covers the basics of the service telemetry. + // - "normal" adds some other indicators on top of basic. + // - "detailed" adds dimensions and views to the previous levels. + Level string `json:"level,omitempty" yaml:"level,omitempty"` + + // Address is the [address]:port that metrics exposition should be bound to. + Address string `json:"address,omitempty" yaml:"address,omitempty"` +} + +type Telemetry struct { + Metrics MetricsConfig `json:"metrics,omitempty" yaml:"metrics,omitempty"` + + // Resource specifies user-defined attributes to include with all emitted telemetry. + // Note that some attributes are added automatically (e.g. service.version) even + // if they are not specified here. In order to suppress such attributes the + // attribute must be specified in this map with null YAML value (nil string pointer). + Resource map[string]*string `json:"resource,omitempty" yaml:"resource,omitempty"` +} + type Service struct { - Extensions *[]string `json:"extensions,omitempty" yaml:"extensions,omitempty"` + Extensions []string `json:"extensions,omitempty" yaml:"extensions,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Telemetry *AnyConfig `json:"telemetry,omitempty" yaml:"telemetry,omitempty"` + Telemetry *Telemetry `json:"telemetry,omitempty" yaml:"telemetry,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields Pipelines AnyConfig `json:"pipelines" yaml:"pipelines"` } diff --git a/apis/v1alpha2/config_test.go b/apis/v1alpha2/config_test.go index a8ebd29b4c..6034838781 100644 --- a/apis/v1alpha2/config_test.go +++ b/apis/v1alpha2/config_test.go @@ -139,10 +139,10 @@ func TestConfigYaml(t *testing.T) { }, }, Service: Service{ - Extensions: &[]string{"addon"}, - Telemetry: &AnyConfig{ - Object: map[string]interface{}{ - "insights": "yeah!", + Extensions: []string{"addon"}, + Telemetry: &Telemetry{ + Metrics: MetricsConfig{ + Address: "0.0.0.0:9000", }, }, Pipelines: AnyConfig{ @@ -171,7 +171,8 @@ service: extensions: - addon telemetry: - insights: yeah! + metrics: + address: 0.0.0.0:9000 pipelines: exporters: - otlp/exporter diff --git a/apis/v1alpha2/zz_generated.deepcopy.go b/apis/v1alpha2/zz_generated.deepcopy.go index 3ceafb521c..533a6a5fa2 100644 --- a/apis/v1alpha2/zz_generated.deepcopy.go +++ b/apis/v1alpha2/zz_generated.deepcopy.go @@ -406,6 +406,21 @@ func (in *MetricSpec) DeepCopy() *MetricSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MetricsConfig) DeepCopyInto(out *MetricsConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsConfig. +func (in *MetricsConfig) DeepCopy() *MetricsConfig { + if in == nil { + return nil + } + out := new(MetricsConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Nginx) DeepCopyInto(out *Nginx) { *out = *in @@ -883,16 +898,13 @@ func (in *Service) DeepCopyInto(out *Service) { *out = *in if in.Extensions != nil { in, out := &in.Extensions, &out.Extensions - *out = new([]string) - if **in != nil { - in, out := *in, *out - *out = make([]string, len(*in)) - copy(*out, *in) - } + *out = make([]string, len(*in)) + copy(*out, *in) } if in.Telemetry != nil { in, out := &in.Telemetry, &out.Telemetry - *out = (*in).DeepCopy() + *out = new(Telemetry) + (*in).DeepCopyInto(*out) } in.Pipelines.DeepCopyInto(&out.Pipelines) } @@ -1103,3 +1115,34 @@ func (in *TargetAllocatorStatus) DeepCopy() *TargetAllocatorStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Telemetry) DeepCopyInto(out *Telemetry) { + *out = *in + out.Metrics = in.Metrics + if in.Resource != nil { + in, out := &in.Resource, &out.Resource + *out = make(map[string]*string, len(*in)) + for key, val := range *in { + var outVal *string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(string) + **out = **in + } + (*out)[key] = outVal + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Telemetry. +func (in *Telemetry) DeepCopy() *Telemetry { + if in == nil { + return nil + } + out := new(Telemetry) + in.DeepCopyInto(out) + return out +} diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 367ef8fe76..af479f2fa4 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -18,4 +18,3 @@ LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ COPY bundle/manifests /manifests/ COPY bundle/metadata /metadata/ COPY bundle/tests/scorecard /tests/scorecard/ -LABEL com.redhat.openshift.versions="v4.11-v4.15" diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 1dc119a11f..b0f3b46044 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -12,6 +12,3 @@ annotations: # Annotations for testing. operators.operatorframework.io.test.mediatype.v1: scorecard+v1 operators.operatorframework.io.test.config.v1: tests/scorecard/ - - # OpenShift specific annotations - com.redhat.openshift.versions: "v4.11-v4.15" diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index 103c51c7ce..f4e452f26c 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -15,14 +15,12 @@ package adapters import ( - "fmt" "net" "sort" "strconv" "strings" "github.com/go-logr/logr" - "github.com/mitchellh/mapstructure" corev1 "k8s.io/api/core/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" @@ -43,94 +41,50 @@ func (c ComponentType) String() string { return [...]string{"receiver", "exporter", "processor"}[c] } -// ConfigToComponentPorts converts the incoming configuration object into a set of service ports required by the exporters. -func ConfigToComponentPorts(logger logr.Logger, cType ComponentType, config v1alpha2.Config) ([]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 - // components: - // componentexample: - // endpoint: 0.0.0.0:12345 - // componentexample/settings: - // endpoint: 0.0.0.0:12346 - // in this case, we have 2 ports, named: "componentexample" and "componentexample-settings" - componentsProperty, ok := config[fmt.Sprintf("%ss", cType.String())] - if !ok { - return nil, fmt.Errorf("no %ss available as part of the configuration", cType) - } - - components, ok := componentsProperty.(map[interface{}]interface{}) - if !ok { - return nil, fmt.Errorf("%ss doesn't contain valid components", cType.String()) - } - - compEnabled := getEnabledComponents(config, cType) +func PortsForExporters(l logr.Logger, c v1alpha2.Config) ([]corev1.ServicePort, error) { + compEnabled := getEnabledComponents(c.Service, ComponentTypeExporter) + return componentPorts(l, c.Exporters, exporterParser.BuilderFor, compEnabled) +} - if compEnabled == nil { - return nil, fmt.Errorf("no enabled %ss available as part of the configuration", cType) - } +func PortsForReceivers(l logr.Logger, c v1alpha2.Config) ([]corev1.ServicePort, error) { + compEnabled := getEnabledComponents(c.Service, ComponentTypeReceiver) + return componentPorts(l, c.Receivers, receiverParser.BuilderFor, compEnabled) +} - ports := []corev1.ServicePort{} - for key, val := range components { - // This check will pass only the enabled components, - // then only the related ports will be opened. - if !compEnabled[key] { +func componentPorts(l logr.Logger, c v1alpha2.AnyConfig, p parser.BuilderFor, enabledComponents map[string]bool) ([]corev1.ServicePort, error) { + var ports []corev1.ServicePort + for cmptName, val := range c.Object { + if !enabledComponents[cmptName] { continue } - exporter, ok := val.(map[interface{}]interface{}) + component, ok := val.(map[string]interface{}) if !ok { - logger.V(2).Info("component doesn't seem to be a map of properties", cType.String(), key) - exporter = map[interface{}]interface{}{} - } - - cmptName := key.(string) - var cmptParser parser.ComponentPortParser - var err error - switch cType { - case ComponentTypeExporter: - cmptParser, err = exporterParser.For(logger, cmptName, exporter) - case ComponentTypeReceiver: - cmptParser, err = receiverParser.For(logger, cmptName, exporter) - case ComponentTypeProcessor: - logger.V(4).Info("processors don't provide a way to enable associated ports", "name", key) - } - - if err != nil { - logger.V(2).Info("no parser found for '%s'", cmptName) - continue + component = map[string]interface{}{} } - - exprtPorts, err := cmptParser.Ports() + builder := p(cmptName) + componentParser := builder(l, cmptName, component) + componentPorts, err := componentParser.Ports() if err != nil { - logger.Error(err, "parser for '%s' has returned an error: %w", cmptName, err) + l.Error(err, "parser for '%s' has returned an error: %w", cmptName, err) continue } - - if len(exprtPorts) > 0 { - ports = append(ports, exprtPorts...) - } + ports = append(ports, componentPorts...) } sort.Slice(ports, func(i, j int) bool { return ports[i].Name < ports[j].Name }) - return ports, nil } func ConfigToPorts(logger logr.Logger, config v1alpha2.Config) ([]corev1.ServicePort, error) { - ports, err := ConfigToComponentPorts(logger, ComponentTypeReceiver, config) + ports, err := PortsForReceivers(logger, config) if err != nil { logger.Error(err, "there was a problem while getting the ports from the receivers") return nil, err } - exporterPorts, err := ConfigToComponentPorts(logger, ComponentTypeExporter, config) + exporterPorts, err := PortsForExporters(logger, config) if err != nil { logger.Error(err, "there was a problem while getting the ports from the exporters") return nil, err @@ -146,29 +100,12 @@ func ConfigToPorts(logger logr.Logger, config v1alpha2.Config) ([]corev1.Service } // 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 - // the metrics address. - type metricsCfg struct { - Address string - } - type telemetryCfg struct { - Metrics metricsCfg - } - type serviceCfg struct { - Telemetry telemetryCfg - } - type cfg struct { - Service serviceCfg - } - - var cOut cfg - err := mapstructure.Decode(config, &cOut) - if err != nil { - return 0, err +func ConfigToMetricsPort(config v1alpha2.Service) (int32, error) { + if config.Telemetry == nil { + // telemetry isn't set, use the default + return 8888, nil } - - _, port, netErr := net.SplitHostPort(cOut.Service.Telemetry.Metrics.Address) + _, port, netErr := net.SplitHostPort(config.Telemetry.Metrics.Address) if netErr != nil && strings.Contains(netErr.Error(), "missing port in address") { return 8888, nil } else if netErr != nil { diff --git a/internal/manifests/collector/adapters/config_to_ports_test.go b/internal/manifests/collector/adapters/config_to_ports_test.go index 7c872606f6..b2412b7088 100644 --- a/internal/manifests/collector/adapters/config_to_ports_test.go +++ b/internal/manifests/collector/adapters/config_to_ports_test.go @@ -20,11 +20,12 @@ import ( "github.com/go-logr/logr" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" logf "sigs.k8s.io/controller-runtime/pkg/log" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "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" @@ -79,12 +80,13 @@ service: func TestExtractPortsFromConfig(t *testing.T) { // prepare - config, err := adapters.ConfigFromString(portConfigStr) - require.NoError(t, err) - require.NotEmpty(t, config) + cfg := v1alpha2.Config{} + if err := yaml.Unmarshal([]byte(portConfigStr), &cfg); err != nil { + t.Fatal(err) + } // test - ports, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeReceiver, config) + ports, err := adapters.PortsForReceivers(logger, cfg) assert.NoError(t, err) assert.Len(t, ports, 10) @@ -110,38 +112,6 @@ func TestExtractPortsFromConfig(t *testing.T) { assert.ElementsMatch(t, expectedPorts, ports) } -func TestNoPortsParsed(t *testing.T) { - for _, tt := range []struct { - expected error - desc string - configStr string - }{ - { - expected: errors.New("no receivers available as part of the configuration"), - desc: "empty", - configStr: "", - }, - { - expected: errors.New("receivers doesn't contain valid components"), - desc: "not a map", - configStr: "receivers: some-string", - }, - } { - t.Run(tt.desc, func(t *testing.T) { - // prepare - config, err := adapters.ConfigFromString(tt.configStr) - require.NoError(t, err) - - // test - ports, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeReceiver, config) - - // verify - assert.Nil(t, ports) - assert.Equal(t, tt.expected, err) - }) - } -} - func TestInvalidReceivers(t *testing.T) { for _, tt := range []struct { desc string @@ -158,11 +128,13 @@ func TestInvalidReceivers(t *testing.T) { } { t.Run(tt.desc, func(t *testing.T) { // prepare - config, err := adapters.ConfigFromString(tt.configStr) - require.NoError(t, err) + cfg := v1alpha2.Config{} + if err := yaml.Unmarshal([]byte(tt.configStr), &cfg); err != nil { + t.Fatal(err) + } // test - ports, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeReceiver, config) + ports, err := adapters.PortsForReceivers(logger, cfg) // verify assert.NoError(t, err) @@ -180,25 +152,29 @@ func TestParserFailed(t *testing.T) { return nil, errors.New("mocked error") }, } - receiver.Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { + receiver.Register("mock", func(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return mockParser }) - config := map[interface{}]interface{}{ - "receivers": map[interface{}]interface{}{ - "mock": map[string]interface{}{}, + cfg := v1alpha2.Config{ + Receivers: v1alpha2.AnyConfig{ + Object: map[string]interface{}{ + "mock": map[string]interface{}{}, + }, }, - "service": map[interface{}]interface{}{ - "pipelines": map[interface{}]interface{}{ - "metrics": map[interface{}]interface{}{ - "receivers": []interface{}{"mock"}, + Service: v1alpha2.Service{ + Pipelines: v1alpha2.AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "receivers": []interface{}{"mock"}, + }, }, }, }, } // test - ports, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeReceiver, config) + ports, err := adapters.PortsForReceivers(logger, cfg) // verify assert.Len(t, ports, 0) @@ -208,67 +184,57 @@ func TestParserFailed(t *testing.T) { func TestConfigToMetricsPort(t *testing.T) { t.Run("custom port specified", func(t *testing.T) { - config := map[interface{}]interface{}{ - "service": map[interface{}]interface{}{ - "telemetry": map[interface{}]interface{}{ - "metrics": map[interface{}]interface{}{ - "address": "0.0.0.0:9090", - }, + config := v1alpha2.Service{ + Telemetry: &v1alpha2.Telemetry{ + Metrics: v1alpha2.MetricsConfig{ + Address: "0.0.0.0:9090", }, }, } - port, err := adapters.ConfigToMetricsPort(logger, config) + port, err := adapters.ConfigToMetricsPort(config) assert.NoError(t, err) assert.Equal(t, int32(9090), port) }) for _, tt := range []struct { desc string - config map[interface{}]interface{} + config v1alpha2.Service }{ { "bad address", - map[interface{}]interface{}{ - "service": map[interface{}]interface{}{ - "telemetry": map[interface{}]interface{}{ - "metrics": map[interface{}]interface{}{ - "address": "0.0.0.0", - }, + v1alpha2.Service{ + Telemetry: &v1alpha2.Telemetry{ + Metrics: v1alpha2.MetricsConfig{ + Address: "0.0.0.0", }, }, }, }, { "missing address", - map[interface{}]interface{}{ - "service": map[interface{}]interface{}{ - "telemetry": map[interface{}]interface{}{ - "metrics": map[interface{}]interface{}{ - "level": "detailed", - }, + v1alpha2.Service{ + Telemetry: &v1alpha2.Telemetry{ + Metrics: v1alpha2.MetricsConfig{ + Level: "detailed", }, }, }, }, { "missing metrics", - map[interface{}]interface{}{ - "service": map[interface{}]interface{}{ - "telemetry": map[interface{}]interface{}{}, - }, + v1alpha2.Service{ + Telemetry: &v1alpha2.Telemetry{}, }, }, { "missing telemetry", - map[interface{}]interface{}{ - "service": map[interface{}]interface{}{}, - }, + v1alpha2.Service{}, }, } { t.Run(tt.desc, func(t *testing.T) { // these are acceptable failures, we return to the collector's default metric port - port, err := adapters.ConfigToMetricsPort(logger, tt.config) + port, err := adapters.ConfigToMetricsPort(tt.config) assert.NoError(t, err) assert.Equal(t, int32(8888), port) }) diff --git a/internal/manifests/collector/adapters/config_to_probe.go b/internal/manifests/collector/adapters/config_to_probe.go index 897b7db068..e173eae70a 100644 --- a/internal/manifests/collector/adapters/config_to_probe.go +++ b/internal/manifests/collector/adapters/config_to_probe.go @@ -20,20 +20,14 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) var ( - errNoService = errors.New("no service available as part of the configuration") - errNoExtensions = errors.New("no extensions available as part of the configuration") - - errServiceNotAMap = errors.New("service property in the configuration doesn't contain valid services") - errExtensionsNotAMap = errors.New("extensions property in the configuration doesn't contain valid extensions") - - errNoExtensionHealthCheck = errors.New("extensions property in the configuration does not contain the expected health_check extension") - - ErrNoServiceExtensions = errors.New("service property in the configuration doesn't contain extensions") - - errServiceExtensionsNotSlice = errors.New("service extensions property in the configuration does not contain valid extensions") + errNoExtensions = errors.New("no extensions available as part of the configuration") + errNoExtensionHealthCheck = errors.New("extensions property in the configuration does not contain the expected health_check extension") + ErrNoServiceExtensions = errors.New("service property in the configuration doesn't contain extensions") ErrNoServiceExtensionHealthCheck = errors.New("no healthcheck extension available in service extension configuration") ) @@ -48,53 +42,28 @@ const ( ) // ConfigToContainerProbe converts the incoming configuration object into a container probe or returns an error. -func ConfigToContainerProbe(config map[interface{}]interface{}) (*corev1.Probe, error) { - serviceProperty, withService := config["service"] - if !withService { - return nil, errNoService - } - service, withSvcProperty := serviceProperty.(map[interface{}]interface{}) - if !withSvcProperty { - return nil, errServiceNotAMap - } - - serviceExtensionsProperty, withExtension := service["extensions"] - if !withExtension { +func ConfigToContainerProbe(config v1alpha2.Config) (*corev1.Probe, error) { + if config.Extensions == nil { + return nil, errNoExtensions + } else if len(config.Service.Extensions) == 0 { return nil, ErrNoServiceExtensions } - - serviceExtensions, withExtProperty := serviceExtensionsProperty.([]interface{}) - if !withExtProperty { - return nil, errServiceExtensionsNotSlice - } healthCheckServiceExtensions := make([]string, 0) - for _, ext := range serviceExtensions { - parsedExt, ok := ext.(string) - if ok && strings.HasPrefix(parsedExt, "health_check") { - healthCheckServiceExtensions = append(healthCheckServiceExtensions, parsedExt) + for _, ext := range config.Service.Extensions { + if strings.HasPrefix(ext, "health_check") { + healthCheckServiceExtensions = append(healthCheckServiceExtensions, ext) } } - if len(healthCheckServiceExtensions) == 0 { return nil, ErrNoServiceExtensionHealthCheck } - - extensionsProperty, ok := config["extensions"] - if !ok { - return nil, errNoExtensions - } - extensions, ok := extensionsProperty.(map[interface{}]interface{}) - if !ok { - return nil, errExtensionsNotAMap - } // in the event of multiple health_check service extensions defined, we arbitrarily take the first one found for _, healthCheckForProbe := range healthCheckServiceExtensions { - healthCheckExtension, ok := extensions[healthCheckForProbe] + healthCheckExtension, ok := config.Extensions.Object[healthCheckForProbe] if ok { return createProbeFromExtension(healthCheckExtension) } } - return nil, errNoExtensionHealthCheck } @@ -111,7 +80,7 @@ func createProbeFromExtension(extension interface{}) (*corev1.Probe, error) { } func extractProbeConfigurationFromExtension(ext interface{}) probeConfiguration { - extensionCfg, ok := ext.(map[interface{}]interface{}) + extensionCfg, ok := ext.(map[string]interface{}) if !ok { return defaultProbeConfiguration() } @@ -128,7 +97,7 @@ func defaultProbeConfiguration() probeConfiguration { } } -func extractPathFromExtensionConfig(cfg map[interface{}]interface{}) string { +func extractPathFromExtensionConfig(cfg map[string]interface{}) string { if path, ok := cfg["path"]; ok { if parsedPath, ok := path.(string); ok { return parsedPath @@ -137,7 +106,7 @@ func extractPathFromExtensionConfig(cfg map[interface{}]interface{}) string { return defaultHealthCheckPath } -func extractPortFromExtensionConfig(cfg map[interface{}]interface{}) intstr.IntOrString { +func extractPortFromExtensionConfig(cfg map[string]interface{}) intstr.IntOrString { endpoint, ok := cfg["endpoint"] if !ok { return defaultHealthCheckEndpoint() @@ -154,5 +123,5 @@ func extractPortFromExtensionConfig(cfg map[interface{}]interface{}) intstr.IntO } func defaultHealthCheckEndpoint() intstr.IntOrString { - return intstr.FromInt(defaultHealthCheckPort) + return intstr.FromInt32(defaultHealthCheckPort) } diff --git a/internal/manifests/collector/adapters/config_to_probe_test.go b/internal/manifests/collector/adapters/config_to_probe_test.go index 89e1f97349..24f9ae60ec 100644 --- a/internal/manifests/collector/adapters/config_to_probe_test.go +++ b/internal/manifests/collector/adapters/config_to_probe_test.go @@ -19,6 +19,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + go_yaml "gopkg.in/yaml.v3" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) func TestConfigToProbeShouldCreateProbeFor(t *testing.T) { @@ -104,17 +107,20 @@ service: } for _, test := range tests { - // prepare - config, err := ConfigFromString(test.config) - require.NoError(t, err, test.desc) - require.NotEmpty(t, config, test.desc) + t.Run(test.desc, func(t *testing.T) { + // prepare + cfg := v1alpha2.Config{} + err := go_yaml.Unmarshal([]byte(test.config), &cfg) + require.NoError(t, err, test.desc) + require.NotEmpty(t, cfg, test.desc) - // test - actualProbe, err := ConfigToContainerProbe(config) - assert.NoError(t, err) - assert.Equal(t, test.expectedPath, actualProbe.HTTPGet.Path, test.desc) - assert.Equal(t, test.expectedPort, actualProbe.HTTPGet.Port.IntVal, test.desc) - assert.Equal(t, "", actualProbe.HTTPGet.Host, test.desc) + // test + actualProbe, err := ConfigToContainerProbe(cfg) + assert.NoError(t, err) + assert.Equal(t, test.expectedPath, actualProbe.HTTPGet.Path, test.desc) + assert.Equal(t, test.expectedPort, actualProbe.HTTPGet.Port.IntVal, test.desc) + assert.Equal(t, "", actualProbe.HTTPGet.Host, test.desc) + }) } } @@ -131,12 +137,6 @@ func TestConfigToProbeShouldErrorIf(t *testing.T) { service: extensions: [health_check]`, expectedErr: errNoExtensionHealthCheck, - }, { - desc: "BadlyFormattedExtensions", - config: `extensions: [hi] -service: - extensions: [health_check]`, - expectedErr: errExtensionsNotAMap, }, { desc: "NoExtensions", config: `service: @@ -144,44 +144,33 @@ service: expectedErr: errNoExtensions, }, { desc: "NoHealthCheckInServiceExtensions", - config: `service: + config: `extensions: + health_check: +service: extensions: [pprof]`, expectedErr: ErrNoServiceExtensionHealthCheck, - }, { - desc: "BadlyFormattedServiceExtensions", - config: `service: - extensions: - this: should-not-be-a-map`, - expectedErr: errServiceExtensionsNotSlice, }, { desc: "NoServiceExtensions", - config: `service: + config: `extensions: + health_check: +service: pipelines: traces: receivers: [otlp]`, expectedErr: ErrNoServiceExtensions, - }, { - desc: "BadlyFormattedService", - config: `extensions: - health_check: -service: [hi]`, - expectedErr: errServiceNotAMap, - }, { - desc: "NoService", - config: `extensions: - health_check:`, - expectedErr: errNoService, }, } - for _, test := range tests { - // prepare - config, err := ConfigFromString(test.config) - require.NoError(t, err, test.desc) - require.NotEmpty(t, config, test.desc) + t.Run(test.desc, func(t *testing.T) { + // prepare + cfg := v1alpha2.Config{} + err := go_yaml.Unmarshal([]byte(test.config), &cfg) + require.NoError(t, err, test.desc) + require.NotEmpty(t, cfg, test.desc) - // test - _, err = ConfigToContainerProbe(config) - assert.Equal(t, test.expectedErr, err, test.desc) + // test + _, err = ConfigToContainerProbe(cfg) + assert.Equal(t, test.expectedErr, err, test.desc) + }) } } diff --git a/internal/manifests/collector/adapters/config_to_rbac.go b/internal/manifests/collector/adapters/config_to_rbac.go index 340e11eb41..7005b70dac 100644 --- a/internal/manifests/collector/adapters/config_to_rbac.go +++ b/internal/manifests/collector/adapters/config_to_rbac.go @@ -18,38 +18,29 @@ import ( "github.com/go-logr/logr" rbacv1 "k8s.io/api/rbac/v1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/parser/processor" ) // ConfigToRBAC parses the OpenTelemetry Collector configuration and checks what RBAC resources are needed to be created. -func ConfigToRBAC(logger logr.Logger, config map[interface{}]interface{}) []rbacv1.PolicyRule { +func ConfigToRBAC(logger logr.Logger, config v1alpha2.Config) []rbacv1.PolicyRule { var policyRules []rbacv1.PolicyRule - processorsRaw, ok := config["processors"] - if !ok { - logger.V(2).Info("no processors available as part of the configuration") + if config.Processors == nil { return policyRules } + enabledProcessors := getEnabledComponents(config.Service, ComponentTypeProcessor) - processors, ok := processorsRaw.(map[interface{}]interface{}) - if !ok { - logger.V(2).Info("processors doesn't contain valid components") - return policyRules - } - - enabledProcessors := getEnabledComponents(config, ComponentTypeProcessor) - - for key, val := range processors { - if !enabledProcessors[key] { + for processorName, val := range config.Processors.Object { + if !enabledProcessors[processorName] { continue } - processorCfg, ok := val.(map[interface{}]interface{}) + processorCfg, ok := val.(map[string]interface{}) if !ok { - logger.V(2).Info("processor doesn't seem to be a map of properties", "processor", key) - processorCfg = map[interface{}]interface{}{} + logger.V(2).Info("processor doesn't seem to be a map of properties", "processor", processorName) + processorCfg = map[string]interface{}{} } - processorName := key.(string) processorParser, err := processor.For(logger, processorName, processorCfg) if err != nil { logger.V(2).Info("no parser found for '%s'", processorName) diff --git a/internal/manifests/collector/adapters/config_to_rbac_test.go b/internal/manifests/collector/adapters/config_to_rbac_test.go index 28774ca846..cf39bc17f8 100644 --- a/internal/manifests/collector/adapters/config_to_rbac_test.go +++ b/internal/manifests/collector/adapters/config_to_rbac_test.go @@ -19,8 +19,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" rbacv1 "k8s.io/api/rbac/v1" logf "sigs.k8s.io/controller-runtime/pkg/log" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) func TestConfigRBAC(t *testing.T) { @@ -87,12 +90,12 @@ service: for _, tt := range tests { t.Run(tt.desc, func(t *testing.T) { - config, err := ConfigFromString(tt.config) - require.NoError(t, err, tt.desc) - require.NotEmpty(t, config, tt.desc) + cfg := v1alpha2.Config{} + err := yaml.Unmarshal([]byte(tt.config), &cfg) + require.NoError(t, err) // test - rules := ConfigToRBAC(logger, config) + rules := ConfigToRBAC(logger, cfg) assert.NoError(t, err) assert.Equal(t, tt.expectedRules, rules, tt.desc) }) diff --git a/internal/manifests/collector/adapters/config_validate.go b/internal/manifests/collector/adapters/config_validate.go index 87082b30e7..0ce6fca409 100644 --- a/internal/manifests/collector/adapters/config_validate.go +++ b/internal/manifests/collector/adapters/config_validate.go @@ -22,88 +22,40 @@ import ( // Following Otel Doc: Configuring a receiver does not enable it. The receivers are enabled via pipelines within the service section. // getEnabledComponents returns all enabled components as a true flag set. If it can't find any receiver, it will return a nil interface. -func getEnabledComponents(config v1alpha2.Config, componentType ComponentType) map[interface{}]bool { +func getEnabledComponents(config v1alpha2.Service, componentType ComponentType) map[string]bool { + availableComponents := map[string]bool{} componentTypePlural := fmt.Sprintf("%ss", componentType.String()) - cfgComponents, ok := config[componentTypePlural] - if !ok { - return nil - } - components, ok := cfgComponents.(map[interface{}]interface{}) - if !ok { - return nil - } - availableComponents := map[interface{}]bool{} - - for compID := range components { - - //Safe Cast - componentID, withComponent := compID.(string) - if !withComponent { - return nil - } - //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{}) - if !withService { - return nil - } - - pipeline, withPipeline := cfgService["pipelines"].(map[interface{}]interface{}) - if !withPipeline { - return nil - } - availablePipelines := map[string]bool{} - - for pipID := range pipeline { - //Safe Cast - pipelineID, existsPipeline := pipID.(string) - if !existsPipeline { - return nil - } - //Getting all the available pipelines. - availablePipelines[pipelineID] = true - } - - if len(pipeline) > 0 { - for pipelineID, pipelineCfg := range pipeline { - //Safe Cast - pipelineV, withPipelineCfg := pipelineID.(string) - if !withPipelineCfg { - continue + for pipelineID, pipelineCfg := range config.Pipelines.Object { + //Condition will get information if there are multiple configured pipelines. + if len(pipelineID) > 0 { + pipelineDesc, ok := pipelineCfg.(map[string]interface{}) + if !ok { + return nil } - //Condition will get information if there are multiple configured pipelines. - if len(pipelineV) > 0 { - pipelineDesc, ok := pipelineCfg.(map[interface{}]interface{}) - if !ok { - return nil - } - for pipSpecID, pipSpecCfg := range pipelineDesc { - if pipSpecID.(string) == componentTypePlural { - receiversList, ok := pipSpecCfg.([]interface{}) - if !ok { - continue - } - // If receiversList is empty means that we haven't any enabled Receiver. - if len(receiversList) == 0 { - availableComponents = nil - } else { - // All enabled receivers will be set as true - for _, comKey := range receiversList { - //Safe Cast - receiverKey, ok := comKey.(string) - if !ok { - return nil - } - availableComponents[receiverKey] = true + for pipSpecID, pipSpecCfg := range pipelineDesc { + if pipSpecID == componentTypePlural { + receiversList, ok := pipSpecCfg.([]interface{}) + if !ok { + continue + } + // If receiversList is empty means that we haven't any enabled Receiver. + if len(receiversList) == 0 { + availableComponents = nil + } else { + // All enabled receivers will be set as true + for _, comKey := range receiversList { + //Safe Cast + receiverKey, ok := comKey.(string) + if !ok { + return nil } + availableComponents[receiverKey] = true } - //Removing all non-enabled receivers - for comID, comKey := range availableComponents { - if !(comKey) { - delete(availableComponents, comID) - } + } + //Removing all non-enabled receivers + for comID, comKey := range availableComponents { + if !(comKey) { + delete(availableComponents, comID) } } } diff --git a/internal/manifests/collector/adapters/config_validate_test.go b/internal/manifests/collector/adapters/config_validate_test.go index 7003235fed..22cec8585f 100644 --- a/internal/manifests/collector/adapters/config_validate_test.go +++ b/internal/manifests/collector/adapters/config_validate_test.go @@ -18,6 +18,9 @@ import ( "testing" "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" + + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) func TestConfigValidate(t *testing.T) { @@ -52,12 +55,12 @@ service: exporters: [debug] ` // // prepare - config, err := ConfigFromString(configStr) + cfg := v1alpha2.Config{} + err := yaml.Unmarshal([]byte(configStr), &cfg) require.NoError(t, err) - require.NotEmpty(t, config) // test - check := getEnabledComponents(config, ComponentTypeReceiver) + check := getEnabledComponents(cfg.Service, ComponentTypeReceiver) require.NotEmpty(t, check) } @@ -93,11 +96,11 @@ service: exporters: [] ` // // prepare - config, err := ConfigFromString(configStr) + cfg := v1alpha2.Config{} + err := yaml.Unmarshal([]byte(configStr), &cfg) require.NoError(t, err) - require.NotEmpty(t, config) // test - check := getEnabledComponents(config, ComponentTypeReceiver) + check := getEnabledComponents(cfg.Service, ComponentTypeReceiver) require.Empty(t, check) } diff --git a/internal/manifests/collector/annotations_test.go b/internal/manifests/collector/annotations_test.go index 9119bbda0a..fee3f900a5 100644 --- a/internal/manifests/collector/annotations_test.go +++ b/internal/manifests/collector/annotations_test.go @@ -35,10 +35,7 @@ func TestDefaultAnnotations(t *testing.T) { Spec: v1alpha2.OpenTelemetryCollectorSpec{ Config: v1alpha2.Config{ Service: v1alpha2.Service{ - Extensions: func() *[]string { - res := []string{"test"} - return &res - }(), + Extensions: []string{"test"}, }, }, }, @@ -111,10 +108,7 @@ func TestUserAnnotations(t *testing.T) { Spec: v1alpha2.OpenTelemetryCollectorSpec{ Config: v1alpha2.Config{ Service: v1alpha2.Service{ - Extensions: func() *[]string { - res := []string{"test2"} - return &res - }(), + Extensions: []string{"test2"}, }, }, }, diff --git a/internal/manifests/collector/container.go b/internal/manifests/collector/container.go index 2223eaaa29..79d59d16c0 100644 --- a/internal/manifests/collector/container.go +++ b/internal/manifests/collector/container.go @@ -42,12 +42,6 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha2.OpenTelem image = cfg.CollectorImage() } - configYaml, err := otelcol.Spec.Config.Yaml() - if err != nil { - logger.Error(err, "could not convert json to yaml") - return corev1.Container{} - } - // build container ports from service ports ports, err := getConfigContainerPorts(logger, otelcol) if err != nil { @@ -139,16 +133,14 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha2.OpenTelem } var livenessProbe *corev1.Probe - if configFromString, err := adapters.ConfigFromString(configYaml); err == nil { - if probe, err := getLivenessProbe(configFromString, otelcol.Spec.LivenessProbe); err == nil { - livenessProbe = probe - } else if errors.Is(err, adapters.ErrNoServiceExtensions) { - logger.Info("extensions not configured, skipping liveness probe creation") - } else if errors.Is(err, adapters.ErrNoServiceExtensionHealthCheck) { - logger.Info("healthcheck extension not configured, skipping liveness probe creation") - } else { - logger.Error(err, "cannot create liveness probe.") - } + if probe, err := getLivenessProbe(otelcol.Spec.Config, otelcol.Spec.LivenessProbe); err == nil { + livenessProbe = probe + } else if errors.Is(err, adapters.ErrNoServiceExtensions) { + logger.Info("extensions not configured, skipping liveness probe creation") + } else if errors.Is(err, adapters.ErrNoServiceExtensionHealthCheck) { + logger.Info("healthcheck extension not configured, skipping liveness probe creation") + } else { + logger.Error(err, "cannot create liveness probe.") } envVars = append(envVars, proxy.ReadProxyVarsFromEnv()...) @@ -196,7 +188,7 @@ func getConfigContainerPorts(logger logr.Logger, collector v1alpha2.OpenTelemetr } } - metricsPort, err := adapters.ConfigToMetricsPort(logger, c) + metricsPort, err := adapters.ConfigToMetricsPort(collector.Spec.Config.Service) if err != nil { logger.Info("couldn't determine metrics port from configuration, using 8888 default value", "error", err) metricsPort = 8888 @@ -221,7 +213,7 @@ func portMapToList(portMap map[string]corev1.ContainerPort) []corev1.ContainerPo return ports } -func getLivenessProbe(config map[interface{}]interface{}, probeConfig *v1alpha2.Probe) (*corev1.Probe, error) { +func getLivenessProbe(config v1alpha2.Config, probeConfig *v1alpha2.Probe) (*corev1.Probe, error) { probe, err := adapters.ConfigToContainerProbe(config) if err != nil { return nil, err diff --git a/internal/manifests/collector/ingress.go b/internal/manifests/collector/ingress.go index 2992aa941f..2dc08a02a0 100644 --- a/internal/manifests/collector/ingress.go +++ b/internal/manifests/collector/ingress.go @@ -24,7 +24,6 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -137,17 +136,7 @@ func createSubdomainIngressRules(otelcol string, hostname string, ports []corev1 } func servicePortsFromCfg(logger logr.Logger, otelcol v1alpha2.OpenTelemetryCollector) ([]corev1.ServicePort, error) { - out, err := otelcol.Spec.Config.Yaml() - if err != nil { - return nil, err - } - configFromString, err := adapters.ConfigFromString(out) - if err != nil { - logger.Error(err, "couldn't extract the configuration from the context") - return nil, err - } - - ports, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeReceiver, configFromString) + ports, err := otelcol.Spec.Config.Receivers.Ports(logger) if err != nil { logger.Error(err, "couldn't build the ingress for this instance") return nil, err diff --git a/internal/manifests/collector/parser/exporter/exporter.go b/internal/manifests/collector/parser/exporter/exporter.go index 93c66b8599..80272d692b 100644 --- a/internal/manifests/collector/parser/exporter/exporter.go +++ b/internal/manifests/collector/parser/exporter/exporter.go @@ -38,7 +38,7 @@ func BuilderFor(name string) parser.Builder { } // For returns a new parser for the given exporter name + config. -func For(logger logr.Logger, name string, config map[interface{}]interface{}) (parser.ComponentPortParser, error) { +func For(logger logr.Logger, name string, config map[string]interface{}) (parser.ComponentPortParser, error) { builder := BuilderFor(name) if builder == nil { return nil, fmt.Errorf("no builders for %s", name) @@ -61,7 +61,7 @@ var ( endpointKey = "endpoint" ) -func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[interface{}]interface{}) *corev1.ServicePort { +func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[string]interface{}) *corev1.ServicePort { endpoint := getAddressFromConfig(logger, name, endpointKey, config) switch e := endpoint.(type) { @@ -85,7 +85,7 @@ func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[in return nil } -func getAddressFromConfig(logger logr.Logger, name, key string, config map[interface{}]interface{}) interface{} { +func getAddressFromConfig(logger logr.Logger, name, key string, config map[string]interface{}) interface{} { endpoint, ok := config[key] if !ok { logger.V(2).Info("%s exporter doesn't have an %s", name, key) diff --git a/internal/manifests/collector/parser/exporter/exporter_prometheus.go b/internal/manifests/collector/parser/exporter/exporter_prometheus.go index 61d58588da..92fa06ae8f 100644 --- a/internal/manifests/collector/parser/exporter/exporter_prometheus.go +++ b/internal/manifests/collector/parser/exporter/exporter_prometheus.go @@ -32,13 +32,13 @@ const ( // PrometheusExporterParser parses the configuration for OTLP receivers. type PrometheusExporterParser struct { - config map[interface{}]interface{} + config map[string]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{}) parser.ComponentPortParser { +func NewPrometheusExporterParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &PrometheusExporterParser{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/parser.go b/internal/manifests/collector/parser/parser.go index 62de283b15..e7a1acd253 100644 --- a/internal/manifests/collector/parser/parser.go +++ b/internal/manifests/collector/parser/parser.go @@ -28,4 +28,7 @@ type ComponentPortParser interface { } // Builder specifies the signature required for parser builders. -type Builder func(logr.Logger, string, map[interface{}]interface{}) ComponentPortParser +type Builder func(logr.Logger, string, map[string]interface{}) ComponentPortParser + +// BuilderFor returns a builder for a given component +type BuilderFor func(component string) Builder diff --git a/internal/manifests/collector/parser/processor/processor.go b/internal/manifests/collector/parser/processor/processor.go index 784fffeade..ddc4f88526 100644 --- a/internal/manifests/collector/parser/processor/processor.go +++ b/internal/manifests/collector/parser/processor/processor.go @@ -30,7 +30,7 @@ type ProcessorParser interface { } // Builder specifies the signature required for parser builders. -type Builder func(logr.Logger, string, map[interface{}]interface{}) ProcessorParser +type Builder func(logr.Logger, string, map[string]interface{}) ProcessorParser // registry holds a record of all known processor parsers. var registry = make(map[string]Builder) @@ -41,7 +41,7 @@ func BuilderFor(name string) Builder { } // For returns a new parser for the given processor name + config. -func For(logger logr.Logger, name string, config map[interface{}]interface{}) (ProcessorParser, error) { +func For(logger logr.Logger, name string, config map[string]interface{}) (ProcessorParser, error) { builder := BuilderFor(name) if builder == nil { return nil, fmt.Errorf("no builders for %s", name) diff --git a/internal/manifests/collector/parser/processor/processor_k8sattributes.go b/internal/manifests/collector/parser/processor/processor_k8sattributes.go index 25b30434af..d3e3ce005a 100644 --- a/internal/manifests/collector/parser/processor/processor_k8sattributes.go +++ b/internal/manifests/collector/parser/processor/processor_k8sattributes.go @@ -30,13 +30,13 @@ const ( // PrometheusExporterParser parses the configuration for k8sattributes processor. type K8sAttributesParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewK8sAttributesParser builds a new parser k8sattributes processor. -func NewK8sAttributesParser(logger logr.Logger, name string, config map[interface{}]interface{}) ProcessorParser { +func NewK8sAttributesParser(logger logr.Logger, name string, config map[string]interface{}) ProcessorParser { return &K8sAttributesParser{ logger: logger, name: name, @@ -57,7 +57,7 @@ func (o *K8sAttributesParser) GetRBACRules() []rbacv1.PolicyRule { return prs } - metadataCfg, ok := extractCfg.(map[interface{}]interface{})["metadata"] + metadataCfg, ok := extractCfg.(map[string]interface{})["metadata"] if !ok { return prs } diff --git a/internal/manifests/collector/parser/processor/processor_resourcedetection.go b/internal/manifests/collector/parser/processor/processor_resourcedetection.go index b9038733c5..23c4a34ff0 100644 --- a/internal/manifests/collector/parser/processor/processor_resourcedetection.go +++ b/internal/manifests/collector/parser/processor/processor_resourcedetection.go @@ -29,13 +29,13 @@ const ( // PrometheusExporterParser parses the configuration for OTLP receivers. type ResourceDetectionParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewPrometheusExporterParser builds a new parser for OTLP receivers. -func NewResourceDetectionParser(logger logr.Logger, name string, config map[interface{}]interface{}) ProcessorParser { +func NewResourceDetectionParser(logger logr.Logger, name string, config map[string]interface{}) ProcessorParser { return &ResourceDetectionParser{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver.go b/internal/manifests/collector/parser/receiver/receiver.go index 97147658f4..a42d65502c 100644 --- a/internal/manifests/collector/parser/receiver/receiver.go +++ b/internal/manifests/collector/parser/receiver/receiver.go @@ -44,7 +44,7 @@ func BuilderFor(name string) parser.Builder { } // For returns a new parser for the given receiver name + config. -func For(logger logr.Logger, name string, config map[interface{}]interface{}) (parser.ComponentPortParser, error) { +func For(logger logr.Logger, name string, config map[string]interface{}) (parser.ComponentPortParser, error) { builder := BuilderFor(name) return builder(logger, name, config), nil } @@ -102,7 +102,7 @@ func isScraperReceiver(name string) bool { return exists } -func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[interface{}]interface{}) *v1.ServicePort { +func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[string]interface{}) *v1.ServicePort { var endpoint interface{} switch { // syslog receiver contains the endpoint @@ -110,12 +110,12 @@ func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[in // i.e. either in tcp or udp section with field key // as `listen_address` case name == "syslog": - var c map[interface{}]interface{} + var c map[string]interface{} if udp, isUDP := config["udp"]; isUDP && udp != nil { - c = udp.(map[interface{}]interface{}) + c = udp.(map[string]interface{}) endpoint = getAddressFromConfig(logger, name, listenAddressKey, c) } else if tcp, isTCP := config["tcp"]; isTCP && tcp != nil { - c = tcp.(map[interface{}]interface{}) + c = tcp.(map[string]interface{}) endpoint = getAddressFromConfig(logger, name, listenAddressKey, c) } @@ -155,7 +155,7 @@ func singlePortFromConfigEndpoint(logger logr.Logger, name string, config map[in return nil } -func getAddressFromConfig(logger logr.Logger, name, key string, config map[interface{}]interface{}) interface{} { +func getAddressFromConfig(logger logr.Logger, name, key string, config map[string]interface{}) interface{} { endpoint, ok := config[key] if !ok { logger.V(2).Info("%s receiver doesn't have an %s", name, key) diff --git a/internal/manifests/collector/parser/receiver/receiver_aws-xray.go b/internal/manifests/collector/parser/receiver/receiver_aws-xray.go index 44618b3aa5..e7911d0de3 100644 --- a/internal/manifests/collector/parser/receiver/receiver_aws-xray.go +++ b/internal/manifests/collector/parser/receiver/receiver_aws-xray.go @@ -23,7 +23,7 @@ import ( const parserNameAWSXRAY = "__awsxray" // NewAWSXrayReceiverParser builds a new parser for AWS xray receivers, from the contrib repository. -func NewAWSXrayReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewAWSXrayReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_carbon.go b/internal/manifests/collector/parser/receiver/receiver_carbon.go index b1b0aaa4ce..55b6e705c2 100644 --- a/internal/manifests/collector/parser/receiver/receiver_carbon.go +++ b/internal/manifests/collector/parser/receiver/receiver_carbon.go @@ -23,7 +23,7 @@ import ( const parserNameCarbon = "__carbon" // NewCarbonReceiverParser builds a new parser for Carbon receivers, from the contrib repository. -func NewCarbonReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewCarbonReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_collectd.go b/internal/manifests/collector/parser/receiver/receiver_collectd.go index aa42ab0397..436357ad89 100644 --- a/internal/manifests/collector/parser/receiver/receiver_collectd.go +++ b/internal/manifests/collector/parser/receiver/receiver_collectd.go @@ -23,7 +23,7 @@ import ( const parserNameCollectd = "__collectd" // NewCollectdReceiverParser builds a new parser for Collectd receivers, from the contrib repository. -func NewCollectdReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewCollectdReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go b/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go index 88881923fa..cd3596499f 100644 --- a/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go +++ b/internal/manifests/collector/parser/receiver/receiver_fluent-forward.go @@ -23,7 +23,7 @@ import ( const parserNameFluentForward = "__fluentforward" // NewFluentForwardReceiverParser builds a new parser for FluentForward receivers, from the contrib repository. -func NewFluentForwardReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewFluentForwardReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_generic.go b/internal/manifests/collector/parser/receiver/receiver_generic.go index 864b5bb111..1c7e314af2 100644 --- a/internal/manifests/collector/parser/receiver/receiver_generic.go +++ b/internal/manifests/collector/parser/receiver/receiver_generic.go @@ -28,7 +28,7 @@ var _ parser.ComponentPortParser = &GenericReceiver{} // GenericReceiver is a special parser for generic receivers. It doesn't self-register and should be created/used directly. type GenericReceiver struct { - config map[interface{}]interface{} + config map[string]interface{} defaultAppProtocol *string logger logr.Logger name string @@ -41,7 +41,7 @@ type GenericReceiver struct { // so that it can expose the required port based on the receiver's config. Receiver scrapers are ignored. // NewGenericReceiverParser builds a new parser for generic receivers. -func NewGenericReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewGenericReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_generic_test.go b/internal/manifests/collector/parser/receiver/receiver_generic_test.go index 1adfcf12df..2e0a1299ba 100644 --- a/internal/manifests/collector/parser/receiver/receiver_generic_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_generic_test.go @@ -30,7 +30,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 := receiver.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ + builder := receiver.NewGenericReceiverParser(logger, "myreceiver", map[string]interface{}{ "endpoint": "0.0.0.0:1234", }) @@ -46,7 +46,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 := receiver.NewGenericReceiverParser(logger, "myreceiver", map[interface{}]interface{}{ + builder := receiver.NewGenericReceiverParser(logger, "myreceiver", map[string]interface{}{ "endpoint": "0.0.0.0", }) @@ -60,7 +60,7 @@ func TestFailedToParseEndpoint(t *testing.T) { func TestDownstreamParsers(t *testing.T) { for _, tt := range []struct { - builder func(logr.Logger, string, map[interface{}]interface{}) parser.ComponentPortParser + builder func(logr.Logger, string, map[string]interface{}) parser.ComponentPortParser desc string receiverName string parserName string @@ -85,7 +85,7 @@ func TestDownstreamParsers(t *testing.T) { t.Run(tt.receiverName, func(t *testing.T) { t.Run("builds successfully", func(t *testing.T) { // test - builder := tt.builder(logger, tt.receiverName, map[interface{}]interface{}{}) + builder := tt.builder(logger, tt.receiverName, map[string]interface{}{}) // verify assert.Equal(t, tt.parserName, builder.ParserName()) @@ -93,7 +93,7 @@ func TestDownstreamParsers(t *testing.T) { t.Run("assigns the expected port", func(t *testing.T) { // prepare - builder := tt.builder(logger, tt.receiverName, map[interface{}]interface{}{}) + builder := tt.builder(logger, tt.receiverName, map[string]interface{}{}) // test ports, err := builder.Ports() @@ -107,7 +107,7 @@ func TestDownstreamParsers(t *testing.T) { t.Run("allows port to be overridden", func(t *testing.T) { // prepare - builder := tt.builder(logger, tt.receiverName, map[interface{}]interface{}{ + builder := tt.builder(logger, tt.receiverName, map[string]interface{}{ "endpoint": "0.0.0.0:65535", }) diff --git a/internal/manifests/collector/parser/receiver/receiver_influxdb.go b/internal/manifests/collector/parser/receiver/receiver_influxdb.go index 0930a29f73..736c27755f 100644 --- a/internal/manifests/collector/parser/receiver/receiver_influxdb.go +++ b/internal/manifests/collector/parser/receiver/receiver_influxdb.go @@ -23,7 +23,7 @@ import ( const parserNameInfluxdb = "__influxdb" // NewInfluxdbReceiverParser builds a new parser for Influxdb receivers, from the contrib repository. -func NewInfluxdbReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewInfluxdbReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_jaeger.go b/internal/manifests/collector/parser/receiver/receiver_jaeger.go index dcc99d8bd9..2970640eec 100644 --- a/internal/manifests/collector/parser/receiver/receiver_jaeger.go +++ b/internal/manifests/collector/parser/receiver/receiver_jaeger.go @@ -37,14 +37,14 @@ const ( // JaegerReceiverParser parses the configuration for Jaeger-specific receivers. type JaegerReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewJaegerReceiverParser builds a new parser for Jaeger receivers. -func NewJaegerReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { - if protocols, ok := config["protocols"].(map[interface{}]interface{}); ok { +func NewJaegerReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { + if protocols, ok := config["protocols"].(map[string]interface{}); ok { return &JaegerReceiverParser{ logger: logger, name: name, @@ -54,7 +54,7 @@ func NewJaegerReceiverParser(logger logr.Logger, name string, config map[interfa return &JaegerReceiverParser{ name: name, - config: map[interface{}]interface{}{}, + config: map[string]interface{}{}, } } @@ -98,7 +98,7 @@ func (j *JaegerReceiverParser) Ports() ([]corev1.ServicePort, error) { var protocolPort *corev1.ServicePort // do we have a configuration block for the protocol? - settings, ok := receiverProtocol.(map[interface{}]interface{}) + settings, ok := receiverProtocol.(map[string]interface{}) if ok { protocolPort = singlePortFromConfigEndpoint(j.logger, nameWithProtocol, settings) } diff --git a/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go b/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go index dadf3e0cb5..1409eaa084 100644 --- a/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_jaeger_test.go @@ -28,7 +28,7 @@ func TestJaegerSelfRegisters(t *testing.T) { func TestJaegerIsFoundByName(t *testing.T) { // test - p, err := For(logger, "jaeger", map[interface{}]interface{}{}) + p, err := For(logger, "jaeger", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -37,9 +37,9 @@ func TestJaegerIsFoundByName(t *testing.T) { func TestJaegerMinimalConfiguration(t *testing.T) { // prepare - builder := NewJaegerReceiverParser(logger, "jaeger", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{}, + builder := NewJaegerReceiverParser(logger, "jaeger", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{}, }, }) @@ -55,9 +55,9 @@ func TestJaegerMinimalConfiguration(t *testing.T) { func TestJaegerPortsOverridden(t *testing.T) { // prepare - builder := NewJaegerReceiverParser(logger, "jaeger", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{ + builder := NewJaegerReceiverParser(logger, "jaeger", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{ "endpoint": "0.0.0.0:1234", }, }, @@ -75,12 +75,12 @@ func TestJaegerPortsOverridden(t *testing.T) { func TestJaegerExposeDefaultPorts(t *testing.T) { // prepare - builder := NewJaegerReceiverParser(logger, "jaeger", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{}, - "thrift_http": map[interface{}]interface{}{}, - "thrift_compact": map[interface{}]interface{}{}, - "thrift_binary": map[interface{}]interface{}{}, + builder := NewJaegerReceiverParser(logger, "jaeger", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{}, + "thrift_http": map[string]interface{}{}, + "thrift_compact": map[string]interface{}{}, + "thrift_binary": map[string]interface{}{}, }, }) diff --git a/internal/manifests/collector/parser/receiver/receiver_loki.go b/internal/manifests/collector/parser/receiver/receiver_loki.go index 6cdac81356..5c81b99592 100644 --- a/internal/manifests/collector/parser/receiver/receiver_loki.go +++ b/internal/manifests/collector/parser/receiver/receiver_loki.go @@ -36,14 +36,14 @@ const ( // LokiReceiverParser parses the configuration for Loki receivers. type LokiReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewLokiReceiverParser builds a new parser for Loki receivers. -func NewLokiReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { - if protocols, ok := config["protocols"].(map[interface{}]interface{}); ok { +func NewLokiReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { + if protocols, ok := config["protocols"].(map[string]interface{}); ok { return &LokiReceiverParser{ logger: logger, name: name, @@ -53,7 +53,7 @@ func NewLokiReceiverParser(logger logr.Logger, name string, config map[interface return &LokiReceiverParser{ name: name, - config: map[interface{}]interface{}{}, + config: map[string]interface{}{}, } } @@ -95,7 +95,7 @@ func (o *LokiReceiverParser) Ports() ([]corev1.ServicePort, error) { var protocolPort *corev1.ServicePort // do we have a configuration block for the protocol? - settings, ok := receiverProtocol.(map[interface{}]interface{}) + settings, ok := receiverProtocol.(map[string]interface{}) if ok { protocolPort = singlePortFromConfigEndpoint(o.logger, nameWithProtocol, settings) } diff --git a/internal/manifests/collector/parser/receiver/receiver_loki_test.go b/internal/manifests/collector/parser/receiver/receiver_loki_test.go index cc10edc9f1..769978fb08 100644 --- a/internal/manifests/collector/parser/receiver/receiver_loki_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_loki_test.go @@ -27,7 +27,7 @@ func TestLokiSelfRegisters(t *testing.T) { func TestLokiIsFoundByName(t *testing.T) { // test - p, err := For(logger, "loki", map[interface{}]interface{}{}) + p, err := For(logger, "loki", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -36,12 +36,12 @@ func TestLokiIsFoundByName(t *testing.T) { func TestLokiPortsOverridden(t *testing.T) { // prepare - builder := NewLokiReceiverParser(logger, "loki", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{ + builder := NewLokiReceiverParser(logger, "loki", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{ "endpoint": "0.0.0.0:1234", }, - "http": map[interface{}]interface{}{ + "http": map[string]interface{}{ "endpoint": "0.0.0.0:1235", }, }, @@ -75,10 +75,10 @@ func TestLokiPortsOverridden(t *testing.T) { func TestLokiExposeDefaultPorts(t *testing.T) { // prepare - builder := NewLokiReceiverParser(logger, "loki", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{}, - "http": map[interface{}]interface{}{}, + builder := NewLokiReceiverParser(logger, "loki", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{}, + "http": map[string]interface{}{}, }, }) diff --git a/internal/manifests/collector/parser/receiver/receiver_oc.go b/internal/manifests/collector/parser/receiver/receiver_oc.go index 6619439a82..8e5c050fa8 100644 --- a/internal/manifests/collector/parser/receiver/receiver_oc.go +++ b/internal/manifests/collector/parser/receiver/receiver_oc.go @@ -23,7 +23,7 @@ import ( const parserNameOpenCensus = "__opencensus" // NewOpenCensusReceiverParser builds a new parser for OpenCensus receivers. -func NewOpenCensusReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewOpenCensusReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { httpAppProtocol := "http" return &GenericReceiver{ logger: logger, diff --git a/internal/manifests/collector/parser/receiver/receiver_otlp.go b/internal/manifests/collector/parser/receiver/receiver_otlp.go index 68972fd950..6b07dd61ea 100644 --- a/internal/manifests/collector/parser/receiver/receiver_otlp.go +++ b/internal/manifests/collector/parser/receiver/receiver_otlp.go @@ -41,14 +41,14 @@ var ( // OTLPReceiverParser parses the configuration for OTLP receivers. type OTLPReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewOTLPReceiverParser builds a new parser for OTLP receivers. -func NewOTLPReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { - if protocols, ok := config["protocols"].(map[interface{}]interface{}); ok { +func NewOTLPReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { + if protocols, ok := config["protocols"].(map[string]interface{}); ok { return &OTLPReceiverParser{ logger: logger, name: name, @@ -58,7 +58,7 @@ func NewOTLPReceiverParser(logger logr.Logger, name string, config map[interface return &OTLPReceiverParser{ name: name, - config: map[interface{}]interface{}{}, + config: map[string]interface{}{}, } } @@ -100,7 +100,7 @@ func (o *OTLPReceiverParser) Ports() ([]corev1.ServicePort, error) { var protocolPort *corev1.ServicePort // do we have a configuration block for the protocol? - settings, ok := receiverProtocol.(map[interface{}]interface{}) + settings, ok := receiverProtocol.(map[string]interface{}) if ok { protocolPort = singlePortFromConfigEndpoint(o.logger, nameWithProtocol, settings) } diff --git a/internal/manifests/collector/parser/receiver/receiver_otlp_test.go b/internal/manifests/collector/parser/receiver/receiver_otlp_test.go index 7165153dde..099c6da267 100644 --- a/internal/manifests/collector/parser/receiver/receiver_otlp_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_otlp_test.go @@ -27,7 +27,7 @@ func TestOTLPSelfRegisters(t *testing.T) { func TestOTLPIsFoundByName(t *testing.T) { // test - p, err := For(logger, "otlp", map[interface{}]interface{}{}) + p, err := For(logger, "otlp", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -36,12 +36,12 @@ func TestOTLPIsFoundByName(t *testing.T) { func TestOTLPPortsOverridden(t *testing.T) { // prepare - builder := NewOTLPReceiverParser(logger, "otlp", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{ + builder := NewOTLPReceiverParser(logger, "otlp", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{ "endpoint": "0.0.0.0:1234", }, - "http": map[interface{}]interface{}{ + "http": map[string]interface{}{ "endpoint": "0.0.0.0:1235", }, }, @@ -75,10 +75,10 @@ func TestOTLPPortsOverridden(t *testing.T) { func TestOTLPExposeDefaultPorts(t *testing.T) { // prepare - builder := NewOTLPReceiverParser(logger, "otlp", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{}, - "http": map[interface{}]interface{}{}, + builder := NewOTLPReceiverParser(logger, "otlp", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{}, + "http": map[string]interface{}{}, }, }) diff --git a/internal/manifests/collector/parser/receiver/receiver_sapm.go b/internal/manifests/collector/parser/receiver/receiver_sapm.go index 924b88bff5..a4e375be95 100644 --- a/internal/manifests/collector/parser/receiver/receiver_sapm.go +++ b/internal/manifests/collector/parser/receiver/receiver_sapm.go @@ -23,7 +23,7 @@ import ( const parserNameSAPM = "__sapm" // NewSAPMReceiverParser builds a new parser for SAPM receivers, from the contrib repository. -func NewSAPMReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewSAPMReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_signalfx.go b/internal/manifests/collector/parser/receiver/receiver_signalfx.go index 549e802453..ce7ab3d107 100644 --- a/internal/manifests/collector/parser/receiver/receiver_signalfx.go +++ b/internal/manifests/collector/parser/receiver/receiver_signalfx.go @@ -23,7 +23,7 @@ import ( const parserNameSignalFx = "__signalfx" // NewSignalFxReceiverParser builds a new parser for SignalFx receivers, from the contrib repository. -func NewSignalFxReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewSignalFxReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_skywalking.go b/internal/manifests/collector/parser/receiver/receiver_skywalking.go index 9b72847ee9..66d6ea7ec7 100644 --- a/internal/manifests/collector/parser/receiver/receiver_skywalking.go +++ b/internal/manifests/collector/parser/receiver/receiver_skywalking.go @@ -36,14 +36,14 @@ const ( // SkywalkingReceiverParser parses the configuration for Skywalking receivers. type SkywalkingReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewSkywalkingReceiverParser builds a new parser for Skywalking receivers. -func NewSkywalkingReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { - if protocols, ok := config["protocols"].(map[interface{}]interface{}); ok { +func NewSkywalkingReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { + if protocols, ok := config["protocols"].(map[string]interface{}); ok { return &SkywalkingReceiverParser{ logger: logger, name: name, @@ -53,7 +53,7 @@ func NewSkywalkingReceiverParser(logger logr.Logger, name string, config map[int return &SkywalkingReceiverParser{ name: name, - config: map[interface{}]interface{}{}, + config: map[string]interface{}{}, } } @@ -95,7 +95,7 @@ func (o *SkywalkingReceiverParser) Ports() ([]corev1.ServicePort, error) { var protocolPort *corev1.ServicePort // do we have a configuration block for the protocol? - settings, ok := receiverProtocol.(map[interface{}]interface{}) + settings, ok := receiverProtocol.(map[string]interface{}) if ok { protocolPort = singlePortFromConfigEndpoint(o.logger, nameWithProtocol, settings) } diff --git a/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go b/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go index ab00c852c2..160d76fc9d 100644 --- a/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_skywalking_test.go @@ -27,7 +27,7 @@ func TestSkywalkingSelfRegisters(t *testing.T) { func TestSkywalkingIsFoundByName(t *testing.T) { // test - p, err := For(logger, "skywalking", map[interface{}]interface{}{}) + p, err := For(logger, "skywalking", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -36,12 +36,12 @@ func TestSkywalkingIsFoundByName(t *testing.T) { func TestSkywalkingPortsOverridden(t *testing.T) { // prepare - builder := NewSkywalkingReceiverParser(logger, "skywalking", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{ + builder := NewSkywalkingReceiverParser(logger, "skywalking", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{ "endpoint": "0.0.0.0:1234", }, - "http": map[interface{}]interface{}{ + "http": map[string]interface{}{ "endpoint": "0.0.0.0:1235", }, }, @@ -75,10 +75,10 @@ func TestSkywalkingPortsOverridden(t *testing.T) { func TestSkywalkingExposeDefaultPorts(t *testing.T) { // prepare - builder := NewSkywalkingReceiverParser(logger, "skywalking", map[interface{}]interface{}{ - "protocols": map[interface{}]interface{}{ - "grpc": map[interface{}]interface{}{}, - "http": map[interface{}]interface{}{}, + builder := NewSkywalkingReceiverParser(logger, "skywalking", map[string]interface{}{ + "protocols": map[string]interface{}{ + "grpc": map[string]interface{}{}, + "http": map[string]interface{}{}, }, }) diff --git a/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go b/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go index 676415334b..38a7b548ce 100644 --- a/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go +++ b/internal/manifests/collector/parser/receiver/receiver_splunk-hec.go @@ -23,7 +23,7 @@ import ( const parserNameSplunkHec = "__splunk_hec" // NewSplunkHecReceiverParser builds a new parser for Splunk Hec receivers, from the contrib repository. -func NewSplunkHecReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewSplunkHecReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_statsd.go b/internal/manifests/collector/parser/receiver/receiver_statsd.go index 0f41520e22..c85818bfc4 100644 --- a/internal/manifests/collector/parser/receiver/receiver_statsd.go +++ b/internal/manifests/collector/parser/receiver/receiver_statsd.go @@ -24,7 +24,7 @@ import ( const parserNameStatsd = "__statsd" // NewStatsdReceiverParser builds a new parser for Statsd receivers, from the contrib repository. -func NewStatsdReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewStatsdReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_test.go b/internal/manifests/collector/parser/receiver/receiver_test.go index 44cb04519d..416c56149b 100644 --- a/internal/manifests/collector/parser/receiver/receiver_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_test.go @@ -91,7 +91,7 @@ func TestReceiverParsePortFromEndpoint(t *testing.T) { func TestReceiverFailsWhenPortIsntString(t *testing.T) { // prepare - config := map[interface{}]interface{}{ + config := map[string]interface{}{ "endpoint": 123, } @@ -105,7 +105,7 @@ func TestReceiverFailsWhenPortIsntString(t *testing.T) { func TestIgnorekubeletstatsEndpoint(t *testing.T) { // ignore "kubeletstats" receiver endpoint field, this is special case // as this receiver gets parsed by generic receiver parser - builder := NewGenericReceiverParser(logger, "kubeletstats", map[interface{}]interface{}{ + builder := NewGenericReceiverParser(logger, "kubeletstats", map[string]interface{}{ "endpoint": "0.0.0.0:9000", }) @@ -119,7 +119,7 @@ func TestIgnorekubeletstatsEndpoint(t *testing.T) { func TestReceiverFallbackWhenNotRegistered(t *testing.T) { // test - p, err := For(logger, "myreceiver", map[interface{}]interface{}{}) + p, err := For(logger, "myreceiver", map[string]interface{}{}) assert.NoError(t, err) // test @@ -129,13 +129,13 @@ func TestReceiverFallbackWhenNotRegistered(t *testing.T) { func TestReceiverShouldFindRegisteredParser(t *testing.T) { // prepare builderCalled := false - Register("mock", func(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { + Register("mock", func(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { builderCalled = true return &mockParser{} }) // test - _, _ = For(logger, "mock", map[interface{}]interface{}{}) + _, _ = For(logger, "mock", map[string]interface{}{}) // verify assert.True(t, builderCalled) @@ -154,7 +154,7 @@ func (m *mockParser) ParserName() string { func TestSkipPortsForScrapers(t *testing.T) { for receiver := range scraperReceivers { - builder := NewGenericReceiverParser(logger, receiver, map[interface{}]interface{}{ + builder := NewGenericReceiverParser(logger, receiver, map[string]interface{}{ "endpoint": "0.0.0.0:42069", }) ports, err := builder.Ports() diff --git a/internal/manifests/collector/parser/receiver/receiver_wavefront.go b/internal/manifests/collector/parser/receiver/receiver_wavefront.go index f2eafb8556..8e7498047d 100644 --- a/internal/manifests/collector/parser/receiver/receiver_wavefront.go +++ b/internal/manifests/collector/parser/receiver/receiver_wavefront.go @@ -23,7 +23,7 @@ import ( const parserNameWavefront = "__wavefront" // NewWavefrontReceiverParser builds a new parser for Wavefront receivers, from the contrib repository. -func NewWavefrontReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewWavefrontReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go index 8f8d9fe210..d57d6d3cd0 100644 --- a/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin-scribe.go @@ -23,7 +23,7 @@ import ( const parserNameZipkinScribe = "__zipkinscribe" // NewZipkinScribeReceiverParser builds a new parser for ZipkinScribe receivers. -func NewZipkinScribeReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewZipkinScribeReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &GenericReceiver{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_zipkin.go b/internal/manifests/collector/parser/receiver/receiver_zipkin.go index debbf8e9a4..81ddae4f45 100644 --- a/internal/manifests/collector/parser/receiver/receiver_zipkin.go +++ b/internal/manifests/collector/parser/receiver/receiver_zipkin.go @@ -24,7 +24,7 @@ import ( const parserNameZipkin = "__zipkin" // NewZipkinReceiverParser builds a new parser for Zipkin receivers. -func NewZipkinReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewZipkinReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { http := "http" return &GenericReceiver{ logger: logger, diff --git a/internal/manifests/collector/podmonitor.go b/internal/manifests/collector/podmonitor.go index f51c7c95b1..fd790448ad 100644 --- a/internal/manifests/collector/podmonitor.go +++ b/internal/manifests/collector/podmonitor.go @@ -24,7 +24,6 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -78,18 +77,7 @@ func PodMonitor(params manifests.Params) (*monitoringv1.PodMonitor, error) { } func metricsEndpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemetryCollector) []monitoringv1.PodMetricsEndpoint { - // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 - cfgStr, err := otelcol.Spec.Config.Yaml() - if err != nil { - logger.V(2).Error(err, "Error while marshaling to YAML") - return []monitoringv1.PodMetricsEndpoint{} - } - config, err := adapters.ConfigFromString(cfgStr) - if err != nil { - logger.V(2).Error(err, "Error while parsing the configuration") - return []monitoringv1.PodMetricsEndpoint{} - } - exporterPorts, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeExporter, config) + exporterPorts, err := otelcol.Spec.Config.Exporters.Ports(logger) if err != nil { logger.Error(err, "couldn't build endpoints to podMonitors from configuration") return []monitoringv1.PodMetricsEndpoint{} diff --git a/internal/manifests/collector/rbac.go b/internal/manifests/collector/rbac.go index 4af9223996..64cacc13c0 100644 --- a/internal/manifests/collector/rbac.go +++ b/internal/manifests/collector/rbac.go @@ -25,17 +25,7 @@ import ( ) func ClusterRole(params manifests.Params) (*rbacv1.ClusterRole, error) { - confStr, err := params.OtelCol.Spec.Config.Yaml() - if err != nil { - return nil, err - } - - configFromString, err := adapters.ConfigFromString(confStr) - if err != nil { - params.Log.Error(err, "couldn't extract the configuration from the context") - return nil, nil - } - rules := adapters.ConfigToRBAC(params.Log, configFromString) + rules := adapters.ConfigToRBAC(params.Log, params.OtelCol.Spec.Config) if len(rules) == 0 { return nil, nil @@ -55,16 +45,7 @@ func ClusterRole(params manifests.Params) (*rbacv1.ClusterRole, error) { } func ClusterRoleBinding(params manifests.Params) (*rbacv1.ClusterRoleBinding, error) { - confStr, err := params.OtelCol.Spec.Config.Yaml() - if err != nil { - return nil, err - } - configFromString, err := adapters.ConfigFromString(confStr) - if err != nil { - params.Log.Error(err, "couldn't extract the configuration from the context") - return nil, nil - } - rules := adapters.ConfigToRBAC(params.Log, configFromString) + rules := adapters.ConfigToRBAC(params.Log, params.OtelCol.Spec.Config) if len(rules) == 0 { return nil, nil diff --git a/internal/manifests/collector/service.go b/internal/manifests/collector/service.go index 729bde46f5..a90df5c751 100644 --- a/internal/manifests/collector/service.go +++ b/internal/manifests/collector/service.go @@ -61,19 +61,7 @@ func MonitoringService(params manifests.Params) (*corev1.Service, error) { name := naming.MonitoringService(params.OtelCol.Name) labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) - - out, err := params.OtelCol.Spec.Config.Yaml() - if err != nil { - return nil, err - } - - c, err := adapters.ConfigFromString(out) - if err != nil { - params.Log.Error(err, "couldn't extract the configuration") - return nil, err - } - - metricsPort, err := adapters.ConfigToMetricsPort(params.Log, c) + metricsPort, err := adapters.ConfigToMetricsPort(params.OtelCol.Spec.Config.Service) if err != nil { return nil, err } @@ -99,18 +87,6 @@ func MonitoringService(params manifests.Params) (*corev1.Service, error) { func Service(params manifests.Params) (*corev1.Service, error) { name := naming.Service(params.OtelCol.Name) labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) - - out, err := params.OtelCol.Spec.Config.Yaml() - if err != nil { - return nil, err - } - - configFromString, err := adapters.ConfigFromString(out) - if err != nil { - params.Log.Error(err, "couldn't extract the configuration from the context") - return nil, err - } - ports, err := adapters.ConfigToPorts(params.Log, params.OtelCol.Spec.Config) if err != nil { return nil, err diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index 02496e7898..6037ad36d7 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -24,7 +24,6 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" - "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -74,19 +73,7 @@ func ServiceMonitor(params manifests.Params) (*monitoringv1.ServiceMonitor, erro } func endpointsFromConfig(logger logr.Logger, otelcol v1alpha2.OpenTelemetryCollector) []monitoringv1.Endpoint { - // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 - cfgStr, err := otelcol.Spec.Config.Yaml() - if err != nil { - logger.V(2).Error(err, "Error while marshaling to YAML") - return []monitoringv1.Endpoint{} - } - c, err := adapters.ConfigFromString(cfgStr) - if err != nil { - logger.V(2).Error(err, "Error while parsing the configuration") - return []monitoringv1.Endpoint{} - } - - exporterPorts, err := adapters.ConfigToComponentPorts(logger, adapters.ComponentTypeExporter, c) + exporterPorts, err := otelcol.Spec.Config.Exporters.Ports(logger) if err != nil { logger.Error(err, "couldn't build service monitors from configuration") return []monitoringv1.Endpoint{} From 6c0b5e9232caa3e4cc00c67970b336c688590b97 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Thu, 7 Mar 2024 13:30:41 -0500 Subject: [PATCH 6/6] working tests --- apis/v1alpha1/collector_webhook.go | 45 ++++++++++--------- apis/v1beta1/config.go | 21 ++++++++- apis/v1beta1/config_test.go | 8 ++-- apis/v1beta1/zz_generated.deepcopy.go | 3 +- .../collector/adapters/config_to_ports.go | 17 ++++--- .../adapters/config_to_ports_test.go | 26 ++++++----- internal/manifests/collector/ingress.go | 3 +- .../parser/exporter/exporter_test.go | 4 +- internal/manifests/collector/parser/parser.go | 4 +- .../parser/receiver/receiver_syslog.go | 10 ++--- .../parser/receiver/receiver_syslog_test.go | 10 ++--- .../parser/receiver/receiver_tcplog.go | 4 +- .../parser/receiver/receiver_tcplog_test.go | 8 ++-- .../parser/receiver/receiver_udplog.go | 4 +- .../parser/receiver/receiver_udplog_test.go | 8 ++-- internal/manifests/collector/podmonitor.go | 3 +- internal/manifests/collector/service_test.go | 2 +- .../manifests/collector/servicemonitor.go | 3 +- 18 files changed, 108 insertions(+), 75 deletions(-) diff --git a/apis/v1alpha1/collector_webhook.go b/apis/v1alpha1/collector_webhook.go index f5ea9d435f..bf5b7ad183 100644 --- a/apis/v1alpha1/collector_webhook.go +++ b/apis/v1alpha1/collector_webhook.go @@ -30,7 +30,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook/admission" "github.com/open-telemetry/opentelemetry-operator/internal/config" + ta "github.com/open-telemetry/opentelemetry-operator/internal/manifests/targetallocator/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/rbac" + "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate" ) var ( @@ -357,28 +359,27 @@ func (c CollectorWebhook) validateTargetAllocatorConfig(ctx context.Context, r * if r.Spec.TargetAllocator.AllocationStrategy == OpenTelemetryTargetAllocatorAllocationStrategyPerNode && r.Spec.Mode != ModeDaemonSet { return nil, fmt.Errorf("target allocation strategy %s is only supported in OpenTelemetry Collector mode %s", OpenTelemetryTargetAllocatorAllocationStrategyPerNode, ModeDaemonSet) } - // TODO: Fix cycle - //// validate Prometheus config for target allocation - //promCfg, err := ta.ConfigToPromConfig(r.Spec.Config) - //if err != nil { - // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - //} - //err = ta.ValidatePromConfig(promCfg, r.Spec.TargetAllocator.Enabled, featuregate.EnableTargetAllocatorRewrite.IsEnabled()) - //if err != nil { - // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - //} - //err = ta.ValidateTargetAllocatorConfig(r.Spec.TargetAllocator.PrometheusCR.Enabled, promCfg) - //if err != nil { - // return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) - //} - //// if the prometheusCR is enabled, it needs a suite of permissions to function - //if r.Spec.TargetAllocator.PrometheusCR.Enabled { - // if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.GetNamespace(), r.Spec.TargetAllocator.ServiceAccount, targetAllocatorCRPolicyRules...); err != nil { - // return nil, fmt.Errorf("unable to check rbac rules %w", err) - // } else if allowed, deniedReviews := rbac.AllSubjectAccessReviewsAllowed(subjectAccessReviews); !allowed { - // return warningsGroupedByResource(deniedReviews), nil - // } - //} + // validate Prometheus config for target allocation + promCfg, err := ta.ConfigToPromConfig(r.Spec.Config) + if err != nil { + return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + } + err = ta.ValidatePromConfig(promCfg, r.Spec.TargetAllocator.Enabled, featuregate.EnableTargetAllocatorRewrite.IsEnabled()) + if err != nil { + return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + } + err = ta.ValidateTargetAllocatorConfig(r.Spec.TargetAllocator.PrometheusCR.Enabled, promCfg) + if err != nil { + return nil, fmt.Errorf("the OpenTelemetry Spec Prometheus configuration is incorrect, %w", err) + } + // if the prometheusCR is enabled, it needs a suite of permissions to function + if r.Spec.TargetAllocator.PrometheusCR.Enabled { + if subjectAccessReviews, err := c.reviewer.CheckPolicyRules(ctx, r.GetNamespace(), r.Spec.TargetAllocator.ServiceAccount, targetAllocatorCRPolicyRules...); err != nil { + return nil, fmt.Errorf("unable to check rbac rules %w", err) + } else if allowed, deniedReviews := rbac.AllSubjectAccessReviewsAllowed(subjectAccessReviews); !allowed { + return warningsGroupedByResource(deniedReviews), nil + } + } return nil, nil } diff --git a/apis/v1beta1/config.go b/apis/v1beta1/config.go index e644cdb72d..982b69a81d 100644 --- a/apis/v1beta1/config.go +++ b/apis/v1beta1/config.go @@ -124,11 +124,30 @@ type Telemetry struct { type Service struct { Extensions []string `json:"extensions,omitempty" yaml:"extensions,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Telemetry *Telemetry `json:"telemetry,omitempty" yaml:"telemetry,omitempty"` + Telemetry *AnyConfig `json:"telemetry,omitempty" yaml:"telemetry,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields Pipelines AnyConfig `json:"pipelines" yaml:"pipelines"` } +// GetTelemetry serves as a helper function to access the fields we care about in the underlying telemetry struct. +// This exists to avoid needing to worry extra fields in the telemetry struct. +func (s *Service) GetTelemetry() *Telemetry { + if s.Telemetry == nil { + return nil + } + // Convert map to JSON bytes + jsonData, err := json.Marshal(s.Telemetry) + if err != nil { + return nil + } + t := &Telemetry{} + // Unmarshal JSON into the provided struct + if err := json.Unmarshal(jsonData, t); err != nil { + return nil + } + return t +} + // Returns null objects in the config. func (c Config) nullObjects() []string { var nullKeys []string diff --git a/apis/v1beta1/config_test.go b/apis/v1beta1/config_test.go index 30e8f363ec..bb87b39b25 100644 --- a/apis/v1beta1/config_test.go +++ b/apis/v1beta1/config_test.go @@ -140,9 +140,11 @@ func TestConfigYaml(t *testing.T) { }, Service: Service{ Extensions: []string{"addon"}, - Telemetry: &Telemetry{ - Metrics: MetricsConfig{ - Address: "0.0.0.0:9000", + Telemetry: &AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "address": "0.0.0.0:9000", + }, }, }, Pipelines: AnyConfig{ diff --git a/apis/v1beta1/zz_generated.deepcopy.go b/apis/v1beta1/zz_generated.deepcopy.go index 94279c7606..5e36bd9666 100644 --- a/apis/v1beta1/zz_generated.deepcopy.go +++ b/apis/v1beta1/zz_generated.deepcopy.go @@ -585,8 +585,7 @@ func (in *Service) DeepCopyInto(out *Service) { } if in.Telemetry != nil { in, out := &in.Telemetry, &out.Telemetry - *out = new(Telemetry) - (*in).DeepCopyInto(*out) + *out = (*in).DeepCopy() } in.Pipelines.DeepCopyInto(&out.Pipelines) } diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index c0704bec6b..feb66204c1 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -43,15 +43,15 @@ func (c ComponentType) String() string { func PortsForExporters(l logr.Logger, c v1beta1.Config) ([]corev1.ServicePort, error) { compEnabled := getEnabledComponents(c.Service, ComponentTypeExporter) - return componentPorts(l, c.Exporters, exporterParser.BuilderFor, compEnabled) + return componentPorts(l, c.Exporters, exporterParser.For, compEnabled) } func PortsForReceivers(l logr.Logger, c v1beta1.Config) ([]corev1.ServicePort, error) { compEnabled := getEnabledComponents(c.Service, ComponentTypeReceiver) - return componentPorts(l, c.Receivers, receiverParser.BuilderFor, compEnabled) + return componentPorts(l, c.Receivers, receiverParser.For, compEnabled) } -func componentPorts(l logr.Logger, c v1beta1.AnyConfig, p parser.BuilderFor, enabledComponents map[string]bool) ([]corev1.ServicePort, error) { +func componentPorts(l logr.Logger, c v1beta1.AnyConfig, p parser.For, enabledComponents map[string]bool) ([]corev1.ServicePort, error) { var ports []corev1.ServicePort for cmptName, val := range c.Object { if !enabledComponents[cmptName] { @@ -61,8 +61,11 @@ func componentPorts(l logr.Logger, c v1beta1.AnyConfig, p parser.BuilderFor, ena if !ok { component = map[string]interface{}{} } - builder := p(cmptName) - componentParser := builder(l, cmptName, component) + componentParser, err := p(l, cmptName, component) + if err != nil { + l.V(2).Info("no parser found for '%s'", cmptName) + continue + } componentPorts, err := componentParser.Ports() if err != nil { l.Error(err, "parser for '%s' has returned an error: %w", cmptName, err) @@ -101,11 +104,11 @@ func ConfigToPorts(logger logr.Logger, config v1beta1.Config) ([]corev1.ServiceP // ConfigToMetricsPort gets the port number for the metrics endpoint from the collector config if it has been set. func ConfigToMetricsPort(config v1beta1.Service) (int32, error) { - if config.Telemetry == nil { + if config.GetTelemetry() == nil { // telemetry isn't set, use the default return 8888, nil } - _, port, netErr := net.SplitHostPort(config.Telemetry.Metrics.Address) + _, port, netErr := net.SplitHostPort(config.GetTelemetry().Metrics.Address) if netErr != nil && strings.Contains(netErr.Error(), "missing port in address") { return 8888, nil } else if netErr != nil { diff --git a/internal/manifests/collector/adapters/config_to_ports_test.go b/internal/manifests/collector/adapters/config_to_ports_test.go index 3896e2fa4e..cd34df29b3 100644 --- a/internal/manifests/collector/adapters/config_to_ports_test.go +++ b/internal/manifests/collector/adapters/config_to_ports_test.go @@ -185,9 +185,11 @@ func TestParserFailed(t *testing.T) { func TestConfigToMetricsPort(t *testing.T) { t.Run("custom port specified", func(t *testing.T) { config := v1beta1.Service{ - Telemetry: &v1beta1.Telemetry{ - Metrics: v1beta1.MetricsConfig{ - Address: "0.0.0.0:9090", + Telemetry: &v1beta1.AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "address": "0.0.0.0:9090", + }, }, }, } @@ -204,9 +206,11 @@ func TestConfigToMetricsPort(t *testing.T) { { "bad address", v1beta1.Service{ - Telemetry: &v1beta1.Telemetry{ - Metrics: v1beta1.MetricsConfig{ - Address: "0.0.0.0", + Telemetry: &v1beta1.AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "address": "0.0.0.0", + }, }, }, }, @@ -214,9 +218,11 @@ func TestConfigToMetricsPort(t *testing.T) { { "missing address", v1beta1.Service{ - Telemetry: &v1beta1.Telemetry{ - Metrics: v1beta1.MetricsConfig{ - Level: "detailed", + Telemetry: &v1beta1.AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "level": "detailed", + }, }, }, }, @@ -224,7 +230,7 @@ func TestConfigToMetricsPort(t *testing.T) { { "missing metrics", v1beta1.Service{ - Telemetry: &v1beta1.Telemetry{}, + Telemetry: &v1beta1.AnyConfig{}, }, }, { diff --git a/internal/manifests/collector/ingress.go b/internal/manifests/collector/ingress.go index ea2e9fb77b..c57f08aa80 100644 --- a/internal/manifests/collector/ingress.go +++ b/internal/manifests/collector/ingress.go @@ -24,6 +24,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -135,7 +136,7 @@ func createSubdomainIngressRules(otelcol string, hostname string, ports []corev1 } func servicePortsFromCfg(logger logr.Logger, otelcol v1beta1.OpenTelemetryCollector) ([]corev1.ServicePort, error) { - ports, err := otelcol.Spec.Config.Receivers.Ports(logger) + ports, err := adapters.PortsForReceivers(logger, otelcol.Spec.Config) if err != nil { logger.Error(err, "couldn't build the ingress for this instance") return nil, err diff --git a/internal/manifests/collector/parser/exporter/exporter_test.go b/internal/manifests/collector/parser/exporter/exporter_test.go index e022160784..bb84631417 100644 --- a/internal/manifests/collector/parser/exporter/exporter_test.go +++ b/internal/manifests/collector/parser/exporter/exporter_test.go @@ -33,7 +33,7 @@ func TestPorts(t *testing.T) { testName: "Valid Configuration", parser: &PrometheusExporterParser{ name: "test-exporter", - config: map[interface{}]interface{}{ + config: map[string]interface{}{ "endpoint": "http://myprometheus.io:9090", }, }, @@ -63,7 +63,7 @@ func TestPorts(t *testing.T) { testName: "Invalid Endpoint No Port", parser: &PrometheusExporterParser{ name: "test-exporter", - config: map[interface{}]interface{}{ + config: map[string]interface{}{ "endpoint": "invalidendpoint", }, }, diff --git a/internal/manifests/collector/parser/parser.go b/internal/manifests/collector/parser/parser.go index e7a1acd253..3cf9f69b7d 100644 --- a/internal/manifests/collector/parser/parser.go +++ b/internal/manifests/collector/parser/parser.go @@ -30,5 +30,5 @@ type ComponentPortParser interface { // Builder specifies the signature required for parser builders. type Builder func(logr.Logger, string, map[string]interface{}) ComponentPortParser -// BuilderFor returns a builder for a given component -type BuilderFor func(component string) Builder +// For returns a builder for a given component if found, otherwise it returns an error +type For func(logger logr.Logger, name string, config map[string]interface{}) (ComponentPortParser, error) diff --git a/internal/manifests/collector/parser/receiver/receiver_syslog.go b/internal/manifests/collector/parser/receiver/receiver_syslog.go index 582cb5c2be..5745526717 100644 --- a/internal/manifests/collector/parser/receiver/receiver_syslog.go +++ b/internal/manifests/collector/parser/receiver/receiver_syslog.go @@ -30,13 +30,13 @@ const parserNameSyslog = "__syslog" // SyslogReceiverParser parses the configuration for TCP log receivers. type SyslogReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewSyslogReceiverParser builds a new parser for TCP log receivers. -func NewSyslogReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewSyslogReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &SyslogReceiverParser{ logger: logger, name: name, @@ -48,19 +48,19 @@ func (o *SyslogReceiverParser) Ports() ([]corev1.ServicePort, error) { var endpoint interface{} var endpointName string var protocol corev1.Protocol - var c map[interface{}]interface{} + var c map[string]interface{} // syslog receiver contains the endpoint // that needs to be exposed one level down inside config // i.e. either in tcp or udp section with field key // as `listen_address` if tcp, isTCP := o.config["tcp"]; isTCP && tcp != nil { - c = tcp.(map[interface{}]interface{}) + c = tcp.(map[string]interface{}) endpointName = "tcp" endpoint = getAddressFromConfig(o.logger, o.name, listenAddressKey, c) protocol = corev1.ProtocolTCP } else if udp, isUDP := o.config["udp"]; isUDP && udp != nil { - c = udp.(map[interface{}]interface{}) + c = udp.(map[string]interface{}) endpointName = "udp" endpoint = getAddressFromConfig(o.logger, o.name, listenAddressKey, c) protocol = corev1.ProtocolUDP diff --git a/internal/manifests/collector/parser/receiver/receiver_syslog_test.go b/internal/manifests/collector/parser/receiver/receiver_syslog_test.go index fd7ea9daf5..2d2f534d91 100644 --- a/internal/manifests/collector/parser/receiver/receiver_syslog_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_syslog_test.go @@ -28,7 +28,7 @@ func TestSyslogSelfRegisters(t *testing.T) { func TestSyslogIsFoundByName(t *testing.T) { // test - p, err := For(logger, "syslog", map[interface{}]interface{}{}) + p, err := For(logger, "syslog", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -38,15 +38,15 @@ func TestSyslogIsFoundByName(t *testing.T) { func TestSyslogConfiguration(t *testing.T) { for _, tt := range []struct { desc string - config map[interface{}]interface{} + config map[string]interface{} expected []corev1.ServicePort }{ - {"Empty configuration", map[interface{}]interface{}{}, []corev1.ServicePort{}}, + {"Empty configuration", map[string]interface{}{}, []corev1.ServicePort{}}, {"UDP port configuration", - map[interface{}]interface{}{"udp": map[interface{}]interface{}{"listen_address": "0.0.0.0:1234"}}, + map[string]interface{}{"udp": map[string]interface{}{"listen_address": "0.0.0.0:1234"}}, []corev1.ServicePort{{Name: "syslog", Port: 1234, Protocol: corev1.ProtocolUDP}}}, {"TCP port configuration", - map[interface{}]interface{}{"tcp": map[interface{}]interface{}{"listen_address": "0.0.0.0:1234"}}, + map[string]interface{}{"tcp": map[string]interface{}{"listen_address": "0.0.0.0:1234"}}, []corev1.ServicePort{{Name: "syslog", Port: 1234, Protocol: corev1.ProtocolTCP}}}, } { t.Run(tt.desc, func(t *testing.T) { diff --git a/internal/manifests/collector/parser/receiver/receiver_tcplog.go b/internal/manifests/collector/parser/receiver/receiver_tcplog.go index c0232415a9..c749805bc8 100644 --- a/internal/manifests/collector/parser/receiver/receiver_tcplog.go +++ b/internal/manifests/collector/parser/receiver/receiver_tcplog.go @@ -30,13 +30,13 @@ const parserNameTcpLog = "__tcplog" // TcpLogReceiverParser parses the configuration for TCP log receivers. type TcpLogReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewTcpLogReceiverParser builds a new parser for TCP log receivers. -func NewTcpLogReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewTcpLogReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &TcpLogReceiverParser{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_tcplog_test.go b/internal/manifests/collector/parser/receiver/receiver_tcplog_test.go index 04b4eb03be..25e07c6668 100644 --- a/internal/manifests/collector/parser/receiver/receiver_tcplog_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_tcplog_test.go @@ -28,7 +28,7 @@ func TestTcpLogSelfRegisters(t *testing.T) { func TestTcpLogIsFoundByName(t *testing.T) { // test - p, err := For(logger, "tcplog", map[interface{}]interface{}{}) + p, err := For(logger, "tcplog", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -38,12 +38,12 @@ func TestTcpLogIsFoundByName(t *testing.T) { func TestTcpLogConfiguration(t *testing.T) { for _, tt := range []struct { desc string - config map[interface{}]interface{} + config map[string]interface{} expected []corev1.ServicePort }{ - {"Empty configuration", map[interface{}]interface{}{}, []corev1.ServicePort{}}, + {"Empty configuration", map[string]interface{}{}, []corev1.ServicePort{}}, {"TCP port configuration", - map[interface{}]interface{}{"listen_address": "0.0.0.0:1234"}, + map[string]interface{}{"listen_address": "0.0.0.0:1234"}, []corev1.ServicePort{{Name: "tcplog", Port: 1234, Protocol: corev1.ProtocolTCP}}}, } { t.Run(tt.desc, func(t *testing.T) { diff --git a/internal/manifests/collector/parser/receiver/receiver_udplog.go b/internal/manifests/collector/parser/receiver/receiver_udplog.go index 4f55e5b492..143f8df689 100644 --- a/internal/manifests/collector/parser/receiver/receiver_udplog.go +++ b/internal/manifests/collector/parser/receiver/receiver_udplog.go @@ -30,13 +30,13 @@ const parserNameUdpLog = "__udplog" // UdpLogReceiverParser parses the configuration for UDP log receivers. type UdpLogReceiverParser struct { - config map[interface{}]interface{} + config map[string]interface{} logger logr.Logger name string } // NewUdpLogReceiverParser builds a new parser for UDP log receivers. -func NewUdpLogReceiverParser(logger logr.Logger, name string, config map[interface{}]interface{}) parser.ComponentPortParser { +func NewUdpLogReceiverParser(logger logr.Logger, name string, config map[string]interface{}) parser.ComponentPortParser { return &UdpLogReceiverParser{ logger: logger, name: name, diff --git a/internal/manifests/collector/parser/receiver/receiver_udplog_test.go b/internal/manifests/collector/parser/receiver/receiver_udplog_test.go index 1b12191ed5..7c52520df2 100644 --- a/internal/manifests/collector/parser/receiver/receiver_udplog_test.go +++ b/internal/manifests/collector/parser/receiver/receiver_udplog_test.go @@ -28,7 +28,7 @@ func TestUdpLogSelfRegisters(t *testing.T) { func TestUdpLogIsFoundByName(t *testing.T) { // test - p, err := For(logger, "udplog", map[interface{}]interface{}{}) + p, err := For(logger, "udplog", map[string]interface{}{}) assert.NoError(t, err) // verify @@ -38,12 +38,12 @@ func TestUdpLogIsFoundByName(t *testing.T) { func TestUdpLogConfiguration(t *testing.T) { for _, tt := range []struct { desc string - config map[interface{}]interface{} + config map[string]interface{} expected []corev1.ServicePort }{ - {"Empty configuration", map[interface{}]interface{}{}, []corev1.ServicePort{}}, + {"Empty configuration", map[string]interface{}{}, []corev1.ServicePort{}}, {"UDP port configuration", - map[interface{}]interface{}{"listen_address": "0.0.0.0:1234"}, + map[string]interface{}{"listen_address": "0.0.0.0:1234"}, []corev1.ServicePort{{Name: "udplog", Port: 1234, Protocol: corev1.ProtocolUDP}}}, } { t.Run(tt.desc, func(t *testing.T) { diff --git a/internal/manifests/collector/podmonitor.go b/internal/manifests/collector/podmonitor.go index b7dd1a8721..95fff8d285 100644 --- a/internal/manifests/collector/podmonitor.go +++ b/internal/manifests/collector/podmonitor.go @@ -24,6 +24,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -77,7 +78,7 @@ func PodMonitor(params manifests.Params) (*monitoringv1.PodMonitor, error) { } func metricsEndpointsFromConfig(logger logr.Logger, otelcol v1beta1.OpenTelemetryCollector) []monitoringv1.PodMetricsEndpoint { - exporterPorts, err := otelcol.Spec.Config.Exporters.Ports(logger) + exporterPorts, err := adapters.PortsForExporters(logger, otelcol.Spec.Config) if err != nil { logger.Error(err, "couldn't build endpoints to podMonitors from configuration") return []monitoringv1.PodMetricsEndpoint{} diff --git a/internal/manifests/collector/service_test.go b/internal/manifests/collector/service_test.go index 0498a071a8..9ab6531238 100644 --- a/internal/manifests/collector/service_test.go +++ b/internal/manifests/collector/service_test.go @@ -261,8 +261,8 @@ func TestMonitoringService(t *testing.T) { Telemetry: &v1beta1.AnyConfig{ Object: map[string]interface{}{ "metrics": map[string]interface{}{ - "level": "detailed", "address": "0.0.0.0:9090", + "level": "detailed", }, }, }, diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index 4eb60410b9..88fe390a05 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -24,6 +24,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/apis/v1beta1" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" + "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector/adapters" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -73,7 +74,7 @@ func ServiceMonitor(params manifests.Params) (*monitoringv1.ServiceMonitor, erro } func endpointsFromConfig(logger logr.Logger, otelcol v1beta1.OpenTelemetryCollector) []monitoringv1.Endpoint { - exporterPorts, err := otelcol.Spec.Config.Exporters.Ports(logger) + exporterPorts, err := adapters.PortsForExporters(logger, otelcol.Spec.Config) if err != nil { logger.Error(err, "couldn't build service monitors from configuration") return []monitoringv1.Endpoint{}