From fcca8ac5348e7893bfaae741b75785a547c53ea5 Mon Sep 17 00:00:00 2001 From: Haja Date: Fri, 27 Sep 2024 22:51:46 +0200 Subject: [PATCH 01/18] e2e tests for additionalContainers added --- ...emonset-without-additional-containers.yaml | 14 +++ ...loyment-without-additional-containers.yaml | 14 +++ ...efulset-without-additional-containers.yaml | 14 +++ ...lectors-without-additional-containers.yaml | 76 ++++++++++++++++ ...-daemonset-with-additional-containers.yaml | 16 ++++ ...deployment-with-additional-containers.yaml | 16 ++++ ...tatefulset-with-additional-containers.yaml | 16 ++++ ...collectors-with-additional-containers.yaml | 88 +++++++++++++++++++ ...t-with-modified-additional-containers.yaml | 18 ++++ ...t-with-modified-additional-containers.yaml | 18 ++++ ...t-with-modified-additional-containers.yaml | 18 ++++ ...dify-collectors-additional-containers.yaml | 82 +++++++++++++++++ .../chainsaw-test.yaml | 66 ++++++++++++++ 13 files changed, 456 insertions(+) create mode 100644 tests/e2e/additional-containers-collector/00-assert-daemonset-without-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/00-assert-deployment-without-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/00-assert-statefulset-without-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/01-assert-daemonset-with-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/01-assert-deployment-with-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/01-assert-statefulset-with-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/01-install-collectors-with-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/02-assert-daemonset-with-modified-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/02-assert-deployment-with-modified-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/02-assert-statefulset-with-modified-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/02-modify-collectors-additional-containers.yaml create mode 100644 tests/e2e/additional-containers-collector/chainsaw-test.yaml diff --git a/tests/e2e/additional-containers-collector/00-assert-daemonset-without-additional-containers.yaml b/tests/e2e/additional-containers-collector/00-assert-daemonset-without-additional-containers.yaml new file mode 100644 index 0000000000..9c9a9588a2 --- /dev/null +++ b/tests/e2e/additional-containers-collector/00-assert-daemonset-without-additional-containers.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: without +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 diff --git a/tests/e2e/additional-containers-collector/00-assert-deployment-without-additional-containers.yaml b/tests/e2e/additional-containers-collector/00-assert-deployment-without-additional-containers.yaml new file mode 100644 index 0000000000..8fbcd2fb4b --- /dev/null +++ b/tests/e2e/additional-containers-collector/00-assert-deployment-without-additional-containers.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: without +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 diff --git a/tests/e2e/additional-containers-collector/00-assert-statefulset-without-additional-containers.yaml b/tests/e2e/additional-containers-collector/00-assert-statefulset-without-additional-containers.yaml new file mode 100644 index 0000000000..25896fd560 --- /dev/null +++ b/tests/e2e/additional-containers-collector/00-assert-statefulset-without-additional-containers.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: without +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 diff --git a/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml b/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml new file mode 100644 index 0000000000..9c474e174a --- /dev/null +++ b/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml @@ -0,0 +1,76 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + additional-containers: without +spec: + mode: deployment + additionalContainers: [] + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + additional-containers: without +spec: + mode: daemonset + additionalContainers: [] + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + additional-containers: without +spec: + mode: statefulset + additionalContainers: [] + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/additional-containers-collector/01-assert-daemonset-with-additional-containers.yaml b/tests/e2e/additional-containers-collector/01-assert-daemonset-with-additional-containers.yaml new file mode 100644 index 0000000000..77427d8cef --- /dev/null +++ b/tests/e2e/additional-containers-collector/01-assert-daemonset-with-additional-containers.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 1 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/01-assert-deployment-with-additional-containers.yaml b/tests/e2e/additional-containers-collector/01-assert-deployment-with-additional-containers.yaml new file mode 100644 index 0000000000..cae1197c53 --- /dev/null +++ b/tests/e2e/additional-containers-collector/01-assert-deployment-with-additional-containers.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 1 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/01-assert-statefulset-with-additional-containers.yaml b/tests/e2e/additional-containers-collector/01-assert-statefulset-with-additional-containers.yaml new file mode 100644 index 0000000000..34496ba36c --- /dev/null +++ b/tests/e2e/additional-containers-collector/01-assert-statefulset-with-additional-containers.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 1 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/01-install-collectors-with-additional-containers.yaml b/tests/e2e/additional-containers-collector/01-install-collectors-with-additional-containers.yaml new file mode 100644 index 0000000000..ae03e35ee1 --- /dev/null +++ b/tests/e2e/additional-containers-collector/01-install-collectors-with-additional-containers.yaml @@ -0,0 +1,88 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + additional-containers: with +spec: + mode: deployment + additionalContainers: + - image: alpine + name: alpine + - image: alpine + name: alpine2 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + additional-containers: with +spec: + mode: daemonset + additionalContainers: + - image: alpine + name: alpine + - image: alpine + name: alpine2 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + additional-containers: with +spec: + mode: statefulset + additionalContainers: + - image: alpine + name: alpine + - image: alpine + name: alpine2 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/additional-containers-collector/02-assert-daemonset-with-modified-additional-containers.yaml b/tests/e2e/additional-containers-collector/02-assert-daemonset-with-modified-additional-containers.yaml new file mode 100644 index 0000000000..7d45a9bad7 --- /dev/null +++ b/tests/e2e/additional-containers-collector/02-assert-daemonset-with-modified-additional-containers.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine3']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/02-assert-deployment-with-modified-additional-containers.yaml b/tests/e2e/additional-containers-collector/02-assert-deployment-with-modified-additional-containers.yaml new file mode 100644 index 0000000000..12fc910899 --- /dev/null +++ b/tests/e2e/additional-containers-collector/02-assert-deployment-with-modified-additional-containers.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine3']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/02-assert-statefulset-with-modified-additional-containers.yaml b/tests/e2e/additional-containers-collector/02-assert-statefulset-with-modified-additional-containers.yaml new file mode 100644 index 0000000000..4de3a7ffcd --- /dev/null +++ b/tests/e2e/additional-containers-collector/02-assert-statefulset-with-modified-additional-containers.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + additional-containers: with +spec: + template: + spec: + (containers[?image == 'alpine' && name == 'alpine']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine2']): + (length(@)): 0 + (containers[?image == 'alpine' && name == 'alpine3']): + (length(@)): 1 diff --git a/tests/e2e/additional-containers-collector/02-modify-collectors-additional-containers.yaml b/tests/e2e/additional-containers-collector/02-modify-collectors-additional-containers.yaml new file mode 100644 index 0000000000..45397baece --- /dev/null +++ b/tests/e2e/additional-containers-collector/02-modify-collectors-additional-containers.yaml @@ -0,0 +1,82 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + additional-containers: with +spec: + mode: deployment + additionalContainers: + - image: alpine + name: alpine3 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + additional-containers: with +spec: + mode: daemonset + additionalContainers: + - image: alpine + name: alpine3 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + additional-containers: with +spec: + mode: statefulset + additionalContainers: + - image: alpine + name: alpine3 + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/additional-containers-collector/chainsaw-test.yaml b/tests/e2e/additional-containers-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..e44e5afffe --- /dev/null +++ b/tests/e2e/additional-containers-collector/chainsaw-test.yaml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: additional-containers-collector +spec: + steps: + - name: step-00 + description: collectors without additionalContainers + try: + - apply: + file: 00-install-collectors-without-additional-containers.yaml + # deployment + - assert: + file: 00-assert-deployment-without-additional-containers.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-additional-containers.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-additional-containers.yaml + + - name: step-01 + description: collectors with additionalContainers + try: + - apply: + file: 01-install-collectors-with-additional-containers.yaml + # deployment + - assert: + file: 01-assert-deployment-with-additional-containers.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-additional-containers.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-additional-containers.yaml + + - name: step-02 + description: modify additionalContainers + try: + - apply: + file: 02-modify-collectors-additional-containers.yaml + # deployment + - assert: + file: 02-assert-deployment-with-modified-additional-containers.yaml + # daemonset + - assert: + file: 02-assert-daemonset-with-modified-additional-containers.yaml + # statefulset + - assert: + file: 02-assert-statefulset-with-modified-additional-containers.yaml + + - name: step-03 + description: delete additionalContainers + try: + - apply: + file: 00-install-collectors-without-additional-containers.yaml + # deployment + - assert: + file: 00-assert-deployment-without-additional-containers.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-additional-containers.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-additional-containers.yaml From 5e264521fc642b9c28faa7230c66238e2136538f Mon Sep 17 00:00:00 2001 From: Haja Date: Sat, 28 Sep 2024 00:29:18 +0200 Subject: [PATCH 02/18] additionalContainers related unit tests added for mutation --- internal/manifests/mutate_test.go | 433 ++++++++++++++++++++++++++++++ 1 file changed, 433 insertions(+) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index c165c8535c..4273fd2ef8 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -48,3 +49,435 @@ func TestMutateServiceAccount(t *testing.T) { }, }, existing) } + +func TestMutateDaemonsetAdditionalContainers(t *testing.T) { + tests := []struct { + name string + existing appsv1.DaemonSet + desired appsv1.DaemonSet + }{ + { + name: "add container to daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "remove container from daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify container in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:1.0", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateDeploymentAdditionalContainers(t *testing.T) { + tests := []struct { + name string + existing appsv1.Deployment + desired appsv1.Deployment + }{ + { + name: "add container to deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "remove container from deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify container in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:1.0", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateStatefulSetAdditionalContainers(t *testing.T) { + tests := []struct { + name string + existing appsv1.StatefulSet + desired appsv1.StatefulSet + }{ + { + name: "add container to statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "remove container from statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify container in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + { + Name: "alpine", + Image: "alpine:1.0", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} From f0645f0e21dbd506e7746b97aa26640af677bfd9 Mon Sep 17 00:00:00 2001 From: Haja Date: Sat, 28 Sep 2024 15:18:54 +0200 Subject: [PATCH 03/18] Changed apiversion to v1beta1 in nodeselector e2e test --- ...tall-collectors-without-node-selector.yaml | 38 +++++++++---------- ...install-collectors-with-node-selector.yaml | 38 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml b/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml index b4e3044ef0..baad346f14 100644 --- a/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml +++ b/tests/e2e/node-selector-collector/00-install-collectors-without-node-selector.yaml @@ -1,4 +1,4 @@ -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: deployment @@ -7,16 +7,16 @@ metadata: spec: mode: deployment nodeSelector: - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: @@ -25,7 +25,7 @@ spec: exporters: [debug] --- -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: daemonset @@ -34,16 +34,16 @@ metadata: spec: mode: daemonset nodeSelector: - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: @@ -52,7 +52,7 @@ spec: exporters: [debug] --- -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: statefulset @@ -61,19 +61,19 @@ metadata: spec: mode: statefulset nodeSelector: - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: traces: receivers: [otlp] - exporters: [debug] \ No newline at end of file + exporters: [debug] diff --git a/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml b/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml index b03ae2569e..f83f56eb2c 100644 --- a/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml +++ b/tests/e2e/node-selector-collector/01-install-collectors-with-node-selector.yaml @@ -1,4 +1,4 @@ -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: deployment @@ -8,16 +8,16 @@ spec: mode: deployment nodeSelector: kubernetes.io/os: linux - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: @@ -26,7 +26,7 @@ spec: exporters: [debug] --- -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: daemonset @@ -36,16 +36,16 @@ spec: mode: daemonset nodeSelector: kubernetes.io/os: linux - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: @@ -54,7 +54,7 @@ spec: exporters: [debug] --- -apiVersion: opentelemetry.io/v1alpha1 +apiVersion: opentelemetry.io/v1beta1 kind: OpenTelemetryCollector metadata: name: statefulset @@ -64,19 +64,19 @@ spec: mode: statefulset nodeSelector: kubernetes.io/os: linux - config: | + config: receivers: otlp: protocols: - grpc: - http: - processors: + grpc: {} + http: {} + processors: {} exporters: - debug: + debug: {} service: pipelines: traces: receivers: [otlp] - exporters: [debug] \ No newline at end of file + exporters: [debug] From 69e79d0f224f624b933bbe3c982b0f80e5baa312 Mon Sep 17 00:00:00 2001 From: Haja Date: Sun, 29 Sep 2024 01:07:56 +0200 Subject: [PATCH 04/18] removed explicit zero value for additionalContainers and changed apply to update in chainsaw test --- ...00-install-collectors-without-additional-containers.yaml | 3 --- .../e2e/additional-containers-collector/chainsaw-test.yaml | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml b/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml index 9c474e174a..392395ce4d 100644 --- a/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml +++ b/tests/e2e/additional-containers-collector/00-install-collectors-without-additional-containers.yaml @@ -6,7 +6,6 @@ metadata: additional-containers: without spec: mode: deployment - additionalContainers: [] config: receivers: otlp: @@ -32,7 +31,6 @@ metadata: additional-containers: without spec: mode: daemonset - additionalContainers: [] config: receivers: otlp: @@ -58,7 +56,6 @@ metadata: additional-containers: without spec: mode: statefulset - additionalContainers: [] config: receivers: otlp: diff --git a/tests/e2e/additional-containers-collector/chainsaw-test.yaml b/tests/e2e/additional-containers-collector/chainsaw-test.yaml index e44e5afffe..64b47db477 100644 --- a/tests/e2e/additional-containers-collector/chainsaw-test.yaml +++ b/tests/e2e/additional-containers-collector/chainsaw-test.yaml @@ -23,7 +23,7 @@ spec: - name: step-01 description: collectors with additionalContainers try: - - apply: + - update: file: 01-install-collectors-with-additional-containers.yaml # deployment - assert: @@ -38,7 +38,7 @@ spec: - name: step-02 description: modify additionalContainers try: - - apply: + - update: file: 02-modify-collectors-additional-containers.yaml # deployment - assert: @@ -53,7 +53,7 @@ spec: - name: step-03 description: delete additionalContainers try: - - apply: + - update: file: 00-install-collectors-without-additional-containers.yaml # deployment - assert: From 89cda21630911ef2012a7c873687650d0d2f1f8f Mon Sep 17 00:00:00 2001 From: Haja Date: Sun, 29 Sep 2024 01:37:02 +0200 Subject: [PATCH 05/18] added affinity in collector e2e tests --- .../00-assert-daemonset-without-affinity.yaml | 13 +++ ...00-assert-deployment-without-affinity.yaml | 13 +++ ...0-assert-statefulset-without-affinity.yaml | 13 +++ ...0-install-collectors-without-affinity.yaml | 73 +++++++++++++ .../01-assert-daemonset-with-affinity.yaml | 13 +++ .../01-assert-deployment-with-affinity.yaml | 13 +++ .../01-assert-statefulset-with-affinity.yaml | 13 +++ .../01-install-collectors-with-affinity.yaml | 100 +++++++++++++++++ ...sert-daemonset-with-modified-affinity.yaml | 16 +++ ...ert-deployment-with-modified-affinity.yaml | 16 +++ ...rt-statefulset-with-modified-affinity.yaml | 16 +++ .../02-modify-collectors-affinity.yaml | 103 ++++++++++++++++++ .../e2e/affinity-collector/chainsaw-test.yaml | 66 +++++++++++ 13 files changed, 468 insertions(+) create mode 100644 tests/e2e/affinity-collector/00-assert-daemonset-without-affinity.yaml create mode 100644 tests/e2e/affinity-collector/00-assert-deployment-without-affinity.yaml create mode 100644 tests/e2e/affinity-collector/00-assert-statefulset-without-affinity.yaml create mode 100644 tests/e2e/affinity-collector/00-install-collectors-without-affinity.yaml create mode 100644 tests/e2e/affinity-collector/01-assert-daemonset-with-affinity.yaml create mode 100644 tests/e2e/affinity-collector/01-assert-deployment-with-affinity.yaml create mode 100644 tests/e2e/affinity-collector/01-assert-statefulset-with-affinity.yaml create mode 100644 tests/e2e/affinity-collector/01-install-collectors-with-affinity.yaml create mode 100644 tests/e2e/affinity-collector/02-assert-daemonset-with-modified-affinity.yaml create mode 100644 tests/e2e/affinity-collector/02-assert-deployment-with-modified-affinity.yaml create mode 100644 tests/e2e/affinity-collector/02-assert-statefulset-with-modified-affinity.yaml create mode 100644 tests/e2e/affinity-collector/02-modify-collectors-affinity.yaml create mode 100644 tests/e2e/affinity-collector/chainsaw-test.yaml diff --git a/tests/e2e/affinity-collector/00-assert-daemonset-without-affinity.yaml b/tests/e2e/affinity-collector/00-assert-daemonset-without-affinity.yaml new file mode 100644 index 0000000000..5f3c249b12 --- /dev/null +++ b/tests/e2e/affinity-collector/00-assert-daemonset-without-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: without +spec: + template: + spec: + (affinity == null): true diff --git a/tests/e2e/affinity-collector/00-assert-deployment-without-affinity.yaml b/tests/e2e/affinity-collector/00-assert-deployment-without-affinity.yaml new file mode 100644 index 0000000000..2af7d10f9f --- /dev/null +++ b/tests/e2e/affinity-collector/00-assert-deployment-without-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + affinity: without +spec: + template: + spec: + (affinity == null): true diff --git a/tests/e2e/affinity-collector/00-assert-statefulset-without-affinity.yaml b/tests/e2e/affinity-collector/00-assert-statefulset-without-affinity.yaml new file mode 100644 index 0000000000..2e267cf6a4 --- /dev/null +++ b/tests/e2e/affinity-collector/00-assert-statefulset-without-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: without +spec: + template: + spec: + (affinity == null): true diff --git a/tests/e2e/affinity-collector/00-install-collectors-without-affinity.yaml b/tests/e2e/affinity-collector/00-install-collectors-without-affinity.yaml new file mode 100644 index 0000000000..77e50adc36 --- /dev/null +++ b/tests/e2e/affinity-collector/00-install-collectors-without-affinity.yaml @@ -0,0 +1,73 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + affinity: without +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + affinity: without +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + affinity: without +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/affinity-collector/01-assert-daemonset-with-affinity.yaml b/tests/e2e/affinity-collector/01-assert-daemonset-with-affinity.yaml new file mode 100644 index 0000000000..9abf98b444 --- /dev/null +++ b/tests/e2e/affinity-collector/01-assert-daemonset-with-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + (affinity != null): true diff --git a/tests/e2e/affinity-collector/01-assert-deployment-with-affinity.yaml b/tests/e2e/affinity-collector/01-assert-deployment-with-affinity.yaml new file mode 100644 index 0000000000..114bc50253 --- /dev/null +++ b/tests/e2e/affinity-collector/01-assert-deployment-with-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + (affinity != null): true diff --git a/tests/e2e/affinity-collector/01-assert-statefulset-with-affinity.yaml b/tests/e2e/affinity-collector/01-assert-statefulset-with-affinity.yaml new file mode 100644 index 0000000000..64e580f02a --- /dev/null +++ b/tests/e2e/affinity-collector/01-assert-statefulset-with-affinity.yaml @@ -0,0 +1,13 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + (affinity != null): true diff --git a/tests/e2e/affinity-collector/01-install-collectors-with-affinity.yaml b/tests/e2e/affinity-collector/01-install-collectors-with-affinity.yaml new file mode 100644 index 0000000000..95fcac394a --- /dev/null +++ b/tests/e2e/affinity-collector/01-install-collectors-with-affinity.yaml @@ -0,0 +1,100 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + affinity: with +spec: + mode: deployment + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + affinity: with +spec: + mode: daemonset + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + affinity: with +spec: + mode: statefulset + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/affinity-collector/02-assert-daemonset-with-modified-affinity.yaml b/tests/e2e/affinity-collector/02-assert-daemonset-with-modified-affinity.yaml new file mode 100644 index 0000000000..8ec0913dad --- /dev/null +++ b/tests/e2e/affinity-collector/02-assert-daemonset-with-modified-affinity.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + affinity: + nodeAffinity: + (requiredDuringSchedulingIgnoredDuringExecution == null): true + (preferredDuringSchedulingIgnoredDuringExecution != null): true diff --git a/tests/e2e/affinity-collector/02-assert-deployment-with-modified-affinity.yaml b/tests/e2e/affinity-collector/02-assert-deployment-with-modified-affinity.yaml new file mode 100644 index 0000000000..34d594fe30 --- /dev/null +++ b/tests/e2e/affinity-collector/02-assert-deployment-with-modified-affinity.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + affinity: + nodeAffinity: + (requiredDuringSchedulingIgnoredDuringExecution == null): true + (preferredDuringSchedulingIgnoredDuringExecution != null): true diff --git a/tests/e2e/affinity-collector/02-assert-statefulset-with-modified-affinity.yaml b/tests/e2e/affinity-collector/02-assert-statefulset-with-modified-affinity.yaml new file mode 100644 index 0000000000..530116b1fb --- /dev/null +++ b/tests/e2e/affinity-collector/02-assert-statefulset-with-modified-affinity.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + affinity: with +spec: + template: + spec: + affinity: + nodeAffinity: + (requiredDuringSchedulingIgnoredDuringExecution == null): true + (preferredDuringSchedulingIgnoredDuringExecution != null): true diff --git a/tests/e2e/affinity-collector/02-modify-collectors-affinity.yaml b/tests/e2e/affinity-collector/02-modify-collectors-affinity.yaml new file mode 100644 index 0000000000..dec25b413c --- /dev/null +++ b/tests/e2e/affinity-collector/02-modify-collectors-affinity.yaml @@ -0,0 +1,103 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + affinity: with +spec: + mode: deployment + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + affinity: with +spec: + mode: daemonset + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + affinity: with +spec: + mode: statefulset + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/affinity-collector/chainsaw-test.yaml b/tests/e2e/affinity-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..84d36ad7ed --- /dev/null +++ b/tests/e2e/affinity-collector/chainsaw-test.yaml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: affinity-collector +spec: + steps: + - name: step-00 + description: collectors without affinity + try: + - apply: + file: 00-install-collectors-without-affinity.yaml + # deployment + - assert: + file: 00-assert-deployment-without-affinity.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-affinity.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-affinity.yaml + + - name: step-01 + description: collectors with affinity + try: + - update: + file: 01-install-collectors-with-affinity.yaml + # deployment + - assert: + file: 01-assert-deployment-with-affinity.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-affinity.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-affinity.yaml + + - name: step-02 + description: modify affinity + try: + - update: + file: 02-modify-collectors-affinity.yaml + # deployment + - assert: + file: 02-assert-deployment-with-modified-affinity.yaml + # daemonset + - assert: + file: 02-assert-daemonset-with-modified-affinity.yaml + # statefulset + - assert: + file: 02-assert-statefulset-with-modified-affinity.yaml + + - name: step-03 + description: delete affinity + try: + - update: + file: 00-install-collectors-without-affinity.yaml + # deployment + - assert: + file: 00-assert-deployment-without-affinity.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-affinity.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-affinity.yaml From 5a713c331033fdd8f615cf5a9eccd420379871db Mon Sep 17 00:00:00 2001 From: Haja Date: Sun, 29 Sep 2024 14:41:46 +0200 Subject: [PATCH 06/18] affinity unit tests added for daemonset, deployment, statefulset during mutation --- internal/manifests/mutate_test.go | 588 ++++++++++++++++++++++++++++++ 1 file changed, 588 insertions(+) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index 4273fd2ef8..c8262a56ad 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -481,3 +481,591 @@ func TestMutateStatefulSetAdditionalContainers(t *testing.T) { }) } } + +func TestMutateDaemonsetAffinity(t *testing.T) { + tests := []struct { + name string + existing appsv1.DaemonSet + desired appsv1.DaemonSet + }{ + { + name: "add affinity to daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove affinity from daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify affinity in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateDeploymentAffinity(t *testing.T) { + tests := []struct { + name string + existing appsv1.Deployment + desired appsv1.Deployment + }{ + { + name: "add affinity to deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove affinity from deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify affinity in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateStatefulSetAffinity(t *testing.T) { + tests := []struct { + name string + existing appsv1.StatefulSet + desired appsv1.StatefulSet + }{ + { + name: "add affinity to statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove affinity from statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modify affinity in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"linux"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + Affinity: &corev1.Affinity{ + NodeAffinity: &corev1.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{ + NodeSelectorTerms: []corev1.NodeSelectorTerm{ + { + MatchFields: []corev1.NodeSelectorRequirement{ + { + Key: "kubernetes.io/os", + Operator: corev1.NodeSelectorOpIn, + Values: []string{"windows"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} From e67658120f1b8b84b365fdf00691cee47bd693d9 Mon Sep 17 00:00:00 2001 From: Haja Date: Sun, 29 Sep 2024 22:05:37 +0200 Subject: [PATCH 07/18] collector container mutate args e2e tests added --- .../00-assert-daemonset-without-args.yaml | 16 ++++ .../00-assert-deployment-without-args.yaml | 16 ++++ .../00-assert-statefulset-without-args.yaml | 16 ++++ .../00-install-collectors-without-args.yaml | 73 +++++++++++++++++ .../01-assert-daemonset-with-args.yaml | 15 ++++ .../01-assert-deployment-with-args.yaml | 15 ++++ .../01-assert-statefulset-with-args.yaml | 15 ++++ .../01-install-collectors-with-args.yaml | 79 +++++++++++++++++++ ...2-assert-daemonset-with-modified-args.yaml | 16 ++++ ...-assert-deployment-with-modified-args.yaml | 16 ++++ ...assert-statefulset-with-modified-args.yaml | 16 ++++ .../02-modify-collectors-args.yaml | 79 +++++++++++++++++++ tests/e2e/args-collector/chainsaw-test.yaml | 66 ++++++++++++++++ 13 files changed, 438 insertions(+) create mode 100644 tests/e2e/args-collector/00-assert-daemonset-without-args.yaml create mode 100644 tests/e2e/args-collector/00-assert-deployment-without-args.yaml create mode 100644 tests/e2e/args-collector/00-assert-statefulset-without-args.yaml create mode 100644 tests/e2e/args-collector/00-install-collectors-without-args.yaml create mode 100644 tests/e2e/args-collector/01-assert-daemonset-with-args.yaml create mode 100644 tests/e2e/args-collector/01-assert-deployment-with-args.yaml create mode 100644 tests/e2e/args-collector/01-assert-statefulset-with-args.yaml create mode 100644 tests/e2e/args-collector/01-install-collectors-with-args.yaml create mode 100644 tests/e2e/args-collector/02-assert-daemonset-with-modified-args.yaml create mode 100644 tests/e2e/args-collector/02-assert-deployment-with-modified-args.yaml create mode 100644 tests/e2e/args-collector/02-assert-statefulset-with-modified-args.yaml create mode 100644 tests/e2e/args-collector/02-modify-collectors-args.yaml create mode 100644 tests/e2e/args-collector/chainsaw-test.yaml diff --git a/tests/e2e/args-collector/00-assert-daemonset-without-args.yaml b/tests/e2e/args-collector/00-assert-daemonset-without-args.yaml new file mode 100644 index 0000000000..1319f06b5f --- /dev/null +++ b/tests/e2e/args-collector/00-assert-daemonset-without-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + args: without +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): false diff --git a/tests/e2e/args-collector/00-assert-deployment-without-args.yaml b/tests/e2e/args-collector/00-assert-deployment-without-args.yaml new file mode 100644 index 0000000000..74dd0c998b --- /dev/null +++ b/tests/e2e/args-collector/00-assert-deployment-without-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + args: without +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): false diff --git a/tests/e2e/args-collector/00-assert-statefulset-without-args.yaml b/tests/e2e/args-collector/00-assert-statefulset-without-args.yaml new file mode 100644 index 0000000000..70a30e913b --- /dev/null +++ b/tests/e2e/args-collector/00-assert-statefulset-without-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + args: without +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): false diff --git a/tests/e2e/args-collector/00-install-collectors-without-args.yaml b/tests/e2e/args-collector/00-install-collectors-without-args.yaml new file mode 100644 index 0000000000..5073aaef66 --- /dev/null +++ b/tests/e2e/args-collector/00-install-collectors-without-args.yaml @@ -0,0 +1,73 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + args: without +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + args: without +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + args: without +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/args-collector/01-assert-daemonset-with-args.yaml b/tests/e2e/args-collector/01-assert-daemonset-with-args.yaml new file mode 100644 index 0000000000..0177692267 --- /dev/null +++ b/tests/e2e/args-collector/01-assert-daemonset-with-args.yaml @@ -0,0 +1,15 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): true diff --git a/tests/e2e/args-collector/01-assert-deployment-with-args.yaml b/tests/e2e/args-collector/01-assert-deployment-with-args.yaml new file mode 100644 index 0000000000..c22de26d67 --- /dev/null +++ b/tests/e2e/args-collector/01-assert-deployment-with-args.yaml @@ -0,0 +1,15 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): true diff --git a/tests/e2e/args-collector/01-assert-statefulset-with-args.yaml b/tests/e2e/args-collector/01-assert-statefulset-with-args.yaml new file mode 100644 index 0000000000..3afba4be8e --- /dev/null +++ b/tests/e2e/args-collector/01-assert-statefulset-with-args.yaml @@ -0,0 +1,15 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): true diff --git a/tests/e2e/args-collector/01-install-collectors-with-args.yaml b/tests/e2e/args-collector/01-install-collectors-with-args.yaml new file mode 100644 index 0000000000..8c6a03ab5e --- /dev/null +++ b/tests/e2e/args-collector/01-install-collectors-with-args.yaml @@ -0,0 +1,79 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + args: with +spec: + mode: deployment + args: + extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + args: with +spec: + mode: daemonset + args: + extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + args: with +spec: + mode: statefulset + args: + extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/args-collector/02-assert-daemonset-with-modified-args.yaml b/tests/e2e/args-collector/02-assert-daemonset-with-modified-args.yaml new file mode 100644 index 0000000000..3246c130db --- /dev/null +++ b/tests/e2e/args-collector/02-assert-daemonset-with-modified-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): true diff --git a/tests/e2e/args-collector/02-assert-deployment-with-modified-args.yaml b/tests/e2e/args-collector/02-assert-deployment-with-modified-args.yaml new file mode 100644 index 0000000000..4eedab6b04 --- /dev/null +++ b/tests/e2e/args-collector/02-assert-deployment-with-modified-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): true diff --git a/tests/e2e/args-collector/02-assert-statefulset-with-modified-args.yaml b/tests/e2e/args-collector/02-assert-statefulset-with-modified-args.yaml new file mode 100644 index 0000000000..6ed1dc4461 --- /dev/null +++ b/tests/e2e/args-collector/02-assert-statefulset-with-modified-args.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + args: with +spec: + template: + spec: + ~.(containers): + name: otc-container + (contains(args, '--extra-arg=yes')): false + (contains(args, '--different-extra-arg=yes')): true diff --git a/tests/e2e/args-collector/02-modify-collectors-args.yaml b/tests/e2e/args-collector/02-modify-collectors-args.yaml new file mode 100644 index 0000000000..2d43e6c1f9 --- /dev/null +++ b/tests/e2e/args-collector/02-modify-collectors-args.yaml @@ -0,0 +1,79 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + args: with +spec: + mode: deployment + args: + different-extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + args: with +spec: + mode: daemonset + args: + different-extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + args: with +spec: + mode: statefulset + args: + different-extra-arg: "yes" + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/args-collector/chainsaw-test.yaml b/tests/e2e/args-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..2f3d6a7311 --- /dev/null +++ b/tests/e2e/args-collector/chainsaw-test.yaml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: args-collector +spec: + steps: + - name: step-00 + description: collectors without args + try: + - apply: + file: 00-install-collectors-without-args.yaml + # deployment + - assert: + file: 00-assert-deployment-without-args.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-args.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-args.yaml + + - name: step-01 + description: collectors with args + try: + - update: + file: 01-install-collectors-with-args.yaml + # deployment + - assert: + file: 01-assert-deployment-with-args.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-args.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-args.yaml + + - name: step-02 + description: modify args + try: + - update: + file: 02-modify-collectors-args.yaml + # deployment + - assert: + file: 02-assert-deployment-with-modified-args.yaml + # daemonset + - assert: + file: 02-assert-daemonset-with-modified-args.yaml + # statefulset + - assert: + file: 02-assert-statefulset-with-modified-args.yaml + + - name: step-03 + description: delete args + try: + - update: + file: 00-install-collectors-without-args.yaml + # deployment + - assert: + file: 00-assert-deployment-without-args.yaml + # daemonset + - assert: + file: 00-assert-daemonset-without-args.yaml + # statefulset + - assert: + file: 00-assert-statefulset-without-args.yaml From 9911706c8781a05ff6b1e1ae6353f0fb69cc94bc Mon Sep 17 00:00:00 2001 From: Haja Date: Sun, 29 Sep 2024 22:23:47 +0200 Subject: [PATCH 08/18] Unit tests added for additional args mutation of collector container --- internal/manifests/mutate_test.go | 402 ++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index c8262a56ad..c2d6af497a 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -1069,3 +1069,405 @@ func TestMutateStatefulSetAffinity(t *testing.T) { }) } } + +func TestMutateDaemonsetCollectorArgs(t *testing.T) { + tests := []struct { + name string + existing appsv1.DaemonSet + desired appsv1.DaemonSet + }{ + { + name: "add argument to collector container in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove extra arg from collector container in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "modify extra arg in collector container in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=no"}, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateDeploymentCollectorArgs(t *testing.T) { + tests := []struct { + name string + existing appsv1.Deployment + desired appsv1.Deployment + }{ + { + name: "add argument to collector container in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove extra arg from collector container in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "modify extra arg in collector container in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=no"}, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} + +func TestMutateStatefulSetCollectorArgs(t *testing.T) { + tests := []struct { + name string + existing appsv1.StatefulSet + desired appsv1.StatefulSet + }{ + { + name: "add argument to collector container in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "remove extra arg from collector container in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true"}, + }, + }, + }, + }, + }, + }, + }, + { + name: "modify extra arg in collector container in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + Args: []string{"--deafult-arg=true", "extra-arg=no"}, + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing, tt.desired) + }) + } +} From 6e72bf5e9d9dfe53c4f2a92a929cfea5988b034b Mon Sep 17 00:00:00 2001 From: Haja Date: Wed, 2 Oct 2024 10:31:35 +0200 Subject: [PATCH 09/18] e2e tests for changing labels in collectors --- .../00-assert-daemonset-with-extra-label.yaml | 14 ++++ ...00-assert-deployment-with-extra-label.yaml | 14 ++++ ...0-assert-statefulset-with-extra-label.yaml | 14 ++++ ...0-install-collectors-with-extra-label.yaml | 73 ++++++++++++++++++ ...01-assert-daemonset-with-label-change.yaml | 16 ++++ ...1-assert-deployment-with-label-change.yaml | 16 ++++ ...-assert-statefulset-with-label-change.yaml | 16 ++++ ...-install-collectors-with-label-change.yaml | 76 +++++++++++++++++++ ...-assert-daemonset-without-extra-label.yaml | 16 ++++ ...assert-deployment-without-extra-label.yaml | 16 ++++ ...ssert-statefulset-without-extra-label.yaml | 16 ++++ ...nstall-collectors-without-extra-label.yaml | 67 ++++++++++++++++ .../label-change-collector/chainsaw-test.yaml | 51 +++++++++++++ 13 files changed, 405 insertions(+) create mode 100644 tests/e2e/label-change-collector/00-assert-daemonset-with-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/00-assert-deployment-with-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/00-assert-statefulset-with-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/00-install-collectors-with-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/01-assert-daemonset-with-label-change.yaml create mode 100644 tests/e2e/label-change-collector/01-assert-deployment-with-label-change.yaml create mode 100644 tests/e2e/label-change-collector/01-assert-statefulset-with-label-change.yaml create mode 100644 tests/e2e/label-change-collector/01-install-collectors-with-label-change.yaml create mode 100644 tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/02-install-collectors-without-extra-label.yaml create mode 100644 tests/e2e/label-change-collector/chainsaw-test.yaml diff --git a/tests/e2e/label-change-collector/00-assert-daemonset-with-extra-label.yaml b/tests/e2e/label-change-collector/00-assert-daemonset-with-extra-label.yaml new file mode 100644 index 0000000000..08e3c0661f --- /dev/null +++ b/tests/e2e/label-change-collector/00-assert-daemonset-with-extra-label.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "existing" +spec: + template: + metadata: + labels: + user-label: "existing" diff --git a/tests/e2e/label-change-collector/00-assert-deployment-with-extra-label.yaml b/tests/e2e/label-change-collector/00-assert-deployment-with-extra-label.yaml new file mode 100644 index 0000000000..91f64baf7e --- /dev/null +++ b/tests/e2e/label-change-collector/00-assert-deployment-with-extra-label.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "existing" +spec: + template: + metadata: + labels: + user-label: "existing" diff --git a/tests/e2e/label-change-collector/00-assert-statefulset-with-extra-label.yaml b/tests/e2e/label-change-collector/00-assert-statefulset-with-extra-label.yaml new file mode 100644 index 0000000000..575d27cd50 --- /dev/null +++ b/tests/e2e/label-change-collector/00-assert-statefulset-with-extra-label.yaml @@ -0,0 +1,14 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "existing" +spec: + template: + metadata: + labels: + user-label: "existing" diff --git a/tests/e2e/label-change-collector/00-install-collectors-with-extra-label.yaml b/tests/e2e/label-change-collector/00-install-collectors-with-extra-label.yaml new file mode 100644 index 0000000000..27fe143df5 --- /dev/null +++ b/tests/e2e/label-change-collector/00-install-collectors-with-extra-label.yaml @@ -0,0 +1,73 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + user-label: "existing" +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + user-label: "existing" +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + user-label: "existing" +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/label-change-collector/01-assert-daemonset-with-label-change.yaml b/tests/e2e/label-change-collector/01-assert-daemonset-with-label-change.yaml new file mode 100644 index 0000000000..770106939d --- /dev/null +++ b/tests/e2e/label-change-collector/01-assert-daemonset-with-label-change.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "modified" + new-label: "yes" +spec: + template: + metadata: + labels: + user-label: "modified" + new-label: "yes" diff --git a/tests/e2e/label-change-collector/01-assert-deployment-with-label-change.yaml b/tests/e2e/label-change-collector/01-assert-deployment-with-label-change.yaml new file mode 100644 index 0000000000..f694609ef1 --- /dev/null +++ b/tests/e2e/label-change-collector/01-assert-deployment-with-label-change.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "modified" + new-label: "yes" +spec: + template: + metadata: + labels: + user-label: "modified" + new-label: "yes" diff --git a/tests/e2e/label-change-collector/01-assert-statefulset-with-label-change.yaml b/tests/e2e/label-change-collector/01-assert-statefulset-with-label-change.yaml new file mode 100644 index 0000000000..64a857d051 --- /dev/null +++ b/tests/e2e/label-change-collector/01-assert-statefulset-with-label-change.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + user-label: "modified" + new-label: "yes" +spec: + template: + metadata: + labels: + user-label: "modified" + new-label: "yes" diff --git a/tests/e2e/label-change-collector/01-install-collectors-with-label-change.yaml b/tests/e2e/label-change-collector/01-install-collectors-with-label-change.yaml new file mode 100644 index 0000000000..46ca873c80 --- /dev/null +++ b/tests/e2e/label-change-collector/01-install-collectors-with-label-change.yaml @@ -0,0 +1,76 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + labels: + user-label: "modified" + new-label: "yes" +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + labels: + user-label: "modified" + new-label: "yes" +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + labels: + user-label: "modified" + new-label: "yes" +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml new file mode 100644 index 0000000000..8e07c89fe1 --- /dev/null +++ b/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: daemonset-collector + app.kubernetes.io/part-of: opentelemetry + (user-label == nil): true + (new-label == nil): true +spec: + template: + metadata: + labels: + (user-label == nil): true + (new-label == nil): true diff --git a/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml new file mode 100644 index 0000000000..20cca20819 --- /dev/null +++ b/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: deployment-collector + app.kubernetes.io/part-of: opentelemetry + (user-label == nil): true + (new-label == nil): true +spec: + template: + metadata: + labels: + (user-label == nil): true + (new-label == nil): true diff --git a/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml new file mode 100644 index 0000000000..e3a0d26709 --- /dev/null +++ b/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml @@ -0,0 +1,16 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: opentelemetry-collector + app.kubernetes.io/managed-by: opentelemetry-operator + app.kubernetes.io/name: statefulset-collector + app.kubernetes.io/part-of: opentelemetry + (user-label == nil): true + (new-label == nil): true +spec: + template: + metadata: + labels: + (user-label == nil): true + (new-label == nil): true diff --git a/tests/e2e/label-change-collector/02-install-collectors-without-extra-label.yaml b/tests/e2e/label-change-collector/02-install-collectors-without-extra-label.yaml new file mode 100644 index 0000000000..4a50758f63 --- /dev/null +++ b/tests/e2e/label-change-collector/02-install-collectors-without-extra-label.yaml @@ -0,0 +1,67 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/label-change-collector/chainsaw-test.yaml b/tests/e2e/label-change-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..470c5f7c34 --- /dev/null +++ b/tests/e2e/label-change-collector/chainsaw-test.yaml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: label-change-collector +spec: + steps: + - name: step-00 + description: collectors with an extra label + try: + - apply: + file: 00-install-collectors-with-extra-label.yaml + # deployment + - assert: + file: 00-assert-deployment-with-extra-label.yaml + # daemonset + - assert: + file: 00-assert-daemonset-with-extra-label.yaml + # statefulset + - assert: + file: 00-assert-statefulset-with-extra-label.yaml + + - name: step-01 + description: collectors with changed extra labels + try: + - update: + file: 01-install-collectors-with-label-change.yaml + # deployment + - assert: + file: 01-assert-deployment-with-label-change.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-label-change.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-label-change.yaml + + - name: step-02 + description: delete extra label from collector + try: + - update: + file: 02-install-collectors-without-extra-label.yaml + # deployment + - assert: + file: 02-assert-deployment-without-extra-label.yaml + # daemonset + - assert: + file: 02-assert-daemonset-without-extra-label.yaml + # statefulset + - assert: + file: 02-assert-statefulset-without-extra-label.yaml From 4ae33981aa3dc7fd33a12a342803a1f040d906b6 Mon Sep 17 00:00:00 2001 From: Haja Date: Wed, 2 Oct 2024 10:45:17 +0200 Subject: [PATCH 10/18] e2e tests for changing annotations in collectors --- ...ssert-daemonset-with-extra-annotation.yaml | 10 +++ ...sert-deployment-with-extra-annotation.yaml | 10 +++ ...ert-statefulset-with-extra-annotation.yaml | 10 +++ ...tall-collectors-with-extra-annotation.yaml | 73 ++++++++++++++++++ ...sert-daemonset-with-annotation-change.yaml | 12 +++ ...ert-deployment-with-annotation-change.yaml | 12 +++ ...rt-statefulset-with-annotation-change.yaml | 12 +++ ...all-collectors-with-annotation-change.yaml | 76 +++++++++++++++++++ ...rt-daemonset-without-extra-annotation.yaml | 12 +++ ...t-deployment-without-extra-annotation.yaml | 12 +++ ...-statefulset-without-extra-annotation.yaml | 12 +++ ...l-collectors-without-extra-annotation.yaml | 67 ++++++++++++++++ .../chainsaw-test.yaml | 51 +++++++++++++ 13 files changed, 369 insertions(+) create mode 100644 tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/00-install-collectors-with-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml create mode 100644 tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml create mode 100644 tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml create mode 100644 tests/e2e/annotation-change-collector/01-install-collectors-with-annotation-change.yaml create mode 100644 tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/02-install-collectors-without-extra-annotation.yaml create mode 100644 tests/e2e/annotation-change-collector/chainsaw-test.yaml diff --git a/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml new file mode 100644 index 0000000000..5ee2f05652 --- /dev/null +++ b/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + user-annotation: "existing" +spec: + template: + metadata: + annotations: + user-annotation: "existing" diff --git a/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml new file mode 100644 index 0000000000..3514f28f82 --- /dev/null +++ b/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + user-annotation: "existing" +spec: + template: + metadata: + annotations: + user-annotation: "existing" diff --git a/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml new file mode 100644 index 0000000000..f385e1f20e --- /dev/null +++ b/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml @@ -0,0 +1,10 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + annotations: + user-annotation: "existing" +spec: + template: + metadata: + annotations: + user-annotation: "existing" diff --git a/tests/e2e/annotation-change-collector/00-install-collectors-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-install-collectors-with-extra-annotation.yaml new file mode 100644 index 0000000000..5e21322a3f --- /dev/null +++ b/tests/e2e/annotation-change-collector/00-install-collectors-with-extra-annotation.yaml @@ -0,0 +1,73 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + annotations: + user-annotation: "existing" +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + annotations: + user-annotation: "existing" +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + annotations: + user-annotation: "existing" +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml new file mode 100644 index 0000000000..e6ce2489b1 --- /dev/null +++ b/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + template: + metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml new file mode 100644 index 0000000000..1bdb9c0f82 --- /dev/null +++ b/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + template: + metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml new file mode 100644 index 0000000000..48135be6ce --- /dev/null +++ b/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + template: + metadata: + annotations: + user-annotation: "modified" + new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/01-install-collectors-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-install-collectors-with-annotation-change.yaml new file mode 100644 index 0000000000..bd02ae5766 --- /dev/null +++ b/tests/e2e/annotation-change-collector/01-install-collectors-with-annotation-change.yaml @@ -0,0 +1,76 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset + annotations: + user-annotation: "modified" + new-annotation: "yes" +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml new file mode 100644 index 0000000000..1be277c492 --- /dev/null +++ b/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true +spec: + template: + metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true diff --git a/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml new file mode 100644 index 0000000000..9088b9cba9 --- /dev/null +++ b/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true +spec: + template: + metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true diff --git a/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml new file mode 100644 index 0000000000..0de9920c71 --- /dev/null +++ b/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml @@ -0,0 +1,12 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true +spec: + template: + metadata: + annotations: + (user-annotation == nil): true + (new-annotation == nil): true diff --git a/tests/e2e/annotation-change-collector/02-install-collectors-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-install-collectors-without-extra-annotation.yaml new file mode 100644 index 0000000000..4a50758f63 --- /dev/null +++ b/tests/e2e/annotation-change-collector/02-install-collectors-without-extra-annotation.yaml @@ -0,0 +1,67 @@ +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: deployment +spec: + mode: deployment + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: daemonset +spec: + mode: daemonset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] + +--- +apiVersion: opentelemetry.io/v1beta1 +kind: OpenTelemetryCollector +metadata: + name: statefulset +spec: + mode: statefulset + config: + receivers: + otlp: + protocols: + grpc: {} + processors: {} + + exporters: + debug: {} + + service: + pipelines: + traces: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/annotation-change-collector/chainsaw-test.yaml b/tests/e2e/annotation-change-collector/chainsaw-test.yaml new file mode 100644 index 0000000000..eeb4e2ccba --- /dev/null +++ b/tests/e2e/annotation-change-collector/chainsaw-test.yaml @@ -0,0 +1,51 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: annotation-change-collector +spec: + steps: + - name: step-00 + description: collectors with an extra annotation + try: + - apply: + file: 00-install-collectors-with-extra-annotation.yaml + # deployment + - assert: + file: 00-assert-deployment-with-extra-annotation.yaml + # daemonset + - assert: + file: 00-assert-daemonset-with-extra-annotation.yaml + # statefulset + - assert: + file: 00-assert-statefulset-with-extra-annotation.yaml + + - name: step-01 + description: collectors with changed extra annotations + try: + - update: + file: 01-install-collectors-with-annotation-change.yaml + # deployment + - assert: + file: 01-assert-deployment-with-annotation-change.yaml + # daemonset + - assert: + file: 01-assert-daemonset-with-annotation-change.yaml + # statefulset + - assert: + file: 01-assert-statefulset-with-annotation-change.yaml + + - name: step-02 + description: delete extra annotation from collector + try: + - update: + file: 02-install-collectors-without-extra-annotation.yaml + # deployment + - assert: + file: 02-assert-deployment-without-extra-annotation.yaml + # daemonset + - assert: + file: 02-assert-daemonset-without-extra-annotation.yaml + # statefulset + - assert: + file: 02-assert-statefulset-without-extra-annotation.yaml From 74fbdc1f0a9c29ca2ad14a954b66a740fd3d3f54 Mon Sep 17 00:00:00 2001 From: David Haja Date: Wed, 2 Oct 2024 18:34:46 +0200 Subject: [PATCH 11/18] fix annotation change e2e test asserts --- .../00-assert-daemonset-with-extra-annotation.yaml | 1 + .../00-assert-deployment-with-extra-annotation.yaml | 1 + .../00-assert-statefulset-with-extra-annotation.yaml | 1 + .../01-assert-daemonset-with-annotation-change.yaml | 1 + .../01-assert-deployment-with-annotation-change.yaml | 1 + .../01-assert-statefulset-with-annotation-change.yaml | 1 + .../02-assert-daemonset-without-extra-annotation.yaml | 9 +++------ .../02-assert-deployment-without-extra-annotation.yaml | 9 +++------ .../02-assert-statefulset-without-extra-annotation.yaml | 9 +++------ 9 files changed, 15 insertions(+), 18 deletions(-) diff --git a/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml index 5ee2f05652..e33371e300 100644 --- a/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/00-assert-daemonset-with-extra-annotation.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: + name: daemonset-collector annotations: user-annotation: "existing" spec: diff --git a/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml index 3514f28f82..e02ad87341 100644 --- a/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/00-assert-deployment-with-extra-annotation.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: + name: deployment-collector annotations: user-annotation: "existing" spec: diff --git a/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml b/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml index f385e1f20e..b74f1945b0 100644 --- a/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/00-assert-statefulset-with-extra-annotation.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: StatefulSet metadata: + name: statefulset-collector annotations: user-annotation: "existing" spec: diff --git a/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml index e6ce2489b1..522e45cfba 100644 --- a/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml +++ b/tests/e2e/annotation-change-collector/01-assert-daemonset-with-annotation-change.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: + name: daemonset-collector annotations: user-annotation: "modified" new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml index 1bdb9c0f82..86b0ac0e6f 100644 --- a/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml +++ b/tests/e2e/annotation-change-collector/01-assert-deployment-with-annotation-change.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: + name: deployment-collector annotations: user-annotation: "modified" new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml b/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml index 48135be6ce..c0bc38d353 100644 --- a/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml +++ b/tests/e2e/annotation-change-collector/01-assert-statefulset-with-annotation-change.yaml @@ -1,6 +1,7 @@ apiVersion: apps/v1 kind: StatefulSet metadata: + name: statefulset-collector annotations: user-annotation: "modified" new-annotation: "yes" diff --git a/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml index 1be277c492..b6059f7e8c 100644 --- a/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/02-assert-daemonset-without-extra-annotation.yaml @@ -1,12 +1,9 @@ apiVersion: apps/v1 kind: DaemonSet metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + name: daemonset-collector spec: template: metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + (contains(keys(annotations), 'user-annotation')): false + (contains(keys(annotations), 'new-annotation')): false diff --git a/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml index 9088b9cba9..42c1fb3a7e 100644 --- a/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/02-assert-deployment-without-extra-annotation.yaml @@ -1,12 +1,9 @@ apiVersion: apps/v1 kind: Deployment metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + name: deployment-collector spec: template: metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + (contains(keys(annotations), 'user-annotation')): false + (contains(keys(annotations), 'new-annotation')): false diff --git a/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml b/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml index 0de9920c71..f293218ba0 100644 --- a/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml +++ b/tests/e2e/annotation-change-collector/02-assert-statefulset-without-extra-annotation.yaml @@ -1,12 +1,9 @@ apiVersion: apps/v1 kind: StatefulSet metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + name: statefulset-collector spec: template: metadata: - annotations: - (user-annotation == nil): true - (new-annotation == nil): true + (contains(keys(annotations), 'user-annotation')): false + (contains(keys(annotations), 'new-annotation')): false From 15f211321af3c2e59e547d91bfeab3c7ade7dd85 Mon Sep 17 00:00:00 2001 From: David Haja Date: Thu, 3 Oct 2024 09:17:25 +0200 Subject: [PATCH 12/18] Error and label change related unit tests added for resource mutation --- internal/manifests/mutate_test.go | 1003 +++++++++++++++++++++++++++++ 1 file changed, 1003 insertions(+) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index c2d6af497a..0eeac2248b 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -1471,3 +1471,1006 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { }) } } + +func TestNoImmutableLabelChange(t *testing.T) { + existingSelectorLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + } + desiredLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "extra-label": "true", + } + err := hasImmutableLabelChange(existingSelectorLabels, desiredLabels) + require.NoError(t, err) + assert.NoError(t, err) +} + +func TestHasImmutableLabelChange(t *testing.T) { + existingSelectorLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + } + desiredLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + } + err := hasImmutableLabelChange(existingSelectorLabels, desiredLabels) + assert.Error(t, err) +} + +func TestMissingImmutableLabelChange(t *testing.T) { + existingSelectorLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + } + desiredLabels := map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + } + err := hasImmutableLabelChange(existingSelectorLabels, desiredLabels) + assert.Error(t, err) +} + +func TestMutateDaemonsetError(t *testing.T) { + tests := []struct { + name string + existing appsv1.DaemonSet + desired appsv1.DaemonSet + }{ + { + name: "modified immutable label in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modified immutable selector in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + assert.Error(t, err) + }) + } +} + +func TestMutateDeploymentError(t *testing.T) { + tests := []struct { + name string + existing appsv1.Deployment + desired appsv1.Deployment + }{ + { + name: "modified immutable label in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modified immutable selector in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + assert.Error(t, err) + }) + } +} + +func TestMutateStatefulSetError(t *testing.T) { + tests := []struct { + name string + existing appsv1.StatefulSet + desired appsv1.StatefulSet + }{ + { + name: "modified immutable label in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "modified immutable selector in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "not-opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + assert.Error(t, err) + }) + } +} + +func TestMutateDaemonsetLabelChange(t *testing.T) { + tests := []struct { + name string + existing appsv1.DaemonSet + desired appsv1.DaemonSet + }{ + { + name: "modified label in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "new label in daemonset", + existing: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "daemonset", + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.daemonset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "new-user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing.Spec, tt.desired.Spec) + }) + } +} + +func TestMutateDeploymentLabelChange(t *testing.T) { + tests := []struct { + name string + existing appsv1.Deployment + desired appsv1.Deployment + }{ + { + name: "modified label in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "new label in deployment", + existing: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deployment", + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.deployment", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "new-user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing.Spec, tt.desired.Spec) + }) + } +} + +func TestMutateStatefulSetLabelChange(t *testing.T) { + tests := []struct { + name string + existing appsv1.StatefulSet + desired appsv1.StatefulSet + }{ + { + name: "modified label in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + { + name: "new label in statefulset", + existing: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + CreationTimestamp: metav1.Now(), + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "user-label": "existing", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + desired: appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "statefulset", + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + }, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "app.kubernetes.io/component": "opentelemetry-collector", + "app.kubernetes.io/instance": "default.statefulset", + "app.kubernetes.io/managed-by": "opentelemetry-operator", + "app.kubernetes.io/part-of": "opentelemetry", + "new-user-label": "desired", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "collector", + Image: "collector:latest", + }, + }, + }, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mutateFn := MutateFuncFor(&tt.existing, &tt.desired) + err := mutateFn() + require.NoError(t, err) + assert.Equal(t, tt.existing.Spec, tt.desired.Spec) + }) + } +} From 88ef17b63b7cbf46e393a005a7dbc4f34a8629ca Mon Sep 17 00:00:00 2001 From: David Haja Date: Thu, 3 Oct 2024 09:46:51 +0200 Subject: [PATCH 13/18] fix label change e2e tests for mutation --- .../02-assert-daemonset-without-extra-label.yaml | 9 ++++----- .../02-assert-deployment-without-extra-label.yaml | 9 ++++----- .../02-assert-statefulset-without-extra-label.yaml | 9 ++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml index 8e07c89fe1..ba48302357 100644 --- a/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml +++ b/tests/e2e/label-change-collector/02-assert-daemonset-without-extra-label.yaml @@ -1,16 +1,15 @@ apiVersion: apps/v1 kind: DaemonSet metadata: + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false labels: app.kubernetes.io/component: opentelemetry-collector app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/name: daemonset-collector app.kubernetes.io/part-of: opentelemetry - (user-label == nil): true - (new-label == nil): true spec: template: metadata: - labels: - (user-label == nil): true - (new-label == nil): true + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false diff --git a/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml index 20cca20819..0e972156e8 100644 --- a/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml +++ b/tests/e2e/label-change-collector/02-assert-deployment-without-extra-label.yaml @@ -1,16 +1,15 @@ apiVersion: apps/v1 kind: Deployment metadata: + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false labels: app.kubernetes.io/component: opentelemetry-collector app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/name: deployment-collector app.kubernetes.io/part-of: opentelemetry - (user-label == nil): true - (new-label == nil): true spec: template: metadata: - labels: - (user-label == nil): true - (new-label == nil): true + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false diff --git a/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml b/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml index e3a0d26709..f3763314b4 100644 --- a/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml +++ b/tests/e2e/label-change-collector/02-assert-statefulset-without-extra-label.yaml @@ -1,16 +1,15 @@ apiVersion: apps/v1 kind: StatefulSet metadata: + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false labels: app.kubernetes.io/component: opentelemetry-collector app.kubernetes.io/managed-by: opentelemetry-operator app.kubernetes.io/name: statefulset-collector app.kubernetes.io/part-of: opentelemetry - (user-label == nil): true - (new-label == nil): true spec: template: metadata: - labels: - (user-label == nil): true - (new-label == nil): true + (contains(keys(labels),'user-label')): false + (contains(keys(labels),'new-label')): false From fc1e3ad966bbc3121d387c00c881eed13f1a2e1f Mon Sep 17 00:00:00 2001 From: David Haja Date: Thu, 3 Oct 2024 15:12:42 +0200 Subject: [PATCH 14/18] mutating the spec and labels of deployment, daemonset, statefulset with mergeWithOverwriteWithEmptyValue --- controllers/common.go | 2 +- internal/manifests/mutate.go | 112 ++++++++++++++--------------------- 2 files changed, 45 insertions(+), 69 deletions(-) diff --git a/controllers/common.go b/controllers/common.go index 3003907913..01b254128a 100644 --- a/controllers/common.go +++ b/controllers/common.go @@ -155,7 +155,7 @@ func reconcileDesiredObjects(ctx context.Context, kubeClient client.Client, logg op = result return createOrUpdateErr }) - if crudErr != nil && errors.Is(crudErr, manifests.ImmutableChangeErr) { + if crudErr != nil && errors.As(crudErr, &manifests.ImmutableChangeErr) { l.Error(crudErr, "detected immutable field change, trying to delete, new object will be created on next reconcile", "existing", existing.GetName()) delErr := kubeClient.Delete(ctx, existing) if delErr != nil { diff --git a/internal/manifests/mutate.go b/internal/manifests/mutate.go index 75c1a07804..8ae436699a 100644 --- a/internal/manifests/mutate.go +++ b/internal/manifests/mutate.go @@ -15,7 +15,6 @@ package manifests import ( - "errors" "fmt" "reflect" @@ -33,8 +32,16 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) +type ImmutableFieldChangeErr struct { + Field string +} + +func (e *ImmutableFieldChangeErr) Error() string { + return fmt.Sprintf("Immutable field change attempted: %s", e.Field) +} + var ( - ImmutableChangeErr = errors.New("immutable field change attempted") + ImmutableChangeErr *ImmutableFieldChangeErr ) // MutateFuncFor returns a mutate function based on the @@ -71,7 +78,7 @@ func MutateFuncFor(existing, desired client.Object) controllerutil.MutateFn { // Get the existing labels and override any conflicts with the desired labels // This will preserve any labels on the existing set. existingLabels := existing.GetLabels() - if err := mergeWithOverride(&existingLabels, desired.GetLabels()); err != nil { + if err := mergeWithOverwriteWithEmptyValue(&existingLabels, desired.GetLabels()); err != nil { return err } existing.SetLabels(existingLabels) @@ -265,84 +272,53 @@ func mutateService(existing, desired *corev1.Service) { } func mutateDaemonset(existing, desired *appsv1.DaemonSet) error { - if !existing.CreationTimestamp.IsZero() && !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { - return ImmutableChangeErr - } - // Daemonset selector is immutable so we set this value only if - // a new object is going to be created - if existing.CreationTimestamp.IsZero() { - existing.Spec.Selector = desired.Spec.Selector - } - if err := mergeWithOverride(&existing.Spec, desired.Spec); err != nil { - return err - } - if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { - return err + if !existing.CreationTimestamp.IsZero() { + if !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { + return &ImmutableFieldChangeErr{Field: "Spec.Selector"} + } + if err := hasImmutableLabelChange(existing.Spec.Selector.MatchLabels, desired.Spec.Template.Labels); err != nil { + return err + } } - return nil + + return mergeWithOverwriteWithEmptyValue(&existing.Spec, desired.Spec) } func mutateDeployment(existing, desired *appsv1.Deployment) error { - if !existing.CreationTimestamp.IsZero() && !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { - return ImmutableChangeErr - } - // Deployment selector is immutable so we set this value only if - // a new object is going to be created - if existing.CreationTimestamp.IsZero() { - existing.Spec.Selector = desired.Spec.Selector - } - existing.Spec.Replicas = desired.Spec.Replicas - if err := mergeWithOverride(&existing.Spec.Template, desired.Spec.Template); err != nil { - return err - } - if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { - return err - } - if err := mergeWithOverride(&existing.Spec.Strategy, desired.Spec.Strategy); err != nil { - return err + if !existing.CreationTimestamp.IsZero() { + if !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { + return &ImmutableFieldChangeErr{Field: "Spec.Selector"} + } + if err := hasImmutableLabelChange(existing.Spec.Selector.MatchLabels, desired.Spec.Template.Labels); err != nil { + return err + } } - return nil + return mergeWithOverwriteWithEmptyValue(&existing.Spec, desired.Spec) } func mutateStatefulSet(existing, desired *appsv1.StatefulSet) error { - if hasChange, field := hasImmutableFieldChange(existing, desired); hasChange { - return fmt.Errorf("%s is being changed, %w", field, ImmutableChangeErr) - } - // StatefulSet selector is immutable so we set this value only if - // a new object is going to be created - if existing.CreationTimestamp.IsZero() { - existing.Spec.Selector = desired.Spec.Selector + if !existing.CreationTimestamp.IsZero() { + if !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { + return &ImmutableFieldChangeErr{Field: "Spec.Selector"} + } + if err := hasImmutableLabelChange(existing.Spec.Selector.MatchLabels, desired.Spec.Template.Labels); err != nil { + return err + } + if hasVolumeClaimsTemplatesChanged(existing, desired) { + return &ImmutableFieldChangeErr{Field: "Spec.VolumeClaimTemplates"} + } } - existing.Spec.PodManagementPolicy = desired.Spec.PodManagementPolicy - existing.Spec.Replicas = desired.Spec.Replicas - for i := range existing.Spec.VolumeClaimTemplates { - existing.Spec.VolumeClaimTemplates[i].TypeMeta = desired.Spec.VolumeClaimTemplates[i].TypeMeta - existing.Spec.VolumeClaimTemplates[i].ObjectMeta = desired.Spec.VolumeClaimTemplates[i].ObjectMeta - existing.Spec.VolumeClaimTemplates[i].Spec = desired.Spec.VolumeClaimTemplates[i].Spec - } - if err := mergeWithOverride(&existing.Spec.Template, desired.Spec.Template); err != nil { - return err - } - if err := mergeWithOverwriteWithEmptyValue(&existing.Spec.Template.Spec.NodeSelector, desired.Spec.Template.Spec.NodeSelector); err != nil { - return err - } - return nil + return mergeWithOverwriteWithEmptyValue(&existing.Spec, desired.Spec) } -func hasImmutableFieldChange(existing, desired *appsv1.StatefulSet) (bool, string) { - if existing.CreationTimestamp.IsZero() { - return false, "" - } - if !apiequality.Semantic.DeepEqual(desired.Spec.Selector, existing.Spec.Selector) { - return true, fmt.Sprintf("Spec.Selector: desired: %s existing: %s", desired.Spec.Selector, existing.Spec.Selector) - } - - if hasVolumeClaimsTemplatesChanged(existing, desired) { - return true, "Spec.VolumeClaimTemplates" +func hasImmutableLabelChange(existingSelectorLabels, desiredLabels map[string]string) error { + for k, v := range existingSelectorLabels { + if vv, ok := desiredLabels[k]; !ok || vv != v { + return &ImmutableFieldChangeErr{Field: "Spec.Template.Metadata.Labels"} + } } - - return false, "" + return nil } // hasVolumeClaimsTemplatesChanged if volume claims template change has been detected. From 9060661d6b82011f77cfa0cebd5a8580bfaa9111 Mon Sep 17 00:00:00 2001 From: David Haja Date: Fri, 4 Oct 2024 10:04:42 +0200 Subject: [PATCH 15/18] Adjust reconcile tests to new mutation logic --- controllers/reconcile_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/controllers/reconcile_test.go b/controllers/reconcile_test.go index 46b0d38837..2891ebddd6 100644 --- a/controllers/reconcile_test.go +++ b/controllers/reconcile_test.go @@ -196,9 +196,8 @@ func TestOpenTelemetryCollectorReconciler_Reconcile(t *testing.T) { // confirm the strategy has been changed assert.Equal(t, d.Spec.Strategy.RollingUpdate.MaxUnavailable.IntVal, int32(1)) assert.Equal(t, d.Spec.Strategy.RollingUpdate.MaxSurge.IntVal, int32(1)) - // confirm that we don't remove annotations and labels even if we don't set them + // confirm that we don't remove annotations from metadata even if we don't set them assert.Contains(t, d.Annotations, annotationName) - assert.Contains(t, d.Labels, labelName) actual := v1.Service{} exists, err = populateObjectIfExists(t, &actual, namespacedObjectName(naming.Service(params.Name), params.Namespace)) assert.NoError(t, err) @@ -757,9 +756,6 @@ func TestOpAMPBridgeReconciler_Reconcile(t *testing.T) { 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.Name), params.Namespace)) assert.NoError(t, err) From 8f5fd10d4baeecffaf2d483181bb3e5036cb46b1 Mon Sep 17 00:00:00 2001 From: David Haja Date: Fri, 4 Oct 2024 10:14:34 +0200 Subject: [PATCH 16/18] Added chlog entry for new mutation logic --- .chloggen/2947-updating-ds-sf-depl-mutation.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 .chloggen/2947-updating-ds-sf-depl-mutation.yaml diff --git a/.chloggen/2947-updating-ds-sf-depl-mutation.yaml b/.chloggen/2947-updating-ds-sf-depl-mutation.yaml new file mode 100755 index 0000000000..baa4dd06c8 --- /dev/null +++ b/.chloggen/2947-updating-ds-sf-depl-mutation.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: collector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Improve mutation of deployments, statefulsets, and daemonsets allowing to remove fields on update" + +# One or more tracking issues related to the change +issues: [2947] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: From 62dc6935d09032a7589c91353095d2670eee1cd5 Mon Sep 17 00:00:00 2001 From: David Haja Date: Fri, 4 Oct 2024 11:01:57 +0200 Subject: [PATCH 17/18] fix typo in mutate_test.go --- internal/manifests/mutate_test.go | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index 0eeac2248b..11f40aa970 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -1089,7 +1089,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1107,7 +1107,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1128,7 +1128,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1146,7 +1146,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1167,7 +1167,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1185,7 +1185,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=no"}, + Args: []string{"--default-arg=true", "extra-arg=no"}, }, }, }, @@ -1223,7 +1223,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1241,7 +1241,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1262,7 +1262,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1280,7 +1280,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1301,7 +1301,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1319,7 +1319,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=no"}, + Args: []string{"--default-arg=true", "extra-arg=no"}, }, }, }, @@ -1357,7 +1357,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1375,7 +1375,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1396,7 +1396,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1414,7 +1414,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true"}, + Args: []string{"--default-arg=true"}, }, }, }, @@ -1435,7 +1435,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=yes"}, + Args: []string{"--default-arg=true", "extra-arg=yes"}, }, }, }, @@ -1453,7 +1453,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { { Name: "collector", Image: "collector:latest", - Args: []string{"--deafult-arg=true", "extra-arg=no"}, + Args: []string{"--default-arg=true", "extra-arg=no"}, }, }, }, From 764f05466865085aacde8928a0e1bfd3d05f821f Mon Sep 17 00:00:00 2001 From: David Haja Date: Fri, 4 Oct 2024 11:16:56 +0200 Subject: [PATCH 18/18] Fix G601: Implicit memory aliasing in mutate_test.go --- internal/manifests/mutate_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/internal/manifests/mutate_test.go b/internal/manifests/mutate_test.go index 11f40aa970..2621116197 100644 --- a/internal/manifests/mutate_test.go +++ b/internal/manifests/mutate_test.go @@ -185,6 +185,7 @@ func TestMutateDaemonsetAdditionalContainers(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -329,6 +330,7 @@ func TestMutateDeploymentAdditionalContainers(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -473,6 +475,7 @@ func TestMutateStatefulSetAdditionalContainers(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -669,6 +672,7 @@ func TestMutateDaemonsetAffinity(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -865,6 +869,7 @@ func TestMutateDeploymentAffinity(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1061,6 +1066,7 @@ func TestMutateStatefulSetAffinity(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1195,6 +1201,7 @@ func TestMutateDaemonsetCollectorArgs(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1329,6 +1336,7 @@ func TestMutateDeploymentCollectorArgs(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1463,6 +1471,7 @@ func TestMutateStatefulSetCollectorArgs(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1672,6 +1681,7 @@ func TestMutateDaemonsetError(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1828,6 +1838,7 @@ func TestMutateDeploymentError(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -1984,6 +1995,7 @@ func TestMutateStatefulSetError(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -2144,6 +2156,7 @@ func TestMutateDaemonsetLabelChange(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -2305,6 +2318,7 @@ func TestMutateDeploymentLabelChange(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn() @@ -2466,6 +2480,7 @@ func TestMutateStatefulSetLabelChange(t *testing.T) { }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { mutateFn := MutateFuncFor(&tt.existing, &tt.desired) err := mutateFn()