diff --git a/apis/v1alpha2/allocation_strategy.go b/apis/v1alpha2/allocation_strategy.go index cc1ac4c1e8..9b710920de 100644 --- a/apis/v1alpha2/allocation_strategy.go +++ b/apis/v1alpha2/allocation_strategy.go @@ -31,5 +31,5 @@ const ( TargetAllocatorAllocationStrategyConsistentHashing TargetAllocatorAllocationStrategy = "consistent-hashing" // TargetAllocatorFilterStrategyRelabelConfig targets will be consistently drops targets based on the relabel_config. - TargetAllocatorFilterStrategyRelabelConfig TargetAllocatorFilterStrategy = "consistent-hashing" + TargetAllocatorFilterStrategyRelabelConfig TargetAllocatorFilterStrategy = "relabel-config" ) diff --git a/apis/v1alpha2/opentelemetrycollector_types.go b/apis/v1alpha2/opentelemetrycollector_types.go index 74d844da1b..3521afcdaf 100644 --- a/apis/v1alpha2/opentelemetrycollector_types.go +++ b/apis/v1alpha2/opentelemetrycollector_types.go @@ -18,6 +18,7 @@ package v1alpha2 import ( appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -120,7 +121,7 @@ type OpenTelemetryCollectorSpec struct { OpenTelemetryCommonFields `json:",inline"` // TargetAllocator indicates a value which determines whether to spawn a target allocation resource or not. // +optional - TargetAllocator v1alpha1.OpenTelemetryTargetAllocator `json:"targetAllocator,omitempty"` + TargetAllocator TargetAllocatorEmbedded `json:"targetAllocator,omitempty"` // Mode represents how the collector should be deployed (deployment, daemonset, statefulset or sidecar) // +optional Mode Mode `json:"mode,omitempty"` @@ -165,6 +166,84 @@ type OpenTelemetryCollectorSpec struct { DeploymentUpdateStrategy appsv1.DeploymentStrategy `json:"deploymentUpdateStrategy,omitempty"` } +// TargetAllocatorEmbedded defines the configuration for the Prometheus target allocator, embedded in the +// OpenTelemetryCollector spec. +type TargetAllocatorEmbedded struct { + // Replicas is the number of pod instances for the underlying TargetAllocator. This should only be set to a value + // other than 1 if a strategy that allows for high availability is chosen. Currently, the only allocation strategy + // that can be run in a high availability mode is consistent-hashing. + // +optional + Replicas *int32 `json:"replicas,omitempty"` + // NodeSelector to schedule OpenTelemetry TargetAllocator pods. + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // Resources to set on the OpenTelemetryTargetAllocator containers. + // +optional + Resources v1.ResourceRequirements `json:"resources,omitempty"` + // AllocationStrategy determines which strategy the target allocator should use for allocation. + // The current options are least-weighted, consistent-hashing and per-node. The default is + // consistent-hashing. + // +optional + // +kubebuilder:default:=consistent-hashing + AllocationStrategy TargetAllocatorAllocationStrategy `json:"allocationStrategy,omitempty"` + // FilterStrategy determines how to filter targets before allocating them among the collectors. + // The only current option is relabel-config (drops targets based on prom relabel_config). + // The default is relabel-config. + // +optional + // +kubebuilder:default:=relabel-config + FilterStrategy TargetAllocatorFilterStrategy `json:"filterStrategy,omitempty"` + // ServiceAccount indicates the name of an existing service account to use with this instance. When set, + // the operator will not automatically create a ServiceAccount for the TargetAllocator. + // +optional + ServiceAccount string `json:"serviceAccount,omitempty"` + // Image indicates the container image to use for the OpenTelemetry TargetAllocator. + // +optional + Image string `json:"image,omitempty"` + // Enabled indicates whether to use a target allocation mechanism for Prometheus targets or not. + // +optional + Enabled bool `json:"enabled,omitempty"` + // If specified, indicates the pod's scheduling constraints + // +optional + Affinity *v1.Affinity `json:"affinity,omitempty"` + // PrometheusCR defines the configuration for the retrieval of PrometheusOperator CRDs ( servicemonitor.monitoring.coreos.com/v1 and podmonitor.monitoring.coreos.com/v1 ) retrieval. + // All CR instances which the ServiceAccount has access to will be retrieved. This includes other namespaces. + // +optional + PrometheusCR TargetAllocatorPrometheusCR `json:"prometheusCR,omitempty"` + // SecurityContext configures the container security context for + // the targetallocator. + // +optional + SecurityContext *v1.SecurityContext `json:"securityContext,omitempty"` + // PodSecurityContext configures the pod security context for the + // targetallocator. + // +optional + PodSecurityContext *v1.PodSecurityContext `json:"podSecurityContext,omitempty"` + // TopologySpreadConstraints embedded kubernetes pod configuration option, + // controls how pods are spread across your cluster among failure-domains + // such as regions, zones, nodes, and other user-defined topology domains + // https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + // +optional + TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"` + // Toleration embedded kubernetes pod configuration option, + // controls how pods can be scheduled with matching taints + // +optional + Tolerations []v1.Toleration `json:"tolerations,omitempty"` + // ENV vars to set on the OpenTelemetry TargetAllocator's Pods. These can then in certain cases be + // consumed in the config file for the TargetAllocator. + // +optional + Env []v1.EnvVar `json:"env,omitempty"` + // ObservabilitySpec defines how telemetry data gets handled. + // + // +optional + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Observability" + Observability v1alpha1.ObservabilitySpec `json:"observability,omitempty"` + // PodDisruptionBudget specifies the pod disruption budget configuration to use + // for the target allocator workload. + // + // +optional + PodDisruptionBudget *PodDisruptionBudgetSpec `json:"podDisruptionBudget,omitempty"` +} + // OpenTelemetryCollectorStatus defines the observed state of OpenTelemetryCollector. type OpenTelemetryCollectorStatus struct { // Scale is the OpenTelemetryCollector's scale subresource status. diff --git a/apis/v1alpha2/zz_generated.deepcopy.go b/apis/v1alpha2/zz_generated.deepcopy.go index afa8717bbd..3ceafb521c 100644 --- a/apis/v1alpha2/zz_generated.deepcopy.go +++ b/apis/v1alpha2/zz_generated.deepcopy.go @@ -934,6 +934,77 @@ func (in *TargetAllocator) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetAllocatorEmbedded) DeepCopyInto(out *TargetAllocatorEmbedded) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + in.PrometheusCR.DeepCopyInto(&out.PrometheusCR) + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(v1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + if in.TopologySpreadConstraints != nil { + in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints + *out = make([]v1.TopologySpreadConstraint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.Observability = in.Observability + if in.PodDisruptionBudget != nil { + in, out := &in.PodDisruptionBudget, &out.PodDisruptionBudget + *out = new(PodDisruptionBudgetSpec) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetAllocatorEmbedded. +func (in *TargetAllocatorEmbedded) DeepCopy() *TargetAllocatorEmbedded { + if in == nil { + return nil + } + out := new(TargetAllocatorEmbedded) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TargetAllocatorList) DeepCopyInto(out *TargetAllocatorList) { *out = *in diff --git a/controllers/builder_test.go b/controllers/builder_test.go index 054981cd6e..7b69e16962 100644 --- a/controllers/builder_test.go +++ b/controllers/builder_test.go @@ -21,6 +21,7 @@ import ( "github.com/go-logr/logr" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/require" + go_yaml "gopkg.in/yaml.v3" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" @@ -33,6 +34,7 @@ import ( colfeaturegate "go.opentelemetry.io/collector/featuregate" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate" @@ -73,7 +75,7 @@ var ( ) func TestBuildCollector(t *testing.T) { - var goodConfig = `receivers: + var goodConfigYaml = `receivers: examplereceiver: endpoint: "0.0.0.0:12345" exporters: @@ -84,9 +86,13 @@ service: receivers: [examplereceiver] exporters: [logging] ` + + goodConfig := v1alpha2.Config{} + err := go_yaml.Unmarshal([]byte(goodConfigYaml), &goodConfig) + require.NoError(t, err) one := int32(1) type args struct { - instance v1alpha1.OpenTelemetryCollector + instance v1alpha2.OpenTelemetryCollector } tests := []struct { name string @@ -97,16 +103,18 @@ service: { name: "base case", args: args{ - instance: v1alpha1.OpenTelemetryCollector{ + instance: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Replicas: &one, - Mode: "deployment", - Image: "test", - Config: goodConfig, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "test", + Replicas: &one, + }, + Mode: "deployment", + Config: goodConfig, }, }, }, @@ -334,17 +342,19 @@ service: { name: "ingress", args: args{ - instance: v1alpha1.OpenTelemetryCollector{ + instance: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Replicas: &one, - Mode: "deployment", - Image: "test", - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeNginx, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "test", + Replicas: &one, + }, + Mode: "deployment", + Ingress: v1alpha2.Ingress{ + Type: v1alpha2.IngressTypeNginx, Hostname: "example.com", Annotations: map[string]string{ "something": "true", @@ -617,17 +627,19 @@ service: { name: "specified service account case", args: args{ - instance: v1alpha1.OpenTelemetryCollector{ + instance: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Replicas: &one, - Mode: "deployment", - Image: "test", - Config: goodConfig, - ServiceAccount: "my-special-sa", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "test", + Replicas: &one, + ServiceAccount: "my-special-sa", + }, + Mode: "deployment", + Config: goodConfig, }, }, }, @@ -1083,7 +1095,7 @@ endpoint: ws://opamp-server:4320/v1/opamp } func TestBuildTargetAllocator(t *testing.T) { - var goodConfig = ` + var goodConfigYaml = ` receivers: prometheus: config: @@ -1108,9 +1120,13 @@ service: receivers: [prometheus] exporters: [logging] ` + + goodConfig := v1alpha2.Config{} + err := go_yaml.Unmarshal([]byte(goodConfigYaml), &goodConfig) + require.NoError(t, err) one := int32(1) type args struct { - instance v1alpha1.OpenTelemetryCollector + instance v1alpha2.OpenTelemetryCollector } tests := []struct { name string @@ -1122,20 +1138,22 @@ service: { name: "base case", args: args{ - instance: v1alpha1.OpenTelemetryCollector{ + instance: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Replicas: &one, - Mode: "statefulset", - Image: "test", - Config: goodConfig, - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "test", + Replicas: &one, + }, + Mode: "statefulset", + Config: goodConfig, + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, FilterStrategy: "relabel-config", - PrometheusCR: v1alpha1.OpenTelemetryTargetAllocatorPrometheusCR{ + PrometheusCR: v1alpha2.TargetAllocatorPrometheusCR{ Enabled: true, }, }, @@ -1353,12 +1371,8 @@ label_selector: app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/part-of: opentelemetry prometheus_cr: - pod_monitor_selector: - matchlabels: {} - matchexpressions: [] - service_monitor_selector: - matchlabels: {} - matchexpressions: [] + pod_monitor_selector: null + service_monitor_selector: null `, }, }, @@ -1391,7 +1405,7 @@ prometheus_cr: "app.kubernetes.io/version": "latest", }, Annotations: map[string]string{ - "opentelemetry-targetallocator-config/hash": "51477b182d2c9e7c0db27a2cbc9c7d35b24895b1cf0774d51a41b8d1753696ed", + "opentelemetry-targetallocator-config/hash": "59307aaa5652c8723f7803aa2d2b631389d1a0267444a4a8dc559878b5c4aa2c", }, }, Spec: corev1.PodSpec{ @@ -1516,19 +1530,21 @@ prometheus_cr: { name: "enable metrics case", args: args{ - instance: v1alpha1.OpenTelemetryCollector{ + instance: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "test", Namespace: "test", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Replicas: &one, - Mode: "statefulset", - Image: "test", - Config: goodConfig, - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "test", + Replicas: &one, + }, + Mode: "statefulset", + Config: goodConfig, + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, - PrometheusCR: v1alpha1.OpenTelemetryTargetAllocatorPrometheusCR{ + PrometheusCR: v1alpha2.TargetAllocatorPrometheusCR{ Enabled: true, }, FilterStrategy: "relabel-config", @@ -1752,12 +1768,8 @@ label_selector: app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/part-of: opentelemetry prometheus_cr: - pod_monitor_selector: - matchlabels: {} - matchexpressions: [] - service_monitor_selector: - matchlabels: {} - matchexpressions: [] + pod_monitor_selector: null + service_monitor_selector: null `, }, }, @@ -1790,7 +1802,7 @@ prometheus_cr: "app.kubernetes.io/version": "latest", }, Annotations: map[string]string{ - "opentelemetry-targetallocator-config/hash": "51477b182d2c9e7c0db27a2cbc9c7d35b24895b1cf0774d51a41b8d1753696ed", + "opentelemetry-targetallocator-config/hash": "59307aaa5652c8723f7803aa2d2b631389d1a0267444a4a8dc559878b5c4aa2c", }, }, Spec: corev1.PodSpec{ diff --git a/controllers/opentelemetrycollector_controller.go b/controllers/opentelemetrycollector_controller.go index f5fc4ceb2f..5f4143d214 100644 --- a/controllers/opentelemetrycollector_controller.go +++ b/controllers/opentelemetrycollector_controller.go @@ -32,6 +32,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" collectorStatus "github.com/open-telemetry/opentelemetry-operator/internal/status/collector" @@ -56,15 +57,19 @@ type Params struct { Config config.Config } -func (r *OpenTelemetryCollectorReconciler) getParams(instance v1alpha1.OpenTelemetryCollector) manifests.Params { +func (r *OpenTelemetryCollectorReconciler) getParams(instance v1alpha1.OpenTelemetryCollector) (manifests.Params, error) { + otelCol, err := convert.V1Alpha1to2(instance) + if err != nil { + return manifests.Params{}, err + } return manifests.Params{ Config: r.config, Client: r.Client, - OtelCol: instance, + OtelCol: otelCol, Log: r.log, Scheme: r.scheme, Recorder: r.recorder, - } + }, nil } // NewReconciler creates a new reconciler for OpenTelemetryCollector objects. @@ -119,14 +124,20 @@ func (r *OpenTelemetryCollectorReconciler) Reconcile(ctx context.Context, req ct return ctrl.Result{}, nil } - params := r.getParams(instance) + params, err := r.getParams(instance) + if err != nil { + log.Error(err, "Failed to create manifest.Params") + return ctrl.Result{}, err + } desiredObjects, buildErr := BuildCollector(params) if buildErr != nil { return ctrl.Result{}, buildErr } - err := reconcileDesiredObjects(ctx, r.Client, log, ¶ms.OtelCol, params.Scheme, desiredObjects...) - return collectorStatus.HandleReconcileStatus(ctx, log, params, err) + // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2620 + // TODO: Change &instance to use params.OtelCol + err = reconcileDesiredObjects(ctx, r.Client, log, &instance, params.Scheme, desiredObjects...) + return collectorStatus.HandleReconcileStatus(ctx, log, params, instance, err) } // SetupWithManager tells the manager what our controller is interested in. diff --git a/controllers/reconcile_test.go b/controllers/reconcile_test.go index 59519e6847..1e97ab8397 100644 --- a/controllers/reconcile_test.go +++ b/controllers/reconcile_test.go @@ -67,28 +67,19 @@ var ( } ) -type check func(t *testing.T, params manifests.Params) - -func newParamsAssertNoErr(t *testing.T, taContainerImage string, file string) manifests.Params { - p, err := newParams(taContainerImage, file) - assert.NoError(t, err) - if len(taContainerImage) == 0 { - p.OtelCol.Spec.TargetAllocator.Enabled = false - } - return p -} +type check[T any] func(t *testing.T, params T) func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { - addedMetadataDeployment := paramsWithMode(v1alpha1.ModeDeployment) - addedMetadataDeployment.OtelCol.Labels = map[string]string{ + addedMetadataDeployment := testCollectorWithMode(v1alpha1.ModeDeployment) + addedMetadataDeployment.Labels = map[string]string{ labelName: labelVal, } - addedMetadataDeployment.OtelCol.Annotations = map[string]string{ + addedMetadataDeployment.Annotations = map[string]string{ annotationName: annotationVal, } - deploymentExtraPorts := paramsWithModeAndReplicas(v1alpha1.ModeDeployment, 3) - deploymentExtraPorts.OtelCol.Spec.Ports = append(deploymentExtraPorts.OtelCol.Spec.Ports, extraPorts) - deploymentExtraPorts.OtelCol.Spec.DeploymentUpdateStrategy = appsv1.DeploymentStrategy{ + deploymentExtraPorts := testCollectorWithModeAndReplicas(v1alpha1.ModeDeployment, 3) + deploymentExtraPorts.Spec.Ports = append(deploymentExtraPorts.Spec.Ports, extraPorts) + deploymentExtraPorts.Spec.DeploymentUpdateStrategy = appsv1.DeploymentStrategy{ RollingUpdate: &appsv1.RollingUpdateDeployment{ MaxUnavailable: &intstr.IntOrString{ Type: intstr.Int, @@ -100,33 +91,33 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, }, } - ingressParams := newParamsAssertNoErr(t, "", testFileIngress) - ingressParams.OtelCol.Spec.Ingress.Type = "ingress" - updatedIngressParams := newParamsAssertNoErr(t, "", testFileIngress) - updatedIngressParams.OtelCol.Spec.Ingress.Type = "ingress" - updatedIngressParams.OtelCol.Spec.Ingress.Annotations = map[string]string{"blub": "blob"} - updatedIngressParams.OtelCol.Spec.Ingress.Hostname = expectHostname - routeParams := newParamsAssertNoErr(t, "", testFileIngress) - routeParams.OtelCol.Spec.Ingress.Type = v1alpha1.IngressTypeRoute - routeParams.OtelCol.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure - updatedRouteParams := newParamsAssertNoErr(t, "", testFileIngress) - updatedRouteParams.OtelCol.Spec.Ingress.Type = v1alpha1.IngressTypeRoute - updatedRouteParams.OtelCol.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure - updatedRouteParams.OtelCol.Spec.Ingress.Hostname = expectHostname - deletedParams := paramsWithMode(v1alpha1.ModeDeployment) + ingressParams := testCollectorAssertNoErr(t, "", testFileIngress) + ingressParams.Spec.Ingress.Type = "ingress" + updatedIngressParams := testCollectorAssertNoErr(t, "", testFileIngress) + updatedIngressParams.Spec.Ingress.Type = "ingress" + updatedIngressParams.Spec.Ingress.Annotations = map[string]string{"blub": "blob"} + updatedIngressParams.Spec.Ingress.Hostname = expectHostname + routeParams := testCollectorAssertNoErr(t, "", testFileIngress) + routeParams.Spec.Ingress.Type = v1alpha1.IngressTypeRoute + routeParams.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure + updatedRouteParams := testCollectorAssertNoErr(t, "", testFileIngress) + updatedRouteParams.Spec.Ingress.Type = v1alpha1.IngressTypeRoute + updatedRouteParams.Spec.Ingress.Route.Termination = v1alpha1.TLSRouteTerminationTypeInsecure + updatedRouteParams.Spec.Ingress.Hostname = expectHostname + deletedParams := testCollectorWithMode(v1alpha1.ModeDeployment) now := metav1.NewTime(time.Now()) - deletedParams.OtelCol.DeletionTimestamp = &now + deletedParams.DeletionTimestamp = &now type args struct { - params manifests.Params + params v1alpha1.OpenTelemetryCollector // an optional list of updates to supply after the initial object - updates []manifests.Params + updates []v1alpha1.OpenTelemetryCollector } type want struct { // result check result controllerruntime.Result // a check to run against the current state applied - checks []check + checks []check[v1alpha1.OpenTelemetryCollector] // if an error from creation validation is expected validateErr assert.ErrorAssertionFunc // if an error from reconciliation is expected @@ -141,15 +132,15 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { name: "deployment collector", args: args{ params: addedMetadataDeployment, - updates: []manifests.Params{deploymentExtraPorts}, + updates: []v1alpha1.OpenTelemetryCollector{deploymentExtraPorts}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { d := appsv1.Deployment{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, int32(2), *d.Spec.Replicas) @@ -158,10 +149,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { // confirm the initial strategy is unset assert.Equal(t, d.Spec.Strategy.RollingUpdate.MaxUnavailable.IntVal, int32(0)) assert.Equal(t, d.Spec.Strategy.RollingUpdate.MaxSurge.IntVal, int32(0)) - exists, err = populateObjectIfExists(t, &v1.Service{}, namespacedObjectName(naming.Service(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &v1.Service{}, namespacedObjectName(naming.Service(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.ServiceAccount(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.ServiceAccount(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) }, @@ -171,10 +162,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { d := appsv1.Deployment{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, int32(3), *d.Spec.Replicas) @@ -185,7 +176,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { assert.Contains(t, d.Annotations, annotationName) assert.Contains(t, d.Labels, labelName) actual := v1.Service{} - exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.Service(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.Service(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Contains(t, actual.Spec.Ports, extraPorts) @@ -199,13 +190,13 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "invalid mode", args: args{ - params: paramsWithMode("bad"), - updates: []manifests.Params{}, + params: testCollectorWithMode("bad"), + updates: []v1alpha1.OpenTelemetryCollector{}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{}, + checks: []check[v1alpha1.OpenTelemetryCollector]{}, wantErr: assert.NoError, validateErr: func(t assert.TestingT, err2 error, msgAndArgs ...interface{}) bool { return assert.ErrorContains(t, err2, "Unsupported value: \"bad\"", msgAndArgs) @@ -216,13 +207,13 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "invalid prometheus configuration", args: args{ - params: newParamsAssertNoErr(t, baseTaImage, testFileIngress), - updates: []manifests.Params{}, + params: testCollectorAssertNoErr(t, baseTaImage, testFileIngress), + updates: []v1alpha1.OpenTelemetryCollector{}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{}, + checks: []check[v1alpha1.OpenTelemetryCollector]{}, wantErr: assert.NoError, validateErr: func(t assert.TestingT, err2 error, msgAndArgs ...interface{}) bool { return assert.ErrorContains(t, err2, "no prometheus available as part of the configuration", msgAndArgs) @@ -234,15 +225,15 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { name: "deployment collector with ingress", args: args{ params: ingressParams, - updates: []manifests.Params{updatedIngressParams}, + updates: []v1alpha1.OpenTelemetryCollector{updatedIngressParams}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { d := networkingv1.Ingress{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Ingress(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Ingress(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) }, @@ -252,10 +243,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { d := networkingv1.Ingress{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Ingress(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.Ingress(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, "something-else.com", d.Spec.Rules[0].Host) @@ -270,15 +261,15 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { name: "deployment collector with routes", args: args{ params: routeParams, - updates: []manifests.Params{updatedRouteParams}, + updates: []v1alpha1.OpenTelemetryCollector{updatedRouteParams}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { got := routev1.Route{} - nsn := types.NamespacedName{Namespace: params.OtelCol.Namespace, Name: "otlp-grpc-test-route"} + nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route"} exists, err := populateObjectIfExists(t, &got, nsn) assert.NoError(t, err) assert.True(t, exists) @@ -289,10 +280,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { got := routev1.Route{} - nsn := types.NamespacedName{Namespace: params.OtelCol.Namespace, Name: "otlp-grpc-test-route"} + nsn := types.NamespacedName{Namespace: params.Namespace, Name: "otlp-grpc-test-route"} exists, err := populateObjectIfExists(t, &got, nsn) assert.NoError(t, err) assert.True(t, exists) @@ -307,16 +298,16 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "hpa v2 deployment collector", args: args{ - params: paramsWithHPA(3, 5), - updates: []manifests.Params{paramsWithHPA(1, 9)}, + params: testCollectorWithHPA(3, 5), + updates: []v1alpha1.OpenTelemetryCollector{testCollectorWithHPA(1, 9)}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { actual := autoscalingv2.HorizontalPodAutoscaler{} - exists, hpaErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, hpaErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.Name), params.Namespace)) assert.NoError(t, hpaErr) require.Len(t, actual.Spec.Metrics, 1) assert.Equal(t, int32(90), *actual.Spec.Metrics[0].Resource.Target.AverageUtilization) @@ -330,10 +321,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { actual := autoscalingv2.HorizontalPodAutoscaler{} - exists, hpaErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, hpaErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.Name), params.Namespace)) assert.NoError(t, hpaErr) require.Len(t, actual.Spec.Metrics, 1) assert.Equal(t, int32(90), *actual.Spec.Metrics[0].Resource.Target.AverageUtilization) @@ -350,16 +341,16 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "policy v1 deployment collector", args: args{ - params: paramsWithPolicy(1, 0), - updates: []manifests.Params{paramsWithPolicy(0, 1)}, + params: testCollectorWithPDB(1, 0), + updates: []v1alpha1.OpenTelemetryCollector{testCollectorWithPDB(0, 1)}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { actual := policyV1.PodDisruptionBudget{} - exists, pdbErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, pdbErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.Name), params.Namespace)) assert.NoError(t, pdbErr) assert.Equal(t, int32(1), actual.Spec.MinAvailable.IntVal) assert.Nil(t, actual.Spec.MaxUnavailable) @@ -371,10 +362,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { actual := policyV1.PodDisruptionBudget{} - exists, pdbErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, pdbErr := populateObjectIfExists(t, &actual, namespacedObjectName(naming.HorizontalPodAutoscaler(params.Name), params.Namespace)) assert.NoError(t, pdbErr) assert.Nil(t, actual.Spec.MinAvailable) assert.Equal(t, int32(1), actual.Spec.MaxUnavailable.IntVal) @@ -389,14 +380,14 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "daemonset collector", args: args{ - params: paramsWithMode(v1alpha1.ModeDaemonSet), + params: testCollectorWithMode(v1alpha1.ModeDaemonSet), }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { - exists, err := populateObjectIfExists(t, &appsv1.DaemonSet{}, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { + exists, err := populateObjectIfExists(t, &appsv1.DaemonSet{}, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) }, @@ -409,29 +400,29 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { { name: "stateful should update collector with TA", args: args{ - params: paramsWithMode(v1alpha1.ModeStatefulSet), - updates: []manifests.Params{ - newParamsAssertNoErr(t, baseTaImage, promFile), - newParamsAssertNoErr(t, baseTaImage, updatedPromFile), - newParamsAssertNoErr(t, updatedTaImage, updatedPromFile), + params: testCollectorWithMode(v1alpha1.ModeStatefulSet), + updates: []v1alpha1.OpenTelemetryCollector{ + testCollectorAssertNoErr(t, baseTaImage, promFile), + testCollectorAssertNoErr(t, baseTaImage, updatedPromFile), + testCollectorAssertNoErr(t, updatedTaImage, updatedPromFile), }, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { - exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { + exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &appsv1.StatefulSet{}, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &appsv1.StatefulSet{}, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) // Check the TA doesn't exist - exists, err = populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.False(t, exists) - exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.False(t, exists) }, @@ -441,23 +432,22 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { - exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { + exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) actual := v1.ConfigMap{} - exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.TargetAllocatorServiceAccount(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.TargetAllocatorServiceAccount(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - - promConfig, err := ta.ConfigToPromConfig(newParamsAssertNoErr(t, baseTaImage, promFile).OtelCol.Spec.Config) + promConfig, err := ta.ConfigToPromConfig(testCollectorAssertNoErr(t, baseTaImage, promFile).Spec.Config) assert.NoError(t, err) taConfig := make(map[interface{}]interface{}) @@ -478,6 +468,8 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { taConfig["config"] = promConfig["config"] taConfig["allocation_strategy"] = "consistent-hashing" taConfig["filter_strategy"] = "relabel-config" + taConfig["pod_monitor_selector"] = map[string]string{} + taConfig["service_monitor_selector"] = map[string]string{} taConfig["prometheus_cr"] = map[string]any{ "scrape_interval": "30s", "pod_monitor_selector": &metav1.LabelSelector{}, @@ -493,16 +485,16 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { - exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { + exists, err := populateObjectIfExists(t, &v1.ConfigMap{}, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) actual := v1.ConfigMap{} - exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &appsv1.Deployment{}, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Contains(t, actual.Data["targetallocator.yaml"], "0.0.0.0:10100") @@ -513,10 +505,10 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { actual := appsv1.Deployment{} - exists, err := populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &actual, namespacedObjectName(naming.TargetAllocator(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, actual.Spec.Template.Spec.Containers[0].Image, updatedTaImage) @@ -531,15 +523,15 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { name: "collector is being deleted", args: args{ params: deletedParams, - updates: []manifests.Params{}, + updates: []v1alpha1.OpenTelemetryCollector{}, }, want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpenTelemetryCollector]{ + func(t *testing.T, params v1alpha1.OpenTelemetryCollector) { o := v1alpha1.OpenTelemetryCollector{} - exists, err := populateObjectIfExists(t, &o, namespacedObjectName(naming.Collector(params.OtelCol.Name), params.OtelCol.Namespace)) + exists, err := populateObjectIfExists(t, &o, namespacedObjectName(naming.Collector(params.Name), params.Namespace)) assert.NoError(t, err) assert.False(t, exists) // There should be no collector anymore }, @@ -554,7 +546,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { testContext := context.Background() - nsn := types.NamespacedName{Name: tt.args.params.OtelCol.Name, Namespace: tt.args.params.OtelCol.Namespace} + nsn := types.NamespacedName{Name: tt.args.params.Name, Namespace: tt.args.params.Namespace} reconciler := controllers.NewReconciler(controllers.Params{ Client: k8sClient, Log: logger, @@ -570,13 +562,13 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { assert.True(t, len(tt.want) > 0, "must have at least one group of checks to run") firstCheck := tt.want[0] // Check for this before create, otherwise it's blown away. - deletionTimestamp := tt.args.params.OtelCol.GetDeletionTimestamp() - createErr := k8sClient.Create(testContext, &tt.args.params.OtelCol) + deletionTimestamp := tt.args.params.GetDeletionTimestamp() + createErr := k8sClient.Create(testContext, &tt.args.params) if !firstCheck.validateErr(t, createErr) { return } if deletionTimestamp != nil { - err := k8sClient.Delete(testContext, &tt.args.params.OtelCol, client.PropagationPolicy(metav1.DeletePropagationForeground)) + err := k8sClient.Delete(testContext, &tt.args.params, client.PropagationPolicy(metav1.DeletePropagationForeground)) assert.NoError(t, err) } req := k8sreconcile.Request{ @@ -584,7 +576,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { } got, reconcileErr := reconciler.Reconcile(testContext, req) if !firstCheck.wantErr(t, reconcileErr) { - require.NoError(t, k8sClient.Delete(testContext, &tt.args.params.OtelCol)) + require.NoError(t, k8sClient.Delete(testContext, &tt.args.params)) return } assert.Equal(t, firstCheck.result, got) @@ -599,9 +591,9 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { assert.True(t, found) assert.NoError(t, err) - updateParam.OtelCol.SetResourceVersion(existing.ResourceVersion) - updateParam.OtelCol.SetUID(existing.UID) - err = k8sClient.Update(testContext, &updateParam.OtelCol) + updateParam.SetResourceVersion(existing.ResourceVersion) + updateParam.SetUID(existing.UID) + err = k8sClient.Update(testContext, &updateParam) assert.NoError(t, err) if err != nil { continue @@ -622,7 +614,7 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { } // Only delete upon a successful creation if createErr == nil { - require.NoError(t, k8sClient.Delete(testContext, &tt.args.params.OtelCol)) + require.NoError(t, k8sClient.Delete(testContext, &tt.args.params)) } }) } @@ -648,7 +640,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { // result check result controllerruntime.Result // a check to run against the current state applied - checks []check + checks []check[v1alpha1.OpAMPBridge] // if an error from creation validation is expected validateErr assert.ErrorAssertionFunc // if an error from reconciliation is expected @@ -668,19 +660,19 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { want: []want{ { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpAMPBridge]{ + func(t *testing.T, params v1alpha1.OpAMPBridge) { d := appsv1.Deployment{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.OpAMPBridge(params.OpAMPBridge.Name), params.OpAMPBridge.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.OpAMPBridge(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Equal(t, int32(1), *d.Spec.Replicas) assert.Contains(t, d.Spec.Template.Annotations, annotationName) assert.Contains(t, d.Labels, labelName) - exists, err = populateObjectIfExists(t, &v1.Service{}, namespacedObjectName(naming.OpAMPBridgeService(params.OpAMPBridge.Name), params.OpAMPBridge.Namespace)) + exists, err = populateObjectIfExists(t, &v1.Service{}, namespacedObjectName(naming.OpAMPBridgeService(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) - exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.ServiceAccount(params.OpAMPBridge.Name), params.OpAMPBridge.Namespace)) + exists, err = populateObjectIfExists(t, &v1.ServiceAccount{}, namespacedObjectName(naming.ServiceAccount(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) }, @@ -690,17 +682,17 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { }, { result: controllerruntime.Result{}, - checks: []check{ - func(t *testing.T, params manifests.Params) { + checks: []check[v1alpha1.OpAMPBridge]{ + func(t *testing.T, params v1alpha1.OpAMPBridge) { d := appsv1.Deployment{} - exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.OpAMPBridge(params.OpAMPBridge.Name), params.OpAMPBridge.Namespace)) + exists, err := populateObjectIfExists(t, &d, namespacedObjectName(naming.OpAMPBridge(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) // confirm that we don't remove annotations and labels even if we don't set them assert.Contains(t, d.Spec.Template.Annotations, annotationName) assert.Contains(t, d.Labels, labelName) actual := v1.Service{} - exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.OpAMPBridgeService(params.OpAMPBridge.Name), params.OpAMPBridge.Namespace)) + exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.OpAMPBridgeService(params.Name), params.Namespace)) assert.NoError(t, err) assert.True(t, exists) assert.Contains(t, actual.Spec.Ports, extraPorts) @@ -744,7 +736,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { } assert.Equal(t, firstCheck.result, got) for _, check := range firstCheck.checks { - check(t, tt.args.params) + check(t, tt.args.params.OpAMPBridge) } // run the next set of checks for pid, updateParam := range tt.args.updates { @@ -772,7 +764,7 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { } assert.Equal(t, checkGroup.result, got) for _, check := range checkGroup.checks { - check(t, updateParam) + check(t, updateParam.OpAMPBridge) } } // Only delete upon a successful creation diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 86e5cc02e5..00176baf4c 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -26,6 +26,7 @@ import ( "time" routev1 "github.com/openshift/api/route/v1" + "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -215,51 +216,53 @@ func TestMain(m *testing.M) { os.Exit(code) } -func paramsWithMode(mode v1alpha1.Mode) manifests.Params { +func testCollectorWithMode(mode v1alpha1.Mode) v1alpha1.OpenTelemetryCollector { replicas := int32(2) - return paramsWithModeAndReplicas(mode, replicas) + return testCollectorWithModeAndReplicas(mode, replicas) } -func paramsWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) manifests.Params { +func testCollectorWithModeAndReplicas(mode v1alpha1.Mode, replicas int32) v1alpha1.OpenTelemetryCollector { configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) } - return manifests.Params{ - Config: config.New(config.WithCollectorImage(defaultCollectorImage), config.WithTargetAllocatorImage(defaultTaAllocationImage)), - Client: k8sClient, - OtelCol: v1alpha1.OpenTelemetryCollector{ - TypeMeta: metav1.TypeMeta{ - Kind: "opentelemetry.io", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "default", - }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - Replicas: &replicas, - Config: string(configYAML), - Mode: mode, - }, + return v1alpha1.OpenTelemetryCollector{ + TypeMeta: metav1.TypeMeta{ + Kind: "opentelemetry.io", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}, + Replicas: &replicas, + Config: string(configYAML), + Mode: mode, }, - Scheme: testScheme, - Log: logger, - Recorder: record.NewFakeRecorder(10), } } -func newParams(taContainerImage string, file string) (manifests.Params, error) { +func testCollectorAssertNoErr(t *testing.T, taContainerImage string, file string) v1alpha1.OpenTelemetryCollector { + p, err := testCollectorWithConfigFile(taContainerImage, file) + assert.NoError(t, err) + if len(taContainerImage) == 0 { + p.Spec.TargetAllocator.Enabled = false + } + return p +} + +func testCollectorWithConfigFile(taContainerImage string, file string) (v1alpha1.OpenTelemetryCollector, error) { replicas := int32(1) var configYAML []byte var err error @@ -270,95 +273,76 @@ func newParams(taContainerImage string, file string) (manifests.Params, error) { configYAML, err = os.ReadFile(file) } if err != nil { - return manifests.Params{}, fmt.Errorf("Error getting yaml file: %w", err) + return v1alpha1.OpenTelemetryCollector{}, fmt.Errorf("Error getting yaml file: %w", err) } - - cfg := config.New(config.WithCollectorImage(defaultCollectorImage), config.WithTargetAllocatorImage(defaultTaAllocationImage)) - - return manifests.Params{ - Config: cfg, - Client: k8sClient, - OtelCol: v1alpha1.OpenTelemetryCollector{ - TypeMeta: metav1.TypeMeta{ - Kind: "opentelemetry.io", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test", - Namespace: "default", - }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Mode: v1alpha1.ModeStatefulSet, - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ - Enabled: true, - Image: taContainerImage, + return v1alpha1.OpenTelemetryCollector{ + TypeMeta: metav1.TypeMeta{ + Kind: "opentelemetry.io", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Mode: v1alpha1.ModeStatefulSet, + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, }, - Replicas: &replicas, - Config: string(configYAML), + NodePort: 0, + }}, + TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Enabled: true, + Image: taContainerImage, }, + Replicas: &replicas, + Config: string(configYAML), }, - Scheme: testScheme, - Log: logger, }, nil } -func paramsWithHPA(minReps, maxReps int32) manifests.Params { +func testCollectorWithHPA(minReps, maxReps int32) v1alpha1.OpenTelemetryCollector { configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) } - cpuUtilization := int32(90) - configuration := config.New(config.WithCollectorImage(defaultCollectorImage), config.WithTargetAllocatorImage(defaultTaAllocationImage)) - - return manifests.Params{ - Config: configuration, - Client: k8sClient, - OtelCol: v1alpha1.OpenTelemetryCollector{ - TypeMeta: metav1.TypeMeta{ - Kind: "opentelemetry.io", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "hpatest", - Namespace: "default", - UID: instanceUID, - }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - Config: string(configYAML), - Autoscaler: &v1alpha1.AutoscalerSpec{ - MinReplicas: &minReps, - MaxReplicas: &maxReps, - TargetCPUUtilization: &cpuUtilization, + return v1alpha1.OpenTelemetryCollector{ + TypeMeta: metav1.TypeMeta{ + Kind: "opentelemetry.io", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "hpatest", + Namespace: "default", + UID: instanceUID, + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, }, + NodePort: 0, + }}, + Config: string(configYAML), + Autoscaler: &v1alpha1.AutoscalerSpec{ + MinReplicas: &minReps, + MaxReplicas: &maxReps, + TargetCPUUtilization: &cpuUtilization, }, }, - Scheme: testScheme, - Log: logger, - Recorder: record.NewFakeRecorder(10), } } -func paramsWithPolicy(minAvailable, maxUnavailable int32) manifests.Params { +func testCollectorWithPDB(minAvailable, maxUnavailable int32) v1alpha1.OpenTelemetryCollector { configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) @@ -387,36 +371,29 @@ func paramsWithPolicy(minAvailable, maxUnavailable int32) manifests.Params { } } - return manifests.Params{ - Config: configuration, - Client: k8sClient, - OtelCol: v1alpha1.OpenTelemetryCollector{ - TypeMeta: metav1.TypeMeta{ - Kind: "opentelemetry.io", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "policytest", - Namespace: "default", - UID: instanceUID, - }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - Config: string(configYAML), - PodDisruptionBudget: pdb, - }, + return v1alpha1.OpenTelemetryCollector{ + TypeMeta: metav1.TypeMeta{ + Kind: "opentelemetry.io", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "policytest", + Namespace: "default", + UID: instanceUID, + }, + Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}, + Config: string(configYAML), + PodDisruptionBudget: pdb, }, - Scheme: testScheme, - Log: logger, - Recorder: record.NewFakeRecorder(10), } } diff --git a/internal/api/convert/v1alpha.go b/internal/api/convert/v1alpha.go index 1a6ed18313..4c5331086b 100644 --- a/internal/api/convert/v1alpha.go +++ b/internal/api/convert/v1alpha.go @@ -18,6 +18,7 @@ import ( "errors" "gopkg.in/yaml.v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" @@ -93,30 +94,7 @@ func V1Alpha1to2(in v1alpha1.OpenTelemetryCollector) (v1alpha2.OpenTelemetryColl out.Spec.OpenTelemetryCommonFields.InitContainers = copy.Spec.InitContainers out.Spec.OpenTelemetryCommonFields.AdditionalContainers = copy.Spec.AdditionalContainers - out.Spec.TargetAllocator.Replicas = copy.Spec.TargetAllocator.Replicas - out.Spec.TargetAllocator.NodeSelector = copy.Spec.TargetAllocator.NodeSelector - out.Spec.TargetAllocator.Resources = copy.Spec.TargetAllocator.Resources - out.Spec.TargetAllocator.AllocationStrategy = copy.Spec.TargetAllocator.AllocationStrategy - out.Spec.TargetAllocator.FilterStrategy = copy.Spec.TargetAllocator.FilterStrategy - out.Spec.TargetAllocator.ServiceAccount = copy.Spec.TargetAllocator.ServiceAccount - out.Spec.TargetAllocator.Image = copy.Spec.TargetAllocator.Image - out.Spec.TargetAllocator.Enabled = copy.Spec.TargetAllocator.Enabled - out.Spec.TargetAllocator.Affinity = copy.Spec.TargetAllocator.Affinity - out.Spec.TargetAllocator.PrometheusCR.Enabled = copy.Spec.TargetAllocator.PrometheusCR.Enabled - out.Spec.TargetAllocator.PrometheusCR.ScrapeInterval = copy.Spec.TargetAllocator.PrometheusCR.ScrapeInterval - out.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector = copy.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector - out.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector = copy.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector - out.Spec.TargetAllocator.SecurityContext = copy.Spec.TargetAllocator.SecurityContext - out.Spec.TargetAllocator.PodSecurityContext = copy.Spec.TargetAllocator.PodSecurityContext - out.Spec.TargetAllocator.TopologySpreadConstraints = copy.Spec.TargetAllocator.TopologySpreadConstraints - out.Spec.TargetAllocator.Tolerations = copy.Spec.TargetAllocator.Tolerations - out.Spec.TargetAllocator.Env = copy.Spec.TargetAllocator.Env - out.Spec.TargetAllocator.Observability = v1alpha1.ObservabilitySpec{ - Metrics: v1alpha1.MetricsConfigSpec{ - EnableMetrics: copy.Spec.TargetAllocator.Observability.Metrics.EnableMetrics, - }, - } - out.Spec.TargetAllocator.PodDisruptionBudget = copy.Spec.TargetAllocator.PodDisruptionBudget + out.Spec.TargetAllocator = TargetAllocatorEmbedded(copy.Spec.TargetAllocator) out.Spec.Mode = v1alpha2.Mode(copy.Spec.Mode) out.Spec.UpgradeStrategy = v1alpha2.UpgradeStrategy(copy.Spec.UpgradeStrategy) @@ -148,3 +126,42 @@ func V1Alpha1to2(in v1alpha1.OpenTelemetryCollector) (v1alpha2.OpenTelemetryColl return out, nil } + +func TargetAllocatorEmbedded(in v1alpha1.OpenTelemetryTargetAllocator) v1alpha2.TargetAllocatorEmbedded { + out := v1alpha2.TargetAllocatorEmbedded{} + out.Replicas = in.Replicas + out.NodeSelector = in.NodeSelector + out.Resources = in.Resources + out.AllocationStrategy = v1alpha2.TargetAllocatorAllocationStrategy(in.AllocationStrategy) + out.FilterStrategy = v1alpha2.TargetAllocatorFilterStrategy(in.FilterStrategy) + out.ServiceAccount = in.ServiceAccount + out.Image = in.Image + out.Enabled = in.Enabled + out.Affinity = in.Affinity + out.PrometheusCR.Enabled = in.PrometheusCR.Enabled + out.PrometheusCR.ScrapeInterval = in.PrometheusCR.ScrapeInterval + out.SecurityContext = in.SecurityContext + out.PodSecurityContext = in.PodSecurityContext + out.TopologySpreadConstraints = in.TopologySpreadConstraints + out.Tolerations = in.Tolerations + out.Env = in.Env + out.Observability = v1alpha1.ObservabilitySpec{ + Metrics: v1alpha1.MetricsConfigSpec{ + EnableMetrics: in.Observability.Metrics.EnableMetrics, + }, + } + + out.PrometheusCR.PodMonitorSelector = &metav1.LabelSelector{ + MatchLabels: in.PrometheusCR.PodMonitorSelector, + } + out.PrometheusCR.ServiceMonitorSelector = &metav1.LabelSelector{ + MatchLabels: in.PrometheusCR.ServiceMonitorSelector, + } + if in.PodDisruptionBudget != nil { + out.PodDisruptionBudget = &v1alpha2.PodDisruptionBudgetSpec{ + MinAvailable: in.PodDisruptionBudget.MinAvailable, + MaxUnavailable: in.PodDisruptionBudget.MaxUnavailable, + } + } + return out +} diff --git a/internal/api/convert/v1alpha_test.go b/internal/api/convert/v1alpha_test.go index 8d3bac8297..3d7f959336 100644 --- a/internal/api/convert/v1alpha_test.go +++ b/internal/api/convert/v1alpha_test.go @@ -16,11 +16,17 @@ package convert import ( "testing" + "time" "github.com/stretchr/testify/assert" "gopkg.in/yaml.v3" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) func Test_V1Alpha1to2(t *testing.T) { @@ -69,3 +75,136 @@ service: assert.ErrorContains(t, err, "could not convert config json to v1alpha2.Config") }) } + +func Test_TargetAllocator(t *testing.T) { + replicas := int32(2) + runAsNonRoot := true + privileged := true + runAsUser := int64(1337) + runasGroup := int64(1338) + input := v1alpha1.OpenTelemetryTargetAllocator{ + Replicas: &replicas, + NodeSelector: map[string]string{"key": "value"}, + Resources: v1.ResourceRequirements{ + Limits: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("500m"), + v1.ResourceMemory: resource.MustParse("128Mi"), + }, + Requests: v1.ResourceList{ + v1.ResourceCPU: resource.MustParse("500m"), + v1.ResourceMemory: resource.MustParse("128Mi"), + }, + }, + AllocationStrategy: v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing, + FilterStrategy: "relabel-config", + ServiceAccount: "serviceAccountName", + Image: "custom_image", + Enabled: true, + Affinity: &v1.Affinity{ + NodeAffinity: &v1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{ + NodeSelectorTerms: []v1.NodeSelectorTerm{ + { + MatchExpressions: []v1.NodeSelectorRequirement{ + { + Key: "node", + Operator: v1.NodeSelectorOpIn, + Values: []string{"test-node"}, + }, + }, + }, + }, + }, + }, + }, + PrometheusCR: v1alpha1.OpenTelemetryTargetAllocatorPrometheusCR{ + Enabled: true, + ScrapeInterval: &metav1.Duration{Duration: time.Second}, + PodMonitorSelector: map[string]string{"podmonitorkey": "podmonitorvalue"}, + ServiceMonitorSelector: map[string]string{"servicemonitorkey": "servicemonitorkey"}, + }, + PodSecurityContext: &v1.PodSecurityContext{ + RunAsNonRoot: &runAsNonRoot, + RunAsUser: &runAsUser, + RunAsGroup: &runasGroup, + }, + SecurityContext: &v1.SecurityContext{ + RunAsUser: &runAsUser, + Privileged: &privileged, + }, + TopologySpreadConstraints: []v1.TopologySpreadConstraint{ + { + MaxSkew: 1, + TopologyKey: "kubernetes.io/hostname", + WhenUnsatisfiable: "DoNotSchedule", + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "foo": "bar", + }, + }, + }, + }, + Tolerations: []v1.Toleration{ + { + Key: "hii", + Value: "greeting", + Effect: "NoSchedule", + }, + }, + Env: []v1.EnvVar{ + { + Name: "POD_NAME", + ValueFrom: &v1.EnvVarSource{ + FieldRef: &v1.ObjectFieldSelector{ + FieldPath: "metadata.name", + }, + }, + }, + }, + Observability: v1alpha1.ObservabilitySpec{ + Metrics: v1alpha1.MetricsConfigSpec{ + EnableMetrics: true, + }, + }, + PodDisruptionBudget: &v1alpha1.PodDisruptionBudgetSpec{ + MaxUnavailable: &intstr.IntOrString{ + Type: intstr.Int, + IntVal: 1, + }, + }, + } + + expected := v1alpha2.TargetAllocatorEmbedded{ + Replicas: input.Replicas, + NodeSelector: input.NodeSelector, + Resources: input.Resources, + AllocationStrategy: v1alpha2.TargetAllocatorAllocationStrategyConsistentHashing, + FilterStrategy: v1alpha2.TargetAllocatorFilterStrategyRelabelConfig, + ServiceAccount: input.ServiceAccount, + Image: input.Image, + Enabled: input.Enabled, + Affinity: input.Affinity, + PrometheusCR: v1alpha2.TargetAllocatorPrometheusCR{ + Enabled: input.PrometheusCR.Enabled, + ScrapeInterval: input.PrometheusCR.ScrapeInterval, + PodMonitorSelector: &metav1.LabelSelector{ + MatchLabels: input.PrometheusCR.PodMonitorSelector, + }, + ServiceMonitorSelector: &metav1.LabelSelector{ + MatchLabels: input.PrometheusCR.ServiceMonitorSelector, + }, + }, + SecurityContext: input.SecurityContext, + PodSecurityContext: input.PodSecurityContext, + TopologySpreadConstraints: input.TopologySpreadConstraints, + Tolerations: input.Tolerations, + Env: input.Env, + Observability: input.Observability, + PodDisruptionBudget: &v1alpha2.PodDisruptionBudgetSpec{ + MinAvailable: input.PodDisruptionBudget.MinAvailable, + MaxUnavailable: input.PodDisruptionBudget.MaxUnavailable, + }, + } + + assert.Equal(t, expected, TargetAllocatorEmbedded(input)) +} diff --git a/internal/manifests/collector/adapters/config_to_ports.go b/internal/manifests/collector/adapters/config_to_ports.go index 2f9c7aa63e..f0945389f8 100644 --- a/internal/manifests/collector/adapters/config_to_ports.go +++ b/internal/manifests/collector/adapters/config_to_ports.go @@ -160,6 +160,7 @@ func ConfigToMetricsPort(logger logr.Logger, config map[interface{}]interface{}) type cfg struct { Service serviceCfg } + var cOut cfg err := mapstructure.Decode(config, &cOut) if err != nil { diff --git a/internal/manifests/collector/collector.go b/internal/manifests/collector/collector.go index 37a006c087..e673b168aa 100644 --- a/internal/manifests/collector/collector.go +++ b/internal/manifests/collector/collector.go @@ -17,7 +17,7 @@ package collector import ( "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate" ) @@ -31,15 +31,15 @@ func Build(params manifests.Params) ([]client.Object, error) { var resourceManifests []client.Object var manifestFactories []manifests.K8sManifestFactory switch params.OtelCol.Spec.Mode { - case v1alpha1.ModeDeployment: + case v1alpha2.ModeDeployment: manifestFactories = append(manifestFactories, manifests.Factory(Deployment)) manifestFactories = append(manifestFactories, manifests.Factory(PodDisruptionBudget)) - case v1alpha1.ModeStatefulSet: + case v1alpha2.ModeStatefulSet: manifestFactories = append(manifestFactories, manifests.Factory(StatefulSet)) manifestFactories = append(manifestFactories, manifests.Factory(PodDisruptionBudget)) - case v1alpha1.ModeDaemonSet: + case v1alpha2.ModeDaemonSet: manifestFactories = append(manifestFactories, manifests.Factory(DaemonSet)) - case v1alpha1.ModeSidecar: + case v1alpha2.ModeSidecar: params.Log.V(5).Info("not building sidecar...") } manifestFactories = append(manifestFactories, []manifests.K8sManifestFactory{ @@ -53,7 +53,7 @@ func Build(params manifests.Params) ([]client.Object, error) { }...) if params.OtelCol.Spec.Observability.Metrics.EnableMetrics && featuregate.PrometheusOperatorIsAvailable.IsEnabled() { - if params.OtelCol.Spec.Mode == v1alpha1.ModeSidecar { + if params.OtelCol.Spec.Mode == v1alpha2.ModeSidecar { manifestFactories = append(manifestFactories, manifests.Factory(PodMonitor)) } else { manifestFactories = append(manifestFactories, manifests.Factory(ServiceMonitor)) diff --git a/internal/manifests/collector/config_replace_test.go b/internal/manifests/collector/config_replace_test.go index 76fb3af32f..8f31af3107 100644 --- a/internal/manifests/collector/config_replace_test.go +++ b/internal/manifests/collector/config_replace_test.go @@ -24,7 +24,6 @@ import ( colfeaturegate "go.opentelemetry.io/collector/featuregate" "gopkg.in/yaml.v2" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" ta "github.com/open-telemetry/opentelemetry-operator/internal/manifests/targetallocator/adapters" "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate" ) @@ -32,8 +31,6 @@ import ( func TestPrometheusParser(t *testing.T) { param, err := newParams("test/test-img", "testdata/http_sd_config_test.yaml") assert.NoError(t, err) - otelCol, err := convert.V1Alpha1to2(param.OtelCol) - assert.NoError(t, err) t.Run("should update config with http_sd_config", func(t *testing.T) { err := colfeaturegate.GlobalRegistry().Set(featuregate.EnableTargetAllocatorRewrite.ID(), false) @@ -41,7 +38,7 @@ func TestPrometheusParser(t *testing.T) { t.Cleanup(func() { _ = colfeaturegate.GlobalRegistry().Set(featuregate.EnableTargetAllocatorRewrite.ID(), true) }) - actualConfig, err := ReplaceConfig(otelCol) + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) // prepare @@ -74,8 +71,8 @@ func TestPrometheusParser(t *testing.T) { t.Run("should update config with targetAllocator block if block not present", func(t *testing.T) { // Set up the test scenario - otelCol.Spec.TargetAllocator.Enabled = true - actualConfig, err := ReplaceConfig(otelCol) + param.OtelCol.Spec.TargetAllocator.Enabled = true + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) // Verify the expected changes in the config @@ -99,12 +96,10 @@ func TestPrometheusParser(t *testing.T) { // Set up the test scenario paramTa, err := newParams("test/test-img", "testdata/http_sd_config_ta_test.yaml") require.NoError(t, err) - otelColTa, err := convert.V1Alpha1to2(paramTa.OtelCol) - assert.NoError(t, err) paramTa.OtelCol.Spec.TargetAllocator.Enabled = true - actualConfig, err := ReplaceConfig(otelColTa) + actualConfig, err := ReplaceConfig(paramTa.OtelCol) assert.NoError(t, err) // Verify the expected changes in the config @@ -125,9 +120,9 @@ func TestPrometheusParser(t *testing.T) { }) t.Run("should not update config with http_sd_config", func(t *testing.T) { - otelCol.Spec.TargetAllocator.Enabled = false + param.OtelCol.Spec.TargetAllocator.Enabled = false - actualConfig, err := ReplaceConfig(otelCol) + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) // prepare @@ -163,16 +158,14 @@ func TestPrometheusParser(t *testing.T) { func TestReplaceConfig(t *testing.T) { param, err := newParams("test/test-img", "testdata/relabel_config_original.yaml") assert.NoError(t, err) - otelCol, err := convert.V1Alpha1to2(param.OtelCol) - assert.NoError(t, err) t.Run("should not modify config when TargetAllocator is disabled", func(t *testing.T) { - otelCol.Spec.TargetAllocator.Enabled = false + param.OtelCol.Spec.TargetAllocator.Enabled = false expectedConfigBytes, err := os.ReadFile("testdata/relabel_config_original.yaml") assert.NoError(t, err) expectedConfig := string(expectedConfigBytes) - actualConfig, err := ReplaceConfig(otelCol) + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) assert.YAMLEq(t, expectedConfig, actualConfig) @@ -185,26 +178,26 @@ func TestReplaceConfig(t *testing.T) { _ = colfeaturegate.GlobalRegistry().Set(featuregate.EnableTargetAllocatorRewrite.ID(), true) }) - otelCol.Spec.TargetAllocator.Enabled = true + param.OtelCol.Spec.TargetAllocator.Enabled = true expectedConfigBytes, err := os.ReadFile("testdata/relabel_config_expected_with_sd_config.yaml") assert.NoError(t, err) expectedConfig := string(expectedConfigBytes) - actualConfig, err := ReplaceConfig(otelCol) + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) assert.YAMLEq(t, expectedConfig, actualConfig) }) t.Run("should remove scrape configs if TargetAllocator is enabled and feature flag is set", func(t *testing.T) { - otelCol.Spec.TargetAllocator.Enabled = true + param.OtelCol.Spec.TargetAllocator.Enabled = true expectedConfigBytes, err := os.ReadFile("testdata/config_expected_targetallocator.yaml") assert.NoError(t, err) expectedConfig := string(expectedConfigBytes) - actualConfig, err := ReplaceConfig(otelCol) + actualConfig, err := ReplaceConfig(param.OtelCol) assert.NoError(t, err) assert.YAMLEq(t, expectedConfig, actualConfig) diff --git a/internal/manifests/collector/configmap.go b/internal/manifests/collector/configmap.go index 6a84c49d53..58ee4c1312 100644 --- a/internal/manifests/collector/configmap.go +++ b/internal/manifests/collector/configmap.go @@ -18,21 +18,16 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) func ConfigMap(params manifests.Params) (*corev1.ConfigMap, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.ConfigMap(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) + name := naming.ConfigMap(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) - replacedConf, err := ReplaceConfig(otelCol) + replacedConf, err := ReplaceConfig(params.OtelCol) if err != nil { params.Log.V(2).Info("failed to update prometheus config to use sharded targets: ", "err", err) return nil, err @@ -41,9 +36,9 @@ func ConfigMap(params manifests.Params) (*corev1.ConfigMap, error) { return &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: otelCol.Namespace, + Namespace: params.OtelCol.Namespace, Labels: labels, - Annotations: otelCol.Annotations, + Annotations: params.OtelCol.Annotations, }, Data: map[string]string{ "collector.yaml": replacedConf, diff --git a/internal/manifests/collector/daemonset.go b/internal/manifests/collector/daemonset.go index 0f79c80d6a..c257be3397 100644 --- a/internal/manifests/collector/daemonset.go +++ b/internal/manifests/collector/daemonset.go @@ -19,7 +19,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -27,32 +26,28 @@ import ( // DaemonSet builds the deployment for the given instance. func DaemonSet(params manifests.Params) (*appsv1.DaemonSet, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.Collector(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + name := naming.Collector(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) - annotations, err := Annotations(otelCol) + annotations, err := Annotations(params.OtelCol) if err != nil { return nil, err } - podAnnotations, err := PodAnnotations(otelCol) + podAnnotations, err := PodAnnotations(params.OtelCol) if err != nil { return nil, err } return &appsv1.DaemonSet{ ObjectMeta: metav1.ObjectMeta{ - Name: naming.Collector(otelCol.Name), - Namespace: otelCol.Namespace, + Name: naming.Collector(params.OtelCol.Name), + Namespace: params.OtelCol.Namespace, Labels: labels, Annotations: annotations, }, Spec: appsv1.DaemonSetSpec{ Selector: &metav1.LabelSelector{ - MatchLabels: manifestutils.SelectorLabels(otelCol.ObjectMeta, ComponentOpenTelemetryCollector), + MatchLabels: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -60,21 +55,21 @@ func DaemonSet(params manifests.Params) (*appsv1.DaemonSet, error) { Annotations: podAnnotations, }, Spec: corev1.PodSpec{ - ServiceAccountName: ServiceAccountName(otelCol), + ServiceAccountName: ServiceAccountName(params.OtelCol), InitContainers: params.OtelCol.Spec.InitContainers, - Containers: append(params.OtelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, otelCol, true)), - Volumes: Volumes(params.Config, otelCol), - Tolerations: otelCol.Spec.Tolerations, - NodeSelector: otelCol.Spec.NodeSelector, - HostNetwork: otelCol.Spec.HostNetwork, - ShareProcessNamespace: &otelCol.Spec.ShareProcessNamespace, - DNSPolicy: getDNSPolicy(otelCol), + Containers: append(params.OtelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, params.OtelCol, true)), + Volumes: Volumes(params.Config, params.OtelCol), + Tolerations: params.OtelCol.Spec.Tolerations, + NodeSelector: params.OtelCol.Spec.NodeSelector, + HostNetwork: params.OtelCol.Spec.HostNetwork, + ShareProcessNamespace: ¶ms.OtelCol.Spec.ShareProcessNamespace, + DNSPolicy: getDNSPolicy(params.OtelCol), SecurityContext: params.OtelCol.Spec.PodSecurityContext, PriorityClassName: params.OtelCol.Spec.PriorityClassName, Affinity: params.OtelCol.Spec.Affinity, }, }, - UpdateStrategy: params.OtelCol.Spec.UpdateStrategy, + UpdateStrategy: params.OtelCol.Spec.DaemonSetUpdateStrategy, }, }, nil } diff --git a/internal/manifests/collector/daemonset_test.go b/internal/manifests/collector/daemonset_test.go index 53acfb0b79..da86c2afe8 100644 --- a/internal/manifests/collector/daemonset_test.go +++ b/internal/manifests/collector/daemonset_test.go @@ -24,7 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" . "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector" @@ -34,13 +34,15 @@ func TestDaemonSetNewDefault(t *testing.T) { // prepare params := manifests.Params{ Config: config.New(), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Tolerations: testTolerationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Tolerations: testTolerationValues, + }, }, }, Log: logger, @@ -96,12 +98,12 @@ func TestDaemonSetNewDefault(t *testing.T) { func TestDaemonsetHostNetwork(t *testing.T) { params1 := manifests.Params{ Config: config.New(), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + Spec: v1alpha2.OpenTelemetryCollectorSpec{}, }, Log: logger, } @@ -114,13 +116,15 @@ func TestDaemonsetHostNetwork(t *testing.T) { // verify custom params2 := manifests.Params{ Config: config.New(), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + }, }, }, Log: logger, @@ -134,12 +138,14 @@ func TestDaemonsetHostNetwork(t *testing.T) { func TestDaemonsetPodAnnotations(t *testing.T) { // prepare testPodAnnotationValues := map[string]string{"annotation-key": "annotation-value"} - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodAnnotations: testPodAnnotationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodAnnotations: testPodAnnotationValues, + }, }, } cfg := config.New() @@ -176,15 +182,17 @@ func TestDaemonstPodSecurityContext(t *testing.T) { runAsUser := int64(1337) runasGroup := int64(1338) - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodSecurityContext: &v1.PodSecurityContext{ - RunAsNonRoot: &runAsNonRoot, - RunAsUser: &runAsUser, - RunAsGroup: &runasGroup, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodSecurityContext: &v1.PodSecurityContext{ + RunAsNonRoot: &runAsNonRoot, + RunAsUser: &runAsUser, + RunAsGroup: &runasGroup, + }, }, }, } @@ -211,12 +219,12 @@ func TestDaemonsetFilterLabels(t *testing.T) { "app.foo.bar": "1", } - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Labels: excludedLabels, }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + Spec: v1alpha2.OpenTelemetryCollectorSpec{}, } cfg := config.New(config.WithLabelFilters([]string{"foo*", "app.*.bar"})) @@ -238,7 +246,7 @@ func TestDaemonsetFilterLabels(t *testing.T) { func TestDaemonSetNodeSelector(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -258,14 +266,16 @@ func TestDaemonSetNodeSelector(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.NodeSelector) // Test nodeSelector - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-nodeselector", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, - NodeSelector: map[string]string{ - "node-key": "node-value", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + NodeSelector: map[string]string{ + "node-key": "node-value", + }, }, }, } @@ -284,7 +294,7 @@ func TestDaemonSetNodeSelector(t *testing.T) { } func TestDaemonSetPriorityClassName(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -304,12 +314,14 @@ func TestDaemonSetPriorityClassName(t *testing.T) { priorityClassName := "test-class" - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PriorityClassName: priorityClassName, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PriorityClassName: priorityClassName, + }, }, } @@ -327,7 +339,7 @@ func TestDaemonSetPriorityClassName(t *testing.T) { } func TestDaemonSetAffinity(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -345,12 +357,14 @@ func TestDaemonSetAffinity(t *testing.T) { require.NoError(t, err) assert.Nil(t, d1.Spec.Template.Spec.Affinity) - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Affinity: testAffinityValue, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Affinity: testAffinityValue, + }, }, } @@ -370,15 +384,17 @@ func TestDaemonSetAffinity(t *testing.T) { func TestDaemonSetInitContainer(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - InitContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + InitContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -404,15 +420,17 @@ func TestDaemonSetInitContainer(t *testing.T) { func TestDaemonSetAdditionalContainer(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - AdditionalContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + AdditionalContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -439,13 +457,13 @@ func TestDaemonSetAdditionalContainer(t *testing.T) { func TestDaemonSetDefaultUpdateStrategy(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - UpdateStrategy: appsv1.DaemonSetUpdateStrategy{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + DaemonSetUpdateStrategy: appsv1.DaemonSetUpdateStrategy{ Type: "RollingUpdate", RollingUpdate: &appsv1.RollingUpdateDaemonSet{ MaxSurge: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)}, @@ -474,13 +492,13 @@ func TestDaemonSetDefaultUpdateStrategy(t *testing.T) { func TestDaemonSetOnDeleteUpdateStrategy(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - UpdateStrategy: appsv1.DaemonSetUpdateStrategy{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + DaemonSetUpdateStrategy: appsv1.DaemonSetUpdateStrategy{ Type: "OnDelete", RollingUpdate: &appsv1.RollingUpdateDaemonSet{ MaxSurge: &intstr.IntOrString{Type: intstr.Int, IntVal: int32(1)}, @@ -510,11 +528,11 @@ func TestDaemonSetOnDeleteUpdateStrategy(t *testing.T) { func TestDaemonsetShareProcessNamespace(t *testing.T) { params1 := manifests.Params{ Config: config.New(), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + Spec: v1alpha2.OpenTelemetryCollectorSpec{}, }, Log: logger, } @@ -526,12 +544,14 @@ func TestDaemonsetShareProcessNamespace(t *testing.T) { // verify custom params2 := manifests.Params{ Config: config.New(), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-with-shareprocessnamespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - ShareProcessNamespace: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + ShareProcessNamespace: true, + }, }, }, Log: logger, diff --git a/internal/manifests/collector/deployment.go b/internal/manifests/collector/deployment.go index a960d3ec11..58e80a2d7e 100644 --- a/internal/manifests/collector/deployment.go +++ b/internal/manifests/collector/deployment.go @@ -19,7 +19,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -27,19 +26,15 @@ import ( // Deployment builds the deployment for the given instance. func Deployment(params manifests.Params) (*appsv1.Deployment, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.Collector(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + name := naming.Collector(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) - annotations, err := Annotations(otelCol) + annotations, err := Annotations(params.OtelCol) if err != nil { return nil, err } - podAnnotations, err := PodAnnotations(otelCol) + podAnnotations, err := PodAnnotations(params.OtelCol) if err != nil { return nil, err } @@ -47,36 +42,36 @@ func Deployment(params manifests.Params) (*appsv1.Deployment, error) { return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: otelCol.Namespace, + Namespace: params.OtelCol.Namespace, Labels: labels, Annotations: annotations, }, Spec: appsv1.DeploymentSpec{ - Replicas: otelCol.Spec.Replicas, + Replicas: params.OtelCol.Spec.Replicas, Selector: &metav1.LabelSelector{ - MatchLabels: manifestutils.SelectorLabels(otelCol.ObjectMeta, ComponentOpenTelemetryCollector), + MatchLabels: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), }, - Strategy: otelCol.Spec.DeploymentUpdateStrategy, + Strategy: params.OtelCol.Spec.DeploymentUpdateStrategy, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: labels, Annotations: podAnnotations, }, Spec: corev1.PodSpec{ - ServiceAccountName: ServiceAccountName(otelCol), - InitContainers: otelCol.Spec.InitContainers, - Containers: append(otelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, otelCol, true)), - Volumes: Volumes(params.Config, otelCol), - DNSPolicy: getDNSPolicy(otelCol), - HostNetwork: otelCol.Spec.HostNetwork, - ShareProcessNamespace: &otelCol.Spec.ShareProcessNamespace, - Tolerations: otelCol.Spec.Tolerations, - NodeSelector: otelCol.Spec.NodeSelector, - SecurityContext: otelCol.Spec.PodSecurityContext, - PriorityClassName: otelCol.Spec.PriorityClassName, - Affinity: otelCol.Spec.Affinity, - TerminationGracePeriodSeconds: otelCol.Spec.TerminationGracePeriodSeconds, - TopologySpreadConstraints: otelCol.Spec.TopologySpreadConstraints, + ServiceAccountName: ServiceAccountName(params.OtelCol), + InitContainers: params.OtelCol.Spec.InitContainers, + Containers: append(params.OtelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, params.OtelCol, true)), + Volumes: Volumes(params.Config, params.OtelCol), + DNSPolicy: getDNSPolicy(params.OtelCol), + HostNetwork: params.OtelCol.Spec.HostNetwork, + ShareProcessNamespace: ¶ms.OtelCol.Spec.ShareProcessNamespace, + Tolerations: params.OtelCol.Spec.Tolerations, + NodeSelector: params.OtelCol.Spec.NodeSelector, + SecurityContext: params.OtelCol.Spec.PodSecurityContext, + PriorityClassName: params.OtelCol.Spec.PriorityClassName, + Affinity: params.OtelCol.Spec.Affinity, + TerminationGracePeriodSeconds: params.OtelCol.Spec.TerminationGracePeriodSeconds, + TopologySpreadConstraints: params.OtelCol.Spec.TopologySpreadConstraints, }, }, }, diff --git a/internal/manifests/collector/deployment_test.go b/internal/manifests/collector/deployment_test.go index c254fbcda8..8d33edabd9 100644 --- a/internal/manifests/collector/deployment_test.go +++ b/internal/manifests/collector/deployment_test.go @@ -24,7 +24,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" . "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector" @@ -71,13 +71,15 @@ var testTopologySpreadConstraintValue = []v1.TopologySpreadConstraint{ func TestDeploymentNewDefault(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Tolerations: testTolerationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Tolerations: testTolerationValues, + }, }, } cfg := config.New() @@ -138,12 +140,14 @@ func TestDeploymentNewDefault(t *testing.T) { func TestDeploymentPodAnnotations(t *testing.T) { // prepare testPodAnnotationValues := map[string]string{"annotation-key": "annotation-value"} - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodAnnotations: testPodAnnotationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodAnnotations: testPodAnnotationValues, + }, }, } cfg := config.New() @@ -180,15 +184,17 @@ func TestDeploymenttPodSecurityContext(t *testing.T) { runAsUser := int64(1337) runasGroup := int64(1338) - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodSecurityContext: &v1.PodSecurityContext{ - RunAsNonRoot: &runAsNonRoot, - RunAsUser: &runAsUser, - RunAsGroup: &runasGroup, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodSecurityContext: &v1.PodSecurityContext{ + RunAsNonRoot: &runAsNonRoot, + RunAsUser: &runAsUser, + RunAsGroup: &runasGroup, + }, }, }, } @@ -210,11 +216,11 @@ func TestDeploymenttPodSecurityContext(t *testing.T) { } func TestDeploymentUpdateStrategy(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ DeploymentUpdateStrategy: appsv1.DeploymentStrategy{ Type: "RollingUpdate", RollingUpdate: &appsv1.RollingUpdateDeployment{ @@ -243,7 +249,7 @@ func TestDeploymentUpdateStrategy(t *testing.T) { func TestDeploymentHostNetwork(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -264,12 +270,14 @@ func TestDeploymentHostNetwork(t *testing.T) { assert.Equal(t, d1.Spec.Template.Spec.DNSPolicy, v1.DNSClusterFirst) // Test hostNetwork=true - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-hostnetwork", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + }, }, } @@ -293,12 +301,12 @@ func TestDeploymentFilterLabels(t *testing.T) { "app.foo.bar": "1", } - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Labels: excludedLabels, }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + Spec: v1alpha2.OpenTelemetryCollectorSpec{}, } cfg := config.New(config.WithLabelFilters([]string{"foo*", "app.*.bar"})) @@ -320,7 +328,7 @@ func TestDeploymentFilterLabels(t *testing.T) { func TestDeploymentNodeSelector(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -340,14 +348,16 @@ func TestDeploymentNodeSelector(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.NodeSelector) // Test nodeSelector - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-nodeselector", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, - NodeSelector: map[string]string{ - "node-key": "node-value", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + NodeSelector: map[string]string{ + "node-key": "node-value", + }, }, }, } @@ -366,7 +376,7 @@ func TestDeploymentNodeSelector(t *testing.T) { } func TestDeploymentPriorityClassName(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -386,12 +396,14 @@ func TestDeploymentPriorityClassName(t *testing.T) { priorityClassName := "test-class" - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PriorityClassName: priorityClassName, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PriorityClassName: priorityClassName, + }, }, } @@ -409,7 +421,7 @@ func TestDeploymentPriorityClassName(t *testing.T) { } func TestDeploymentAffinity(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -427,12 +439,14 @@ func TestDeploymentAffinity(t *testing.T) { require.NoError(t, err) assert.Nil(t, d1.Spec.Template.Spec.Affinity) - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Affinity: testAffinityValue, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Affinity: testAffinityValue, + }, }, } @@ -451,7 +465,7 @@ func TestDeploymentAffinity(t *testing.T) { } func TestDeploymentTerminationGracePeriodSeconds(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -471,12 +485,14 @@ func TestDeploymentTerminationGracePeriodSeconds(t *testing.T) { gracePeriodSec := int64(60) - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-terminationGracePeriodSeconds", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TerminationGracePeriodSeconds: &gracePeriodSec, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + TerminationGracePeriodSeconds: &gracePeriodSec, + }, }, } @@ -496,15 +512,17 @@ func TestDeploymentTerminationGracePeriodSeconds(t *testing.T) { func TestDeploymentSetInitContainer(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - InitContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + InitContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -530,7 +548,7 @@ func TestDeploymentSetInitContainer(t *testing.T) { func TestDeploymentTopologySpreadConstraints(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -549,12 +567,14 @@ func TestDeploymentTopologySpreadConstraints(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.TopologySpreadConstraints) // Test TopologySpreadConstraints - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-topologyspreadconstraint", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TopologySpreadConstraints: testTopologySpreadConstraintValue, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + TopologySpreadConstraints: testTopologySpreadConstraintValue, + }, }, } @@ -575,15 +595,17 @@ func TestDeploymentTopologySpreadConstraints(t *testing.T) { func TestDeploymentAdditionalContainers(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - AdditionalContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + AdditionalContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -610,7 +632,7 @@ func TestDeploymentAdditionalContainers(t *testing.T) { func TestDeploymentShareProcessNamespace(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -629,12 +651,14 @@ func TestDeploymentShareProcessNamespace(t *testing.T) { assert.False(t, *d1.Spec.Template.Spec.ShareProcessNamespace) // Test hostNetwork=true - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-with-shareprocessnamespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - ShareProcessNamespace: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + ShareProcessNamespace: true, + }, }, } diff --git a/internal/manifests/collector/horizontalpodautoscaler.go b/internal/manifests/collector/horizontalpodautoscaler.go index 9b176ebc18..43c0b4354d 100644 --- a/internal/manifests/collector/horizontalpodautoscaler.go +++ b/internal/manifests/collector/horizontalpodautoscaler.go @@ -21,20 +21,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) func HorizontalPodAutoscaler(params manifests.Params) (client.Object, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.Collector(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) - annotations, err := Annotations(otelCol) + name := naming.Collector(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + annotations, err := Annotations(params.OtelCol) if err != nil { return nil, err } @@ -42,54 +37,42 @@ func HorizontalPodAutoscaler(params manifests.Params) (client.Object, error) { var result client.Object objectMeta := metav1.ObjectMeta{ - Name: naming.HorizontalPodAutoscaler(otelCol.Name), - Namespace: otelCol.Namespace, + Name: naming.HorizontalPodAutoscaler(params.OtelCol.Name), + Namespace: params.OtelCol.Namespace, Labels: labels, Annotations: annotations, } // defaulting webhook should always set this, but if unset then return nil. - if otelCol.Spec.Autoscaler == nil { + if params.OtelCol.Spec.Autoscaler == nil { params.Log.Info("hpa field is unset in Spec, skipping autoscaler creation") return nil, nil } - if otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MaxReplicas == nil { - otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MaxReplicas = params.OtelCol.Spec.MaxReplicas - } - - if otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas == nil { - if params.OtelCol.Spec.MinReplicas != nil { - otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas = params.OtelCol.Spec.MinReplicas - } else { - otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas = params.OtelCol.Spec.Replicas - } - } - metrics := []autoscalingv2.MetricSpec{} - if otelCol.Spec.Autoscaler.TargetMemoryUtilization != nil { + if params.OtelCol.Spec.Autoscaler.TargetMemoryUtilization != nil { memoryTarget := autoscalingv2.MetricSpec{ Type: autoscalingv2.ResourceMetricSourceType, Resource: &autoscalingv2.ResourceMetricSource{ Name: corev1.ResourceMemory, Target: autoscalingv2.MetricTarget{ Type: autoscalingv2.UtilizationMetricType, - AverageUtilization: otelCol.Spec.Autoscaler.TargetMemoryUtilization, + AverageUtilization: params.OtelCol.Spec.Autoscaler.TargetMemoryUtilization, }, }, } metrics = append(metrics, memoryTarget) } - if otelCol.Spec.Autoscaler.TargetCPUUtilization != nil { + if params.OtelCol.Spec.Autoscaler.TargetCPUUtilization != nil { cpuTarget := autoscalingv2.MetricSpec{ Type: autoscalingv2.ResourceMetricSourceType, Resource: &autoscalingv2.ResourceMetricSource{ Name: corev1.ResourceCPU, Target: autoscalingv2.MetricTarget{ Type: autoscalingv2.UtilizationMetricType, - AverageUtilization: otelCol.Spec.Autoscaler.TargetCPUUtilization, + AverageUtilization: params.OtelCol.Spec.Autoscaler.TargetCPUUtilization, }, }, } @@ -102,24 +85,24 @@ func HorizontalPodAutoscaler(params manifests.Params) (client.Object, error) { ScaleTargetRef: autoscalingv2.CrossVersionObjectReference{ APIVersion: v1alpha1.GroupVersion.String(), Kind: "OpenTelemetryCollector", - Name: naming.OpenTelemetryCollector(otelCol.Name), + Name: naming.OpenTelemetryCollector(params.OtelCol.Name), }, - MinReplicas: otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas, + MinReplicas: params.OtelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas, MaxReplicas: func(max *int32) int32 { if max == nil { return 0 } return *max - }(otelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MaxReplicas), + }(params.OtelCol.Spec.OpenTelemetryCommonFields.Autoscaler.MaxReplicas), Metrics: metrics, }, } - if otelCol.Spec.Autoscaler.Behavior != nil { - autoscaler.Spec.Behavior = otelCol.Spec.Autoscaler.Behavior + if params.OtelCol.Spec.Autoscaler.Behavior != nil { + autoscaler.Spec.Behavior = params.OtelCol.Spec.Autoscaler.Behavior } // convert from v1alpha1.MetricSpec into a autoscalingv2.MetricSpec. - for _, metric := range otelCol.Spec.Autoscaler.Metrics { + for _, metric := range params.OtelCol.Spec.Autoscaler.Metrics { if metric.Type == autoscalingv2.PodsMetricSourceType { v2metric := autoscalingv2.MetricSpec{ Type: metric.Type, diff --git a/internal/manifests/collector/horizontalpodautoscaler_test.go b/internal/manifests/collector/horizontalpodautoscaler_test.go index 62ac2eb460..79f2074dc2 100644 --- a/internal/manifests/collector/horizontalpodautoscaler_test.go +++ b/internal/manifests/collector/horizontalpodautoscaler_test.go @@ -23,7 +23,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" @@ -81,14 +80,16 @@ func TestHPA(t *testing.T) { configuration := config.New() params := manifests.Params{ Config: configuration, - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: otelcol.ObjectMeta, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - MinReplicas: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.MinReplicas, - MaxReplicas: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.MaxReplicas, - Autoscaler: &v1alpha1.AutoscalerSpec{ - TargetCPUUtilization: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.TargetCPUUtilization, - TargetMemoryUtilization: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.TargetMemoryUtilization, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Autoscaler: &v1alpha2.AutoscalerSpec{ + MinReplicas: otelcol.Spec.Autoscaler.MinReplicas, + MaxReplicas: otelcol.Spec.Autoscaler.MaxReplicas, + TargetCPUUtilization: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.TargetCPUUtilization, + TargetMemoryUtilization: otelcol.Spec.OpenTelemetryCommonFields.Autoscaler.TargetMemoryUtilization, + }, }, }, }, diff --git a/internal/manifests/collector/ingress.go b/internal/manifests/collector/ingress.go index 8875949c95..2992aa941f 100644 --- a/internal/manifests/collector/ingress.go +++ b/internal/manifests/collector/ingress.go @@ -23,22 +23,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "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" ) func Ingress(params manifests.Params) (*networkingv1.Ingress, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - if otelCol.Spec.Ingress.Type != v1alpha2.IngressTypeNginx { + if params.OtelCol.Spec.Ingress.Type != v1alpha2.IngressTypeNginx { return nil, nil } - ports, err := servicePortsFromCfg(params.Log, otelCol) + ports, err := servicePortsFromCfg(params.Log, params.OtelCol) // if we have no ports, we don't need a ingress entry if len(ports) == 0 || err != nil { @@ -51,28 +46,28 @@ func Ingress(params manifests.Params) (*networkingv1.Ingress, error) { } var rules []networkingv1.IngressRule - switch otelCol.Spec.Ingress.RuleType { + switch params.OtelCol.Spec.Ingress.RuleType { case v1alpha2.IngressRuleTypePath, "": - rules = []networkingv1.IngressRule{createPathIngressRules(otelCol.Name, otelCol.Spec.Ingress.Hostname, ports)} + rules = []networkingv1.IngressRule{createPathIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports)} case v1alpha2.IngressRuleTypeSubdomain: - rules = createSubdomainIngressRules(otelCol.Name, otelCol.Spec.Ingress.Hostname, ports) + rules = createSubdomainIngressRules(params.OtelCol.Name, params.OtelCol.Spec.Ingress.Hostname, ports) } return &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: naming.Ingress(otelCol.Name), - Namespace: otelCol.Namespace, - Annotations: otelCol.Spec.Ingress.Annotations, + Name: naming.Ingress(params.OtelCol.Name), + Namespace: params.OtelCol.Namespace, + Annotations: params.OtelCol.Spec.Ingress.Annotations, Labels: map[string]string{ - "app.kubernetes.io/name": naming.Ingress(otelCol.Name), - "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otelCol.Namespace, otelCol.Name), + "app.kubernetes.io/name": naming.Ingress(params.OtelCol.Name), + "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name), "app.kubernetes.io/managed-by": "opentelemetry-operator", }, }, Spec: networkingv1.IngressSpec{ - TLS: otelCol.Spec.Ingress.TLS, + TLS: params.OtelCol.Spec.Ingress.TLS, Rules: rules, - IngressClassName: otelCol.Spec.Ingress.IngressClassName, + IngressClassName: params.OtelCol.Spec.Ingress.IngressClassName, }, }, nil } diff --git a/internal/manifests/collector/ingress_test.go b/internal/manifests/collector/ingress_test.go index 8fb2103720..5dbede9a93 100644 --- a/internal/manifests/collector/ingress_test.go +++ b/internal/manifests/collector/ingress_test.go @@ -23,11 +23,9 @@ import ( networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/naming" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" ) @@ -39,10 +37,10 @@ func TestDesiredIngresses(t *testing.T) { params := manifests.Params{ Config: config.Config{}, Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressType("unknown"), + OtelCol: v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Ingress: v1alpha2.Ingress{ + Type: v1alpha2.IngressType("unknown"), }, }, }, @@ -53,37 +51,15 @@ func TestDesiredIngresses(t *testing.T) { assert.NoError(t, err) }) - t.Run("should return nil unable to parse config", func(t *testing.T) { - params := manifests.Params{ - Config: config.Config{}, - Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Config: "!!!", - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeNginx, - }, - }, - }, - } - - actual, err := Ingress(params) - fmt.Printf("error1: %+v", err) - assert.Nil(t, actual) - assert.ErrorContains(t, err, "could not convert config json to v1alpha2.Config") - }) - t.Run("should return nil unable to parse receiver ports", func(t *testing.T) { params := manifests.Params{ Config: config.Config{}, Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Config: `exporters: - nothing: -`, - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeNginx, + OtelCol: v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Config: v1alpha2.Config{}, + Ingress: v1alpha2.Ingress{ + Type: v1alpha2.IngressTypeNginx, }, }, }, @@ -106,11 +82,8 @@ func TestDesiredIngresses(t *testing.T) { t.Fatal(err) } - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - assert.Nil(t, err) - - otelCol.Namespace = ns - otelCol.Spec.Ingress = v1alpha2.Ingress{ + params.OtelCol.Namespace = ns + params.OtelCol.Spec.Ingress = v1alpha2.Ingress{ Type: v1alpha2.IngressTypeNginx, Hostname: hostname, Annotations: map[string]string{"some.key": "some.value"}, @@ -124,12 +97,12 @@ func TestDesiredIngresses(t *testing.T) { assert.NotEqual(t, &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: naming.Ingress(otelCol.Name), + Name: naming.Ingress(params.OtelCol.Name), Namespace: ns, - Annotations: otelCol.Spec.Ingress.Annotations, + Annotations: params.OtelCol.Spec.Ingress.Annotations, Labels: map[string]string{ - "app.kubernetes.io/name": naming.Ingress(otelCol.Name), - "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otelCol.Namespace, otelCol.Name), + "app.kubernetes.io/name": naming.Ingress(params.OtelCol.Name), + "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name), "app.kubernetes.io/managed-by": "opentelemetry-operator", }, }, @@ -197,11 +170,8 @@ func TestDesiredIngresses(t *testing.T) { t.Fatal(err) } - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - assert.Nil(t, err) - - otelCol.Namespace = ns - otelCol.Spec.Ingress = v1alpha2.Ingress{ + params.OtelCol.Namespace = ns + params.OtelCol.Spec.Ingress = v1alpha2.Ingress{ Type: v1alpha2.IngressTypeNginx, RuleType: v1alpha2.IngressRuleTypeSubdomain, Hostname: hostname, @@ -216,12 +186,12 @@ func TestDesiredIngresses(t *testing.T) { assert.NotEqual(t, &networkingv1.Ingress{ ObjectMeta: metav1.ObjectMeta{ - Name: naming.Ingress(otelCol.Name), + Name: naming.Ingress(params.OtelCol.Name), Namespace: ns, - Annotations: otelCol.Spec.Ingress.Annotations, + Annotations: params.OtelCol.Spec.Ingress.Annotations, Labels: map[string]string{ - "app.kubernetes.io/name": naming.Ingress(otelCol.Name), - "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otelCol.Namespace, otelCol.Name), + "app.kubernetes.io/name": naming.Ingress(params.OtelCol.Name), + "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name), "app.kubernetes.io/managed-by": "opentelemetry-operator", }, }, diff --git a/internal/manifests/collector/poddisruptionbudget.go b/internal/manifests/collector/poddisruptionbudget.go index be2a20e52c..73fe774da0 100644 --- a/internal/manifests/collector/poddisruptionbudget.go +++ b/internal/manifests/collector/poddisruptionbudget.go @@ -18,33 +18,28 @@ import ( policyV1 "k8s.io/api/policy/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) func PodDisruptionBudget(params manifests.Params) (*policyV1.PodDisruptionBudget, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } // defaulting webhook should always set this, but if unset then return nil. - if otelCol.Spec.PodDisruptionBudget == nil { + if params.OtelCol.Spec.PodDisruptionBudget == nil { params.Log.Info("pdb field is unset in Spec, skipping podDisruptionBudget creation") return nil, nil } - name := naming.Collector(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) - annotations, err := Annotations(otelCol) + name := naming.Collector(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + annotations, err := Annotations(params.OtelCol) if err != nil { return nil, err } objectMeta := metav1.ObjectMeta{ - Name: naming.PodDisruptionBudget(otelCol.Name), - Namespace: otelCol.Namespace, + Name: naming.PodDisruptionBudget(params.OtelCol.Name), + Namespace: params.OtelCol.Namespace, Labels: labels, Annotations: annotations, } @@ -52,8 +47,8 @@ func PodDisruptionBudget(params manifests.Params) (*policyV1.PodDisruptionBudget return &policyV1.PodDisruptionBudget{ ObjectMeta: objectMeta, Spec: policyV1.PodDisruptionBudgetSpec{ - MinAvailable: otelCol.Spec.PodDisruptionBudget.MinAvailable, - MaxUnavailable: otelCol.Spec.PodDisruptionBudget.MaxUnavailable, + MinAvailable: params.OtelCol.Spec.PodDisruptionBudget.MinAvailable, + MaxUnavailable: params.OtelCol.Spec.PodDisruptionBudget.MaxUnavailable, Selector: &metav1.LabelSelector{ MatchLabels: objectMeta.Labels, }, diff --git a/internal/manifests/collector/poddisruptionbudget_test.go b/internal/manifests/collector/poddisruptionbudget_test.go index 9adbcd515d..b759d4b677 100644 --- a/internal/manifests/collector/poddisruptionbudget_test.go +++ b/internal/manifests/collector/poddisruptionbudget_test.go @@ -22,7 +22,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" . "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector" @@ -65,7 +65,7 @@ func TestPDB(t *testing.T) { }, } - otelcols := []v1alpha1.OpenTelemetryCollector{ + otelcols := []v1alpha2.OpenTelemetryCollector{ { ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", @@ -76,7 +76,7 @@ func TestPDB(t *testing.T) { for _, otelcol := range otelcols { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - otelcol.Spec.PodDisruptionBudget = &v1alpha1.PodDisruptionBudgetSpec{ + otelcol.Spec.PodDisruptionBudget = &v1alpha2.PodDisruptionBudgetSpec{ MinAvailable: test.MinAvailable, MaxUnavailable: test.MaxUnavailable, } diff --git a/internal/manifests/collector/podmonitor.go b/internal/manifests/collector/podmonitor.go index 428d2673a0..f51c7c95b1 100644 --- a/internal/manifests/collector/podmonitor.go +++ b/internal/manifests/collector/podmonitor.go @@ -22,7 +22,7 @@ import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "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" @@ -39,7 +39,7 @@ func PodMonitor(params manifests.Params) (*monitoringv1.PodMonitor, error) { } var pm monitoringv1.PodMonitor - if params.OtelCol.Spec.Mode != v1alpha1.ModeSidecar { + if params.OtelCol.Spec.Mode != v1alpha2.ModeSidecar { return nil, nil } @@ -77,8 +77,14 @@ func PodMonitor(params manifests.Params) (*monitoringv1.PodMonitor, error) { return &pm, nil } -func metricsEndpointsFromConfig(logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) []monitoringv1.PodMetricsEndpoint { - config, err := adapters.ConfigFromString(otelcol.Spec.Config) +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{} diff --git a/internal/manifests/collector/podmonitor_test.go b/internal/manifests/collector/podmonitor_test.go index 9066b50cbc..2feaa996c8 100644 --- a/internal/manifests/collector/podmonitor_test.go +++ b/internal/manifests/collector/podmonitor_test.go @@ -16,17 +16,16 @@ package collector import ( "fmt" + "testing" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/stretchr/testify/assert" - - "testing" ) func sidecarParams() manifests.Params { - return paramsWithMode(v1alpha1.ModeSidecar) + return paramsWithMode(v1alpha2.ModeSidecar) } func TestDesiredPodMonitors(t *testing.T) { @@ -46,7 +45,7 @@ func TestDesiredPodMonitors(t *testing.T) { params, err = newParams("", "testdata/prometheus-exporter.yaml") assert.NoError(t, err) - params.OtelCol.Spec.Mode = v1alpha1.ModeSidecar + params.OtelCol.Spec.Mode = v1alpha2.ModeSidecar params.OtelCol.Spec.Observability.Metrics.EnableMetrics = true actual, err = PodMonitor(params) assert.NoError(t, err) diff --git a/internal/manifests/collector/rbac.go b/internal/manifests/collector/rbac.go index f1746f9cd3..4af9223996 100644 --- a/internal/manifests/collector/rbac.go +++ b/internal/manifests/collector/rbac.go @@ -18,7 +18,6 @@ import ( rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "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" @@ -26,12 +25,7 @@ import ( ) func ClusterRole(params manifests.Params) (*rbacv1.ClusterRole, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - - confStr, err := otelCol.Spec.Config.Yaml() + confStr, err := params.OtelCol.Spec.Config.Yaml() if err != nil { return nil, err } @@ -61,11 +55,7 @@ func ClusterRole(params manifests.Params) (*rbacv1.ClusterRole, error) { } func ClusterRoleBinding(params manifests.Params) (*rbacv1.ClusterRoleBinding, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - confStr, err := otelCol.Spec.Config.Yaml() + confStr, err := params.OtelCol.Spec.Config.Yaml() if err != nil { return nil, err } @@ -80,25 +70,25 @@ func ClusterRoleBinding(params manifests.Params) (*rbacv1.ClusterRoleBinding, er return nil, nil } - name := naming.ClusterRoleBinding(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + name := naming.ClusterRoleBinding(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) return &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Annotations: otelCol.Annotations, + Annotations: params.OtelCol.Annotations, Labels: labels, }, Subjects: []rbacv1.Subject{ { Kind: "ServiceAccount", - Name: ServiceAccountName(otelCol), - Namespace: otelCol.Namespace, + Name: ServiceAccountName(params.OtelCol), + Namespace: params.OtelCol.Namespace, }, }, RoleRef: rbacv1.RoleRef{ Kind: "ClusterRole", - Name: naming.ClusterRole(otelCol.Name, otelCol.Namespace), + Name: naming.ClusterRole(params.OtelCol.Name, params.OtelCol.Namespace), APIGroup: "rbac.authorization.k8s.io", }, }, nil diff --git a/internal/manifests/collector/route.go b/internal/manifests/collector/route.go index 494a0b73e4..b30fe59288 100644 --- a/internal/manifests/collector/route.go +++ b/internal/manifests/collector/route.go @@ -22,28 +22,23 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) func Routes(params manifests.Params) ([]*routev1.Route, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - if otelCol.Spec.Ingress.Type != v1alpha2.IngressTypeRoute || params.Config.OpenShiftRoutesAvailability() != openshift.RoutesAvailable { + if params.OtelCol.Spec.Ingress.Type != v1alpha2.IngressTypeRoute || params.Config.OpenShiftRoutesAvailability() != openshift.RoutesAvailable { return nil, nil } - if otelCol.Spec.Mode == v1alpha2.ModeSidecar { + if params.OtelCol.Spec.Mode == v1alpha2.ModeSidecar { params.Log.V(3).Info("ingress settings are not supported in sidecar mode") return nil, nil } var tlsCfg *routev1.TLSConfig - switch otelCol.Spec.Ingress.Route.Termination { + switch params.OtelCol.Spec.Ingress.Route.Termination { case v1alpha2.TLSRouteTerminationTypeInsecure: // NOTE: insecure, no tls cfg. case v1alpha2.TLSRouteTerminationTypeEdge: @@ -56,14 +51,14 @@ func Routes(params manifests.Params) ([]*routev1.Route, error) { return nil, nil } - ports, err := servicePortsFromCfg(params.Log, otelCol) + ports, err := servicePortsFromCfg(params.Log, params.OtelCol) // if we have no ports, we don't need a ingress entry if len(ports) == 0 || err != nil { params.Log.V(1).Info( "the instance's configuration didn't yield any ports to open, skipping ingress", - "instance.name", otelCol.Name, - "instance.namespace", otelCol.Namespace, + "instance.name", params.OtelCol.Name, + "instance.namespace", params.OtelCol.Namespace, ) return nil, err } @@ -72,18 +67,18 @@ func Routes(params manifests.Params) ([]*routev1.Route, error) { for i, p := range ports { portName := naming.PortName(p.Name, p.Port) host := "" - if otelCol.Spec.Ingress.Hostname != "" { + if params.OtelCol.Spec.Ingress.Hostname != "" { host = fmt.Sprintf("%s.%s", portName, params.OtelCol.Spec.Ingress.Hostname) } routes[i] = &routev1.Route{ ObjectMeta: metav1.ObjectMeta{ Name: naming.Route(params.OtelCol.Name, p.Name), - Namespace: otelCol.Namespace, - Annotations: otelCol.Spec.Ingress.Annotations, + Namespace: params.OtelCol.Namespace, + Annotations: params.OtelCol.Spec.Ingress.Annotations, Labels: map[string]string{ - "app.kubernetes.io/name": naming.Route(otelCol.Name, p.Name), - "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", otelCol.Namespace, otelCol.Name), + "app.kubernetes.io/name": naming.Route(params.OtelCol.Name, p.Name), + "app.kubernetes.io/instance": fmt.Sprintf("%s.%s", params.OtelCol.Namespace, params.OtelCol.Name), "app.kubernetes.io/managed-by": "opentelemetry-operator", "app.kubernetes.io/component": "opentelemetry-collector", }, diff --git a/internal/manifests/collector/route_test.go b/internal/manifests/collector/route_test.go index 374b4a0dee..2826f2dd37 100644 --- a/internal/manifests/collector/route_test.go +++ b/internal/manifests/collector/route_test.go @@ -25,7 +25,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -36,10 +36,10 @@ func TestDesiredRoutes(t *testing.T) { params := manifests.Params{ Config: config.Config{}, Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressType("unknown"), + OtelCol: v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Ingress: v1alpha2.Ingress{ + Type: v1alpha2.IngressType("unknown"), }, }, }, @@ -50,39 +50,17 @@ func TestDesiredRoutes(t *testing.T) { assert.Nil(t, actual) }) - t.Run("should return nil unable to parse config", func(t *testing.T) { - params := manifests.Params{ - Config: config.Config{}, - Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Config: "!!!", - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeRoute, - Route: v1alpha1.OpenShiftRoute{ - Termination: v1alpha1.TLSRouteTerminationTypeInsecure, - }, - }, - }, - }, - } - - actual, err := Routes(params) - assert.Nil(t, actual) - assert.ErrorContains(t, err, "could not convert config json to v1alpha2.Config") - }) - t.Run("should return nil unable to parse receiver ports", func(t *testing.T) { params := manifests.Params{ Config: config.Config{}, Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Config: "---", - Ingress: v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeRoute, - Route: v1alpha1.OpenShiftRoute{ - Termination: v1alpha1.TLSRouteTerminationTypeInsecure, + OtelCol: v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Config: v1alpha2.Config{}, + Ingress: v1alpha2.Ingress{ + Type: v1alpha2.IngressTypeRoute, + Route: v1alpha2.OpenShiftRoute{ + Termination: v1alpha2.TLSRouteTerminationTypeInsecure, }, }, }, @@ -106,12 +84,12 @@ func TestDesiredRoutes(t *testing.T) { } params.OtelCol.Namespace = ns - params.OtelCol.Spec.Ingress = v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeRoute, + params.OtelCol.Spec.Ingress = v1alpha2.Ingress{ + Type: v1alpha2.IngressTypeRoute, Hostname: hostname, Annotations: map[string]string{"some.key": "some.value"}, - Route: v1alpha1.OpenShiftRoute{ - Termination: v1alpha1.TLSRouteTerminationTypeInsecure, + Route: v1alpha2.OpenShiftRoute{ + Termination: v1alpha2.TLSRouteTerminationTypeInsecure, }, } @@ -156,11 +134,11 @@ func TestDesiredRoutes(t *testing.T) { } params.OtelCol.Namespace = "test" - params.OtelCol.Spec.Ingress = v1alpha1.Ingress{ + params.OtelCol.Spec.Ingress = v1alpha2.Ingress{ Hostname: "example.com", - Type: v1alpha1.IngressTypeRoute, - Route: v1alpha1.OpenShiftRoute{ - Termination: v1alpha1.TLSRouteTerminationTypeInsecure, + Type: v1alpha2.IngressTypeRoute, + Route: v1alpha2.OpenShiftRoute{ + Termination: v1alpha2.TLSRouteTerminationTypeInsecure, }, } @@ -178,10 +156,10 @@ func TestDesiredRoutes(t *testing.T) { } params.OtelCol.Namespace = "test" - params.OtelCol.Spec.Ingress = v1alpha1.Ingress{ - Type: v1alpha1.IngressTypeRoute, - Route: v1alpha1.OpenShiftRoute{ - Termination: v1alpha1.TLSRouteTerminationTypeInsecure, + params.OtelCol.Spec.Ingress = v1alpha2.Ingress{ + Type: v1alpha2.IngressTypeRoute, + Route: v1alpha2.OpenShiftRoute{ + Termination: v1alpha2.TLSRouteTerminationTypeInsecure, }, } diff --git a/internal/manifests/collector/service.go b/internal/manifests/collector/service.go index b2b4035ac1..48b4d987d8 100644 --- a/internal/manifests/collector/service.go +++ b/internal/manifests/collector/service.go @@ -23,7 +23,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "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" @@ -42,12 +41,7 @@ func HeadlessService(params manifests.Params) (*corev1.Service, error) { return h, err } - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - - h.Name = naming.HeadlessService(otelCol.Name) + h.Name = naming.HeadlessService(params.OtelCol.Name) h.Labels[headlessLabel] = headlessExists // copy to avoid modifying params.OtelCol.Annotations @@ -64,15 +58,11 @@ func HeadlessService(params manifests.Params) (*corev1.Service, error) { } func MonitoringService(params manifests.Params) (*corev1.Service, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.MonitoringService(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) + name := naming.MonitoringService(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) - out, err := otelCol.Spec.Config.Yaml() + out, err := params.OtelCol.Spec.Config.Yaml() if err != nil { return nil, err } @@ -91,12 +81,12 @@ func MonitoringService(params manifests.Params) (*corev1.Service, error) { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: otelCol.Namespace, + Namespace: params.OtelCol.Namespace, Labels: labels, - Annotations: otelCol.Annotations, + Annotations: params.OtelCol.Annotations, }, Spec: corev1.ServiceSpec{ - Selector: manifestutils.SelectorLabels(otelCol.ObjectMeta, ComponentOpenTelemetryCollector), + Selector: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), ClusterIP: "", Ports: []corev1.ServicePort{{ Name: "monitoring", @@ -107,14 +97,10 @@ func MonitoringService(params manifests.Params) (*corev1.Service, error) { } func Service(params manifests.Params) (*corev1.Service, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.Service(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) + name := naming.Service(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) - out, err := otelCol.Spec.Config.Yaml() + out, err := params.OtelCol.Spec.Config.Yaml() if err != nil { return nil, err } @@ -134,12 +120,12 @@ func Service(params manifests.Params) (*corev1.Service, error) { // OpenShift uses HA proxy that uses appProtocol for its configuration. for i := range ports { h2c := "h2c" - if otelCol.Spec.Ingress.Type == v1alpha2.IngressTypeRoute && ports[i].AppProtocol != nil && strings.EqualFold(*ports[i].AppProtocol, "grpc") { + if params.OtelCol.Spec.Ingress.Type == v1alpha2.IngressTypeRoute && ports[i].AppProtocol != nil && strings.EqualFold(*ports[i].AppProtocol, "grpc") { ports[i].AppProtocol = &h2c } } - if len(otelCol.Spec.Ports) > 0 { + if len(params.OtelCol.Spec.Ports) > 0 { // we should add all the ports from the CR // there are two cases where problems might occur: // 1) when the port number is already being used by a receiver @@ -147,7 +133,7 @@ func Service(params manifests.Params) (*corev1.Service, error) { // // in the first case, we remove the port we inferred from the list // in the second case, we rename our inferred port to something like "port-%d" - portNumbers, portNames := extractPortNumbersAndNames(otelCol.Spec.Ports) + portNumbers, portNames := extractPortNumbersAndNames(params.OtelCol.Spec.Ports) var resultingInferredPorts []corev1.ServicePort for _, inferred := range ports { if filtered := filterPort(params.Log, inferred, portNumbers, portNames); filtered != nil { @@ -155,31 +141,31 @@ func Service(params manifests.Params) (*corev1.Service, error) { } } - ports = append(otelCol.Spec.Ports, resultingInferredPorts...) + ports = append(params.OtelCol.Spec.Ports, resultingInferredPorts...) } // if we have no ports, we don't need a service if len(ports) == 0 { - params.Log.V(1).Info("the instance's configuration didn't yield any ports to open, skipping service", "instance.name", otelCol.Name, "instance.namespace", otelCol.Namespace) + params.Log.V(1).Info("the instance's configuration didn't yield any ports to open, skipping service", "instance.name", params.OtelCol.Name, "instance.namespace", params.OtelCol.Namespace) return nil, err } trafficPolicy := corev1.ServiceInternalTrafficPolicyCluster - if otelCol.Spec.Mode == v1alpha2.ModeDaemonSet { + if params.OtelCol.Spec.Mode == v1alpha2.ModeDaemonSet { trafficPolicy = corev1.ServiceInternalTrafficPolicyLocal } return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: naming.Service(otelCol.Name), - Namespace: otelCol.Namespace, + Name: naming.Service(params.OtelCol.Name), + Namespace: params.OtelCol.Namespace, Labels: labels, - Annotations: otelCol.Annotations, + Annotations: params.OtelCol.Annotations, }, Spec: corev1.ServiceSpec{ InternalTrafficPolicy: &trafficPolicy, - Selector: manifestutils.SelectorLabels(otelCol.ObjectMeta, ComponentOpenTelemetryCollector), + Selector: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), ClusterIP: "", Ports: ports, }, diff --git a/internal/manifests/collector/service_test.go b/internal/manifests/collector/service_test.go index fcc6e5b8d7..ceb35fed81 100644 --- a/internal/manifests/collector/service_test.go +++ b/internal/manifests/collector/service_test.go @@ -24,7 +24,7 @@ import ( "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" ) @@ -99,11 +99,8 @@ func TestDesiredService(t *testing.T) { params := manifests.Params{ Config: config.Config{}, Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{Config: `receivers: - test: - protocols: - unknown:`}, + OtelCol: v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{Config: v1alpha2.Config{}}, }, } @@ -141,7 +138,7 @@ func TestDesiredService(t *testing.T) { params := deploymentParams() - params.OtelCol.Spec.Ingress.Type = v1alpha1.IngressTypeRoute + params.OtelCol.Spec.Ingress.Type = v1alpha2.IngressTypeRoute actual, err := Service(params) ports := append(params.OtelCol.Spec.Ports, jaegerPort) @@ -160,7 +157,7 @@ func TestDesiredService(t *testing.T) { Port: 14250, AppProtocol: &grpc, } - p := paramsWithMode(v1alpha1.ModeDaemonSet) + p := paramsWithMode(v1alpha2.ModeDaemonSet) ports := append(p.OtelCol.Spec.Ports, jaegerPorts) expected := serviceWithInternalTrafficPolicy("test-collector", ports, v1.ServiceInternalTrafficPolicyLocal) @@ -170,20 +167,6 @@ func TestDesiredService(t *testing.T) { assert.Equal(t, expected, *actual) }) - t.Run("should return nil unable to parse config", func(t *testing.T) { - params := manifests.Params{ - Config: config.Config{}, - Log: logger, - OtelCol: v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{Config: `!!!`}, - }, - } - - actual, err := Service(params) - assert.ErrorContains(t, err, "could not convert config json to v1alpha2.Config") - assert.Nil(t, actual) - - }) } func TestHeadlessService(t *testing.T) { @@ -216,11 +199,18 @@ func TestMonitoringService(t *testing.T) { Port: 9090, }} params := deploymentParams() - params.OtelCol.Spec.Config = `service: - telemetry: - metrics: - level: detailed - address: 0.0.0.0:9090` + params.OtelCol.Spec.Config = v1alpha2.Config{ + Service: v1alpha2.Service{ + Telemetry: &v1alpha2.AnyConfig{ + Object: map[string]interface{}{ + "metrics": map[string]interface{}{ + "level": "detailed", + "address": "0.0.0.0:9090", + }, + }, + }, + }, + } actual, err := MonitoringService(params) assert.NoError(t, err) diff --git a/internal/manifests/collector/serviceaccount.go b/internal/manifests/collector/serviceaccount.go index 3c1d48688c..d5f481dea0 100644 --- a/internal/manifests/collector/serviceaccount.go +++ b/internal/manifests/collector/serviceaccount.go @@ -19,7 +19,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -36,23 +35,19 @@ func ServiceAccountName(instance v1alpha2.OpenTelemetryCollector) string { // ServiceAccount returns the service account for the given instance. func ServiceAccount(params manifests.Params) (*corev1.ServiceAccount, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - if otelCol.Spec.ServiceAccount != "" { + if params.OtelCol.Spec.ServiceAccount != "" { return nil, nil } - name := naming.ServiceAccount(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) + name := naming.ServiceAccount(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, []string{}) return &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: otelCol.Namespace, + Namespace: params.OtelCol.Namespace, Labels: labels, - Annotations: otelCol.Annotations, + Annotations: params.OtelCol.Annotations, }, }, nil } diff --git a/internal/manifests/collector/servicemonitor.go b/internal/manifests/collector/servicemonitor.go index db5dcd34d0..02496e7898 100644 --- a/internal/manifests/collector/servicemonitor.go +++ b/internal/manifests/collector/servicemonitor.go @@ -22,7 +22,7 @@ import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "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" @@ -39,7 +39,7 @@ func ServiceMonitor(params manifests.Params) (*monitoringv1.ServiceMonitor, erro } var sm monitoringv1.ServiceMonitor - if params.OtelCol.Spec.Mode == v1alpha1.ModeSidecar { + if params.OtelCol.Spec.Mode == v1alpha2.ModeSidecar { return nil, nil } sm = monitoringv1.ServiceMonitor{ @@ -73,8 +73,14 @@ func ServiceMonitor(params manifests.Params) (*monitoringv1.ServiceMonitor, erro return &sm, nil } -func endpointsFromConfig(logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) []monitoringv1.Endpoint { - c, err := adapters.ConfigFromString(otelcol.Spec.Config) +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{} diff --git a/internal/manifests/collector/statefulset.go b/internal/manifests/collector/statefulset.go index f257a35431..7ac287a8da 100644 --- a/internal/manifests/collector/statefulset.go +++ b/internal/manifests/collector/statefulset.go @@ -19,7 +19,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/internal/api/convert" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -27,19 +26,15 @@ import ( // StatefulSet builds the statefulset for the given instance. func StatefulSet(params manifests.Params) (*appsv1.StatefulSet, error) { - otelCol, err := convert.V1Alpha1to2(params.OtelCol) - if err != nil { - return nil, err - } - name := naming.Collector(otelCol.Name) - labels := manifestutils.Labels(otelCol.ObjectMeta, name, otelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) + name := naming.Collector(params.OtelCol.Name) + labels := manifestutils.Labels(params.OtelCol.ObjectMeta, name, params.OtelCol.Spec.Image, ComponentOpenTelemetryCollector, params.Config.LabelsFilter()) - annotations, err := Annotations(otelCol) + annotations, err := Annotations(params.OtelCol) if err != nil { return nil, err } - podAnnotations, err := PodAnnotations(otelCol) + podAnnotations, err := PodAnnotations(params.OtelCol) if err != nil { return nil, err } @@ -47,14 +42,14 @@ func StatefulSet(params manifests.Params) (*appsv1.StatefulSet, error) { return &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: name, - Namespace: otelCol.Namespace, + Namespace: params.OtelCol.Namespace, Labels: labels, Annotations: annotations, }, Spec: appsv1.StatefulSetSpec{ - ServiceName: naming.Service(otelCol.Name), + ServiceName: naming.Service(params.OtelCol.Name), Selector: &metav1.LabelSelector{ - MatchLabels: manifestutils.SelectorLabels(otelCol.ObjectMeta, ComponentOpenTelemetryCollector), + MatchLabels: manifestutils.SelectorLabels(params.OtelCol.ObjectMeta, ComponentOpenTelemetryCollector), }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -62,24 +57,24 @@ func StatefulSet(params manifests.Params) (*appsv1.StatefulSet, error) { Annotations: podAnnotations, }, Spec: corev1.PodSpec{ - ServiceAccountName: ServiceAccountName(otelCol), - InitContainers: otelCol.Spec.InitContainers, - Containers: append(otelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, otelCol, true)), - Volumes: Volumes(params.Config, otelCol), - DNSPolicy: getDNSPolicy(otelCol), - HostNetwork: otelCol.Spec.HostNetwork, - ShareProcessNamespace: &otelCol.Spec.ShareProcessNamespace, - Tolerations: otelCol.Spec.Tolerations, - NodeSelector: otelCol.Spec.NodeSelector, - SecurityContext: otelCol.Spec.PodSecurityContext, - PriorityClassName: otelCol.Spec.PriorityClassName, - Affinity: otelCol.Spec.Affinity, - TopologySpreadConstraints: otelCol.Spec.TopologySpreadConstraints, + ServiceAccountName: ServiceAccountName(params.OtelCol), + InitContainers: params.OtelCol.Spec.InitContainers, + Containers: append(params.OtelCol.Spec.AdditionalContainers, Container(params.Config, params.Log, params.OtelCol, true)), + Volumes: Volumes(params.Config, params.OtelCol), + DNSPolicy: getDNSPolicy(params.OtelCol), + HostNetwork: params.OtelCol.Spec.HostNetwork, + ShareProcessNamespace: ¶ms.OtelCol.Spec.ShareProcessNamespace, + Tolerations: params.OtelCol.Spec.Tolerations, + NodeSelector: params.OtelCol.Spec.NodeSelector, + SecurityContext: params.OtelCol.Spec.PodSecurityContext, + PriorityClassName: params.OtelCol.Spec.PriorityClassName, + Affinity: params.OtelCol.Spec.Affinity, + TopologySpreadConstraints: params.OtelCol.Spec.TopologySpreadConstraints, }, }, - Replicas: otelCol.Spec.Replicas, + Replicas: params.OtelCol.Spec.Replicas, PodManagementPolicy: "Parallel", - VolumeClaimTemplates: VolumeClaimTemplates(otelCol), + VolumeClaimTemplates: VolumeClaimTemplates(params.OtelCol), }, }, nil } diff --git a/internal/manifests/collector/statefulset_test.go b/internal/manifests/collector/statefulset_test.go index b726785333..36df6de3e3 100644 --- a/internal/manifests/collector/statefulset_test.go +++ b/internal/manifests/collector/statefulset_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" . "github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector" @@ -33,14 +33,16 @@ import ( func TestStatefulSetNewDefault(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Mode: "statefulset", - Tolerations: testTolerationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Mode: "statefulset", + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Tolerations: testTolerationValues, + }, }, } cfg := config.New() @@ -107,13 +109,15 @@ func TestStatefulSetNewDefault(t *testing.T) { func TestStatefulSetReplicas(t *testing.T) { // prepare replicaInt := int32(3) - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Mode: "statefulset", - Replicas: &replicaInt, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + Mode: "statefulset", + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Replicas: &replicaInt, + }, }, } cfg := config.New() @@ -134,23 +138,25 @@ func TestStatefulSetReplicas(t *testing.T) { func TestStatefulSetVolumeClaimTemplates(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ Mode: "statefulset", - VolumeClaimTemplates: []corev1.PersistentVolumeClaim{{ - ObjectMeta: metav1.ObjectMeta{ - Name: "added-volume", - }, - Spec: corev1.PersistentVolumeClaimSpec{ - AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, - Resources: corev1.VolumeResourceRequirements{ - Requests: corev1.ResourceList{"storage": resource.MustParse("1Gi")}, + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + VolumeClaimTemplates: []corev1.PersistentVolumeClaim{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "added-volume", }, - }, - }}, + Spec: corev1.PersistentVolumeClaimSpec{ + AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"}, + Resources: corev1.VolumeResourceRequirements{ + Requests: corev1.ResourceList{"storage": resource.MustParse("1Gi")}, + }, + }, + }}, + }, }, } cfg := config.New() @@ -178,12 +184,14 @@ func TestStatefulSetVolumeClaimTemplates(t *testing.T) { func TestStatefulSetPodAnnotations(t *testing.T) { // prepare testPodAnnotationValues := map[string]string{"annotation-key": "annotation-value"} - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodAnnotations: testPodAnnotationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodAnnotations: testPodAnnotationValues, + }, }, } cfg := config.New() @@ -218,15 +226,17 @@ func TestStatefulSetPodSecurityContext(t *testing.T) { runAsUser := int64(1337) runasGroup := int64(1338) - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PodSecurityContext: &v1.PodSecurityContext{ - RunAsNonRoot: &runAsNonRoot, - RunAsUser: &runAsUser, - RunAsGroup: &runasGroup, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PodSecurityContext: &v1.PodSecurityContext{ + RunAsNonRoot: &runAsNonRoot, + RunAsUser: &runAsUser, + RunAsGroup: &runasGroup, + }, }, }, } @@ -249,7 +259,7 @@ func TestStatefulSetPodSecurityContext(t *testing.T) { func TestStatefulSetHostNetwork(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -270,12 +280,14 @@ func TestStatefulSetHostNetwork(t *testing.T) { assert.Equal(t, d1.Spec.Template.Spec.DNSPolicy, v1.DNSClusterFirst) // Test hostNetwork=true - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-hostnetwork", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + }, }, } @@ -299,12 +311,12 @@ func TestStatefulSetFilterLabels(t *testing.T) { "app.foo.bar": "1", } - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Labels: excludedLabels, }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{}, + Spec: v1alpha2.OpenTelemetryCollectorSpec{}, } cfg := config.New(config.WithLabelFilters([]string{"foo*", "app.*.bar"})) @@ -326,7 +338,7 @@ func TestStatefulSetFilterLabels(t *testing.T) { func TestStatefulSetNodeSelector(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -346,14 +358,16 @@ func TestStatefulSetNodeSelector(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.NodeSelector) // Test nodeSelector - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-nodeselector", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - HostNetwork: true, - NodeSelector: map[string]string{ - "node-key": "node-value", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + HostNetwork: true, + NodeSelector: map[string]string{ + "node-key": "node-value", + }, }, }, } @@ -372,7 +386,7 @@ func TestStatefulSetNodeSelector(t *testing.T) { } func TestStatefulSetPriorityClassName(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -392,12 +406,14 @@ func TestStatefulSetPriorityClassName(t *testing.T) { priorityClassName := "test-class" - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - PriorityClassName: priorityClassName, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + PriorityClassName: priorityClassName, + }, }, } @@ -415,7 +431,7 @@ func TestStatefulSetPriorityClassName(t *testing.T) { } func TestStatefulSetAffinity(t *testing.T) { - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -433,12 +449,14 @@ func TestStatefulSetAffinity(t *testing.T) { require.NoError(t, err) assert.Nil(t, sts1.Spec.Template.Spec.Affinity) - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-priortyClassName", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Affinity: testAffinityValue, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Affinity: testAffinityValue, + }, }, } @@ -458,15 +476,17 @@ func TestStatefulSetAffinity(t *testing.T) { func TestStatefulSetInitContainer(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - InitContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + InitContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -492,7 +512,7 @@ func TestStatefulSetInitContainer(t *testing.T) { func TestStatefulSetTopologySpreadConstraints(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -511,12 +531,14 @@ func TestStatefulSetTopologySpreadConstraints(t *testing.T) { assert.Empty(t, s1.Spec.Template.Spec.TopologySpreadConstraints) // Test TopologySpreadConstraints - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-topologyspreadconstraint", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TopologySpreadConstraints: testTopologySpreadConstraintValue, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + TopologySpreadConstraints: testTopologySpreadConstraintValue, + }, }, } @@ -538,15 +560,17 @@ func TestStatefulSetTopologySpreadConstraints(t *testing.T) { func TestStatefulSetAdditionalContainers(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - AdditionalContainers: []v1.Container{ - { - Name: "test", + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + AdditionalContainers: []v1.Container{ + { + Name: "test", + }, }, }, }, @@ -573,7 +597,7 @@ func TestStatefulSetAdditionalContainers(t *testing.T) { func TestStatefulSetShareProcessNamespace(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -592,12 +616,14 @@ func TestStatefulSetShareProcessNamespace(t *testing.T) { assert.False(t, *d1.Spec.Template.Spec.ShareProcessNamespace) // Test shareProcessNamespace=true - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-with-shareprocessnamespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - ShareProcessNamespace: true, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + ShareProcessNamespace: true, + }, }, } diff --git a/internal/manifests/collector/suite_test.go b/internal/manifests/collector/suite_test.go index fd5e275856..88975a4fdb 100644 --- a/internal/manifests/collector/suite_test.go +++ b/internal/manifests/collector/suite_test.go @@ -18,6 +18,7 @@ import ( "fmt" "os" + go_yaml "gopkg.in/yaml.v3" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -25,7 +26,7 @@ import ( "k8s.io/client-go/tools/record" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/autodetect/openshift" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" @@ -42,18 +43,23 @@ const ( ) func deploymentParams() manifests.Params { - return paramsWithMode(v1alpha1.ModeDeployment) + return paramsWithMode(v1alpha2.ModeDeployment) } -func paramsWithMode(mode v1alpha1.Mode) manifests.Params { +func paramsWithMode(mode v1alpha2.Mode) manifests.Params { replicas := int32(2) configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) } + cfg := v1alpha2.Config{} + err = go_yaml.Unmarshal(configYAML, &cfg) + if err != nil { + fmt.Printf("Error unmarshalling YAML: %v", err) + } return manifests.Params{ Config: config.New(config.WithCollectorImage(defaultCollectorImage), config.WithTargetAllocatorImage(defaultTaAllocationImage)), - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ TypeMeta: metav1.TypeMeta{ Kind: "opentelemetry.io", APIVersion: "v1", @@ -63,20 +69,23 @@ func paramsWithMode(mode v1alpha1.Mode) manifests.Params { Namespace: "default", UID: instanceUID, }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - Replicas: &replicas, - Config: string(configYAML), - Mode: mode, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + + Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}, + Replicas: &replicas, + }, + Config: cfg, + Mode: mode, }, }, Log: logger, @@ -95,7 +104,13 @@ func newParams(taContainerImage string, file string) (manifests.Params, error) { configYAML, err = os.ReadFile(file) } if err != nil { - return manifests.Params{}, fmt.Errorf("Error getting yaml file: %w", err) + return manifests.Params{}, fmt.Errorf("error getting yaml file: %w", err) + } + + colCfg := v1alpha2.Config{} + err = go_yaml.Unmarshal(configYAML, &colCfg) + if err != nil { + return manifests.Params{}, fmt.Errorf("failed to unmarshal config: %w", err) } cfg := config.New( @@ -106,7 +121,7 @@ func newParams(taContainerImage string, file string) (manifests.Params, error) { return manifests.Params{ Config: cfg, - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ TypeMeta: metav1.TypeMeta{ Kind: "opentelemetry.io", APIVersion: "v1", @@ -116,23 +131,26 @@ func newParams(taContainerImage string, file string) (manifests.Params, error) { Namespace: "default", UID: instanceUID, }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Mode: v1alpha1.ModeStatefulSet, - Ports: []v1.ServicePort{{ - Name: "web", - Port: 80, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 80, - }, - NodePort: 0, - }}, - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Ports: []v1.ServicePort{{ + Name: "web", + Port: 80, + TargetPort: intstr.IntOrString{ + Type: intstr.Int, + IntVal: 80, + }, + NodePort: 0, + }}, + + Replicas: &replicas, + }, + Mode: v1alpha2.ModeStatefulSet, + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Image: taContainerImage, }, - Replicas: &replicas, - Config: string(configYAML), + Config: colCfg, }, }, Log: logger, diff --git a/internal/manifests/params.go b/internal/manifests/params.go index a7b377e4f2..95a922a910 100644 --- a/internal/manifests/params.go +++ b/internal/manifests/params.go @@ -21,6 +21,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" ) @@ -30,7 +31,7 @@ type Params struct { Recorder record.EventRecorder Scheme *runtime.Scheme Log logr.Logger - OtelCol v1alpha1.OpenTelemetryCollector + OtelCol v1alpha2.OpenTelemetryCollector OpAMPBridge v1alpha1.OpAMPBridge Config config.Config } diff --git a/internal/manifests/targetallocator/annotations.go b/internal/manifests/targetallocator/annotations.go index 72e648e5bd..8ad5b0d894 100644 --- a/internal/manifests/targetallocator/annotations.go +++ b/internal/manifests/targetallocator/annotations.go @@ -20,13 +20,13 @@ import ( v1 "k8s.io/api/core/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" ) const configMapHashAnnotationKey = "opentelemetry-targetallocator-config/hash" // Annotations returns the annotations for the TargetAllocator Pod. -func Annotations(instance v1alpha1.OpenTelemetryCollector, configMap *v1.ConfigMap) map[string]string { +func Annotations(instance v1alpha2.OpenTelemetryCollector, configMap *v1.ConfigMap) map[string]string { // Make a copy of PodAnnotations to be safe annotations := make(map[string]string, len(instance.Spec.PodAnnotations)) for key, value := range instance.Spec.PodAnnotations { diff --git a/internal/manifests/targetallocator/annotations_test.go b/internal/manifests/targetallocator/annotations_test.go index f50a9d77fb..bb5a839098 100644 --- a/internal/manifests/targetallocator/annotations_test.go +++ b/internal/manifests/targetallocator/annotations_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" ) @@ -57,7 +58,7 @@ func TestConfigMapHash(t *testing.T) { func TestInvalidConfigNoHash(t *testing.T) { instance := collectorInstance() - instance.Spec.Config = "" + instance.Spec.Config = v1alpha2.Config{} annotations := Annotations(instance, nil) require.NotContains(t, annotations, configMapHashAnnotationKey) } diff --git a/internal/manifests/targetallocator/configmap.go b/internal/manifests/targetallocator/configmap.go index e63e86c36f..e4ddb5182a 100644 --- a/internal/manifests/targetallocator/configmap.go +++ b/internal/manifests/targetallocator/configmap.go @@ -19,7 +19,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "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" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" @@ -34,10 +34,15 @@ const ( func ConfigMap(params manifests.Params) (*corev1.ConfigMap, error) { name := naming.TAConfigMap(params.OtelCol.Name) labels := Labels(params.OtelCol, name) + // TODO: https://github.com/open-telemetry/opentelemetry-operator/issues/2603 + cfgStr, err := params.OtelCol.Spec.Config.Yaml() + if err != nil { + return &corev1.ConfigMap{}, err + } // Collector supports environment variable substitution, but the TA does not. // TA ConfigMap should have a single "$", as it does not support env var substitution - prometheusReceiverConfig, err := adapters.UnescapeDollarSignsInPromConfig(params.OtelCol.Spec.Config) + prometheusReceiverConfig, err := adapters.UnescapeDollarSignsInPromConfig(cfgStr) if err != nil { return &corev1.ConfigMap{}, err } @@ -59,7 +64,7 @@ func ConfigMap(params manifests.Params) (*corev1.ConfigMap, error) { if len(params.OtelCol.Spec.TargetAllocator.AllocationStrategy) > 0 { taConfig["allocation_strategy"] = params.OtelCol.Spec.TargetAllocator.AllocationStrategy } else { - taConfig["allocation_strategy"] = v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing + taConfig["allocation_strategy"] = v1alpha2.TargetAllocatorAllocationStrategyConsistentHashing } taConfig["filter_strategy"] = params.OtelCol.Spec.TargetAllocator.FilterStrategy @@ -68,22 +73,20 @@ func ConfigMap(params manifests.Params) (*corev1.ConfigMap, error) { prometheusCRConfig["scrape_interval"] = params.OtelCol.Spec.TargetAllocator.PrometheusCR.ScrapeInterval.Duration } - prometheusCRConfig["service_monitor_selector"] = &metav1.LabelSelector{ - MatchLabels: params.OtelCol.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector, - } + prometheusCRConfig["service_monitor_selector"] = params.OtelCol.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector + // The below instruction is here for compatibility with the previous target allocator version // TODO: Drop it after 3 more versions if params.OtelCol.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector != nil { - taConfig["service_monitor_selector"] = ¶ms.OtelCol.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector + taConfig["service_monitor_selector"] = ¶ms.OtelCol.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector.MatchLabels } - prometheusCRConfig["pod_monitor_selector"] = &metav1.LabelSelector{ - MatchLabels: params.OtelCol.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector, - } + prometheusCRConfig["pod_monitor_selector"] = params.OtelCol.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector + // The below instruction is here for compatibility with the previous target allocator version // TODO: Drop it after 3 more versions if params.OtelCol.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector != nil { - taConfig["pod_monitor_selector"] = ¶ms.OtelCol.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector + taConfig["pod_monitor_selector"] = ¶ms.OtelCol.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector.MatchLabels } if len(prometheusCRConfig) > 0 { diff --git a/internal/manifests/targetallocator/configmap_test.go b/internal/manifests/targetallocator/configmap_test.go index 0ea684bf1a..ee097d8660 100644 --- a/internal/manifests/targetallocator/configmap_test.go +++ b/internal/manifests/targetallocator/configmap_test.go @@ -61,12 +61,8 @@ label_selector: app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/part-of: opentelemetry prometheus_cr: - pod_monitor_selector: - matchlabels: {} - matchexpressions: [] - service_monitor_selector: - matchlabels: {} - matchexpressions: [] + pod_monitor_selector: null + service_monitor_selector: null `, } instance := collectorInstance() @@ -126,11 +122,15 @@ service_monitor_selector: `, } instance := collectorInstance() - instance.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector = map[string]string{ - "release": "my-instance", + instance.Spec.TargetAllocator.PrometheusCR.PodMonitorSelector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "release": "my-instance", + }, } - instance.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector = map[string]string{ - "release": "my-instance", + instance.Spec.TargetAllocator.PrometheusCR.ServiceMonitorSelector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "release": "my-instance", + }, } cfg := config.New() params := manifests.Params{ @@ -173,13 +173,9 @@ label_selector: app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/part-of: opentelemetry prometheus_cr: - pod_monitor_selector: - matchlabels: {} - matchexpressions: [] + pod_monitor_selector: null scrape_interval: 30s - service_monitor_selector: - matchlabels: {} - matchexpressions: [] + service_monitor_selector: null `, } diff --git a/internal/manifests/targetallocator/container.go b/internal/manifests/targetallocator/container.go index 094bd30721..53cbfc3a70 100644 --- a/internal/manifests/targetallocator/container.go +++ b/internal/manifests/targetallocator/container.go @@ -20,13 +20,13 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) // Container builds a container for the given TargetAllocator. -func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelemetryCollector) corev1.Container { +func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha2.OpenTelemetryCollector) corev1.Container { image := otelcol.Spec.TargetAllocator.Image if len(image) == 0 { image = cfg.TargetAllocatorImage() diff --git a/internal/manifests/targetallocator/container_test.go b/internal/manifests/targetallocator/container_test.go index b624467bcb..9957740c9a 100644 --- a/internal/manifests/targetallocator/container_test.go +++ b/internal/manifests/targetallocator/container_test.go @@ -25,7 +25,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" logf "sigs.k8s.io/controller-runtime/pkg/log" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -34,7 +34,7 @@ var logger = logf.Log.WithName("unit-tests") func TestContainerNewDefault(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{} + otelcol := v1alpha2.OpenTelemetryCollector{} cfg := config.New(config.WithTargetAllocatorImage("default-image")) // test @@ -46,9 +46,9 @@ func TestContainerNewDefault(t *testing.T) { func TestContainerWithImageOverridden(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Image: "overridden-image", }, @@ -65,9 +65,9 @@ func TestContainerWithImageOverridden(t *testing.T) { func TestContainerPorts(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Image: "default-image", }, @@ -86,9 +86,9 @@ func TestContainerPorts(t *testing.T) { func TestContainerVolumes(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Image: "default-image", }, @@ -105,9 +105,9 @@ func TestContainerVolumes(t *testing.T) { } func TestContainerResourceRequirements(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("100m"), @@ -143,9 +143,9 @@ func TestContainerResourceRequirements(t *testing.T) { func TestContainerHasEnvVars(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Env: []corev1.EnvVar{ { @@ -228,9 +228,9 @@ func TestContainerHasProxyEnvVars(t *testing.T) { defer os.Unsetenv("NO_PROXY") // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Env: []corev1.EnvVar{ { @@ -254,9 +254,9 @@ func TestContainerHasProxyEnvVars(t *testing.T) { func TestContainerDoesNotOverrideEnvVars(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, Env: []corev1.EnvVar{ { @@ -320,9 +320,9 @@ func TestContainerDoesNotOverrideEnvVars(t *testing.T) { assert.Equal(t, expected, c) } func TestReadinessProbe(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, }, }, @@ -345,9 +345,9 @@ func TestReadinessProbe(t *testing.T) { } func TestLivenessProbe(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, }, }, @@ -375,9 +375,9 @@ func TestSecurityContext(t *testing.T) { RunAsNonRoot: &runAsNonRoot, } // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + otelcol := v1alpha2.OpenTelemetryCollector{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Enabled: true, SecurityContext: securityContext, }, diff --git a/internal/manifests/targetallocator/deployment_test.go b/internal/manifests/targetallocator/deployment_test.go index 007ad0c3c6..61efa1550f 100644 --- a/internal/manifests/targetallocator/deployment_test.go +++ b/internal/manifests/targetallocator/deployment_test.go @@ -20,10 +20,11 @@ import ( "testing" "github.com/stretchr/testify/assert" + go_yaml "gopkg.in/yaml.v3" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" ) @@ -77,7 +78,7 @@ var testSecurityContextValue = &v1.PodSecurityContext{ func TestDeploymentSecurityContext(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -97,12 +98,12 @@ func TestDeploymentSecurityContext(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.SecurityContext) // Test SecurityContext - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-securitycontext", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ PodSecurityContext: testSecurityContextValue, }, }, @@ -174,20 +175,27 @@ func TestDeploymentPodAnnotations(t *testing.T) { assert.Subset(t, ds.Spec.Template.Annotations, testPodAnnotationValues) } -func collectorInstance() v1alpha1.OpenTelemetryCollector { +func collectorInstance() v1alpha2.OpenTelemetryCollector { configYAML, err := os.ReadFile("testdata/test.yaml") if err != nil { fmt.Printf("Error getting yaml file: %v", err) } - return v1alpha1.OpenTelemetryCollector{ + cfg := v1alpha2.Config{} + err = go_yaml.Unmarshal(configYAML, &cfg) + if err != nil { + fmt.Printf("Error unmarshalling YAML: %v", err) + } + return v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "default", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", - Config: string(configYAML), - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.47.0", + }, + Config: cfg, + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Image: "ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-targetallocator:0.47.0", FilterStrategy: "relabel-config", }, @@ -197,7 +205,7 @@ func collectorInstance() v1alpha1.OpenTelemetryCollector { func TestDeploymentNodeSelector(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -215,12 +223,12 @@ func TestDeploymentNodeSelector(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.NodeSelector) // Test nodeSelector - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-nodeselector", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ NodeSelector: map[string]string{ "node-key": "node-value", }, @@ -242,7 +250,7 @@ func TestDeploymentNodeSelector(t *testing.T) { } func TestDeploymentAffinity(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -260,12 +268,12 @@ func TestDeploymentAffinity(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.Affinity) // Test affinity - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-affinity", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Affinity: testAffinityValue, }, }, @@ -286,7 +294,7 @@ func TestDeploymentAffinity(t *testing.T) { func TestDeploymentTolerations(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -304,12 +312,12 @@ func TestDeploymentTolerations(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.Tolerations) // Test Tolerations - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-toleration", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ Tolerations: testTolerationValues, }, }, @@ -330,7 +338,7 @@ func TestDeploymentTolerations(t *testing.T) { func TestDeploymentTopologySpreadConstraints(t *testing.T) { // Test default - otelcol1 := v1alpha1.OpenTelemetryCollector{ + otelcol1 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -349,12 +357,12 @@ func TestDeploymentTopologySpreadConstraints(t *testing.T) { assert.Empty(t, d1.Spec.Template.Spec.TopologySpreadConstraints) // Test TopologySpreadConstraints - otelcol2 := v1alpha1.OpenTelemetryCollector{ + otelcol2 := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance-topologyspreadconstraint", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ TopologySpreadConstraints: testTopologySpreadConstraintValue, }, }, diff --git a/internal/manifests/targetallocator/labels.go b/internal/manifests/targetallocator/labels.go index 6271ebb6ea..f2b87c1c0e 100644 --- a/internal/manifests/targetallocator/labels.go +++ b/internal/manifests/targetallocator/labels.go @@ -15,18 +15,18 @@ package targetallocator import ( - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests/manifestutils" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) // Labels return the common labels to all TargetAllocator objects that are part of a managed OpenTelemetryCollector. -func Labels(instance v1alpha1.OpenTelemetryCollector, name string) map[string]string { +func Labels(instance v1alpha2.OpenTelemetryCollector, name string) map[string]string { return manifestutils.Labels(instance.ObjectMeta, name, instance.Spec.TargetAllocator.Image, ComponentOpenTelemetryTargetAllocator, nil) } // SelectorLabels return the selector labels for Target Allocator Pods. -func SelectorLabels(instance v1alpha1.OpenTelemetryCollector) map[string]string { +func SelectorLabels(instance v1alpha2.OpenTelemetryCollector) map[string]string { selectorLabels := manifestutils.SelectorLabels(instance.ObjectMeta, ComponentOpenTelemetryTargetAllocator) // TargetAllocator uses the name label as well for selection // This is inconsistent with the Collector, but changing is a somewhat painful breaking change diff --git a/internal/manifests/targetallocator/labels_test.go b/internal/manifests/targetallocator/labels_test.go index d6f1891d19..d029dd5a97 100644 --- a/internal/manifests/targetallocator/labels_test.go +++ b/internal/manifests/targetallocator/labels_test.go @@ -20,7 +20,7 @@ import ( "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) @@ -31,7 +31,7 @@ const ( func TestLabelsCommonSet(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, @@ -50,7 +50,7 @@ func TestLabelsCommonSet(t *testing.T) { func TestLabelsPropagateDown(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "myapp": "mycomponent", @@ -70,7 +70,7 @@ func TestLabelsPropagateDown(t *testing.T) { func TestSelectorLabels(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace, diff --git a/internal/manifests/targetallocator/poddisruptionbudget.go b/internal/manifests/targetallocator/poddisruptionbudget.go index f7d5d21a5e..ed4a441500 100644 --- a/internal/manifests/targetallocator/poddisruptionbudget.go +++ b/internal/manifests/targetallocator/poddisruptionbudget.go @@ -17,7 +17,7 @@ package targetallocator import ( "fmt" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/naming" @@ -35,7 +35,7 @@ func PodDisruptionBudget(params manifests.Params) (*policyV1.PodDisruptionBudget // defaulter doesn't set PodDisruptionBudget if the strategy isn't valid, // if PodDisruptionBudget != nil and stategy isn't correct, users have set // it wrongly - if params.OtelCol.Spec.TargetAllocator.AllocationStrategy != v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing { + if params.OtelCol.Spec.TargetAllocator.AllocationStrategy != v1alpha2.TargetAllocatorAllocationStrategyConsistentHashing { params.Log.V(4).Info("current allocation strategy not compatible, skipping podDisruptionBudget creation") return nil, fmt.Errorf("target allocator pdb has been configured but the allocation strategy isn't not compatible") } diff --git a/internal/manifests/targetallocator/poddisruptionbudget_test.go b/internal/manifests/targetallocator/poddisruptionbudget_test.go index 7547058ea3..88a3097a1c 100644 --- a/internal/manifests/targetallocator/poddisruptionbudget_test.go +++ b/internal/manifests/targetallocator/poddisruptionbudget_test.go @@ -21,7 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" ) @@ -66,17 +66,17 @@ var tests = []test{ func TestPDBWithValidStrategy(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ - PodDisruptionBudget: &v1alpha1.PodDisruptionBudgetSpec{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ + PodDisruptionBudget: &v1alpha2.PodDisruptionBudgetSpec{ MinAvailable: test.MinAvailable, MaxUnavailable: test.MaxUnavailable, }, - AllocationStrategy: v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyConsistentHashing, + AllocationStrategy: v1alpha2.TargetAllocatorAllocationStrategyConsistentHashing, }, }, } @@ -100,17 +100,17 @@ func TestPDBWithValidStrategy(t *testing.T) { func TestPDBWithNotValidStrategy(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ - PodDisruptionBudget: &v1alpha1.PodDisruptionBudgetSpec{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ + PodDisruptionBudget: &v1alpha2.PodDisruptionBudgetSpec{ MinAvailable: test.MinAvailable, MaxUnavailable: test.MaxUnavailable, }, - AllocationStrategy: v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyLeastWeighted, + AllocationStrategy: v1alpha2.TargetAllocatorAllocationStrategyLeastWeighted, }, }, } @@ -129,13 +129,13 @@ func TestPDBWithNotValidStrategy(t *testing.T) { } func TestNoPDB(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ - AllocationStrategy: v1alpha1.OpenTelemetryTargetAllocatorAllocationStrategyLeastWeighted, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ + AllocationStrategy: v1alpha2.TargetAllocatorAllocationStrategyLeastWeighted, }, }, } diff --git a/internal/manifests/targetallocator/serviceaccount.go b/internal/manifests/targetallocator/serviceaccount.go index 96477b7e70..d9e0b1d3e6 100644 --- a/internal/manifests/targetallocator/serviceaccount.go +++ b/internal/manifests/targetallocator/serviceaccount.go @@ -18,14 +18,13 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/naming" - - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" ) // ServiceAccountName returns the name of the existing or self-provisioned service account to use for the given instance. -func ServiceAccountName(instance v1alpha1.OpenTelemetryCollector) string { +func ServiceAccountName(instance v1alpha2.OpenTelemetryCollector) string { if len(instance.Spec.TargetAllocator.ServiceAccount) == 0 { return naming.TargetAllocatorServiceAccount(instance.Name) } diff --git a/internal/manifests/targetallocator/serviceaccount_test.go b/internal/manifests/targetallocator/serviceaccount_test.go index 99e5b42761..bf31c21422 100644 --- a/internal/manifests/targetallocator/serviceaccount_test.go +++ b/internal/manifests/targetallocator/serviceaccount_test.go @@ -21,13 +21,13 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" ) func TestServiceAccountDefaultName(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -42,12 +42,12 @@ func TestServiceAccountDefaultName(t *testing.T) { func TestServiceAccountOverrideName(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ ServiceAccount: "my-special-sa", }, }, @@ -62,7 +62,7 @@ func TestServiceAccountOverrideName(t *testing.T) { func TestServiceAccountDefault(t *testing.T) { params := manifests.Params{ - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, @@ -86,12 +86,12 @@ func TestServiceAccountDefault(t *testing.T) { func TestServiceAccountOverride(t *testing.T) { params := manifests.Params{ - OtelCol: v1alpha1.OpenTelemetryCollector{ + OtelCol: v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - TargetAllocator: v1alpha1.OpenTelemetryTargetAllocator{ + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + TargetAllocator: v1alpha2.TargetAllocatorEmbedded{ ServiceAccount: "my-special-sa", }, }, diff --git a/internal/manifests/targetallocator/servicemonitor_test.go b/internal/manifests/targetallocator/servicemonitor_test.go index 1544eac03d..acb704a102 100644 --- a/internal/manifests/targetallocator/servicemonitor_test.go +++ b/internal/manifests/targetallocator/servicemonitor_test.go @@ -20,7 +20,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" @@ -28,14 +28,16 @@ import ( ) func TestDesiredServiceMonitors(t *testing.T) { - otelcol := v1alpha1.OpenTelemetryCollector{ + otelcol := v1alpha2.OpenTelemetryCollector{ ObjectMeta: metav1.ObjectMeta{ Name: "my-instance", Namespace: "my-namespace", }, - Spec: v1alpha1.OpenTelemetryCollectorSpec{ - Mode: v1alpha1.ModeStatefulSet, - Tolerations: testTolerationValues, + Spec: v1alpha2.OpenTelemetryCollectorSpec{ + OpenTelemetryCommonFields: v1alpha2.OpenTelemetryCommonFields{ + Tolerations: testTolerationValues, + }, + Mode: v1alpha2.ModeStatefulSet, }, } cfg := config.New() diff --git a/internal/manifests/targetallocator/volume.go b/internal/manifests/targetallocator/volume.go index 8200b00d38..e52a57297f 100644 --- a/internal/manifests/targetallocator/volume.go +++ b/internal/manifests/targetallocator/volume.go @@ -17,13 +17,13 @@ package targetallocator import ( corev1 "k8s.io/api/core/v1" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) // Volumes builds the volumes for the given instance, including the config map volume. -func Volumes(cfg config.Config, otelcol v1alpha1.OpenTelemetryCollector) []corev1.Volume { +func Volumes(cfg config.Config, otelcol v1alpha2.OpenTelemetryCollector) []corev1.Volume { volumes := []corev1.Volume{{ Name: naming.TAConfigMapVolume(), VolumeSource: corev1.VolumeSource{ diff --git a/internal/manifests/targetallocator/volume_test.go b/internal/manifests/targetallocator/volume_test.go index 0b50006e4f..76da542d12 100644 --- a/internal/manifests/targetallocator/volume_test.go +++ b/internal/manifests/targetallocator/volume_test.go @@ -19,14 +19,14 @@ import ( "github.com/stretchr/testify/assert" - "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha2" "github.com/open-telemetry/opentelemetry-operator/internal/config" "github.com/open-telemetry/opentelemetry-operator/internal/naming" ) func TestVolumeNewDefault(t *testing.T) { // prepare - otelcol := v1alpha1.OpenTelemetryCollector{} + otelcol := v1alpha2.OpenTelemetryCollector{} cfg := config.New() // test diff --git a/internal/status/collector/handle.go b/internal/status/collector/handle.go index b20b03d24b..d1f1331aed 100644 --- a/internal/status/collector/handle.go +++ b/internal/status/collector/handle.go @@ -22,6 +22,7 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1" "github.com/open-telemetry/opentelemetry-operator/internal/manifests" "github.com/open-telemetry/opentelemetry-operator/internal/version" collectorupgrade "github.com/open-telemetry/opentelemetry-operator/pkg/collector/upgrade" @@ -38,13 +39,14 @@ const ( // HandleReconcileStatus handles updating the status of the CRDs managed by the operator. // TODO: make the status more useful https://github.com/open-telemetry/opentelemetry-operator/issues/1972 -func HandleReconcileStatus(ctx context.Context, log logr.Logger, params manifests.Params, err error) (ctrl.Result, error) { +// TODO: update status to use v1alpha2 https://github.com/open-telemetry/opentelemetry-operator/milestone/4 +func HandleReconcileStatus(ctx context.Context, log logr.Logger, params manifests.Params, otelcol v1alpha1.OpenTelemetryCollector, err error) (ctrl.Result, error) { log.V(2).Info("updating collector status") if err != nil { - params.Recorder.Event(¶ms.OtelCol, eventTypeWarning, reasonError, err.Error()) + params.Recorder.Event(&otelcol, eventTypeWarning, reasonError, err.Error()) return ctrl.Result{}, err } - changed := params.OtelCol.DeepCopy() + changed := otelcol.DeepCopy() up := &collectorupgrade.VersionUpgrade{ Log: params.Log, @@ -55,7 +57,7 @@ func HandleReconcileStatus(ctx context.Context, log logr.Logger, params manifest upgraded, upgradeErr := up.ManagedInstance(ctx, *changed) if upgradeErr != nil { // don't fail to allow setting the status - params.Log.Error(upgradeErr, "failed to upgrade the OpenTelemetry CR") + log.V(2).Error(upgradeErr, "failed to upgrade the OpenTelemetry CR") } changed = &upgraded statusErr := UpdateCollectorStatus(ctx, params.Client, changed) @@ -63,7 +65,7 @@ func HandleReconcileStatus(ctx context.Context, log logr.Logger, params manifest params.Recorder.Event(changed, eventTypeWarning, reasonStatusFailure, statusErr.Error()) return ctrl.Result{}, statusErr } - statusPatch := client.MergeFrom(¶ms.OtelCol) + statusPatch := client.MergeFrom(&otelcol) if err := params.Client.Status().Patch(ctx, changed, statusPatch); err != nil { return ctrl.Result{}, fmt.Errorf("failed to apply status changes to the OpenTelemetry CR: %w", err) }