diff --git a/chart/docs/customizing-labels.rst b/chart/docs/customizing-labels.rst new file mode 100644 index 0000000000000..47e06009854d9 --- /dev/null +++ b/chart/docs/customizing-labels.rst @@ -0,0 +1,59 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +Customizing Labels for Pods +--------------------------- + +The Helm chart allows you to customize labels for your Airflow objects. You can set global labels that apply to all objects and pods defined in the chart, as well as component-specific labels for individual Airflow components. + +Global Labels +~~~~~~~~~~~~~ + +Global labels can be set using the ``labels`` parameter in your values file. These labels will be applied to all Airflow objects and pods defined in the chart: + +.. code-block:: yaml + + labels: + environment: production + +Component-Specific Labels +~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can also set specific labels for individual Airflow components, which will be merged with the global labels. Component-specific labels take precedence over global labels, allowing you to override them as needed. + +For example, to add specific labels to different components: + +.. code-block:: yaml + + # Global labels applied to all pods + labels: + environment: production + + # Scheduler specific labels + scheduler: + labels: + role: scheduler + + # Worker specific labels + workers: + labels: + role: worker + + # Webserver specific labels + webserver: + labels: + role: ui diff --git a/chart/docs/index.rst b/chart/docs/index.rst index 68be09bbedfda..9ce59d74779cd 100644 --- a/chart/docs/index.rst +++ b/chart/docs/index.rst @@ -35,6 +35,7 @@ Helm Chart for Apache Airflow keda using-additional-containers customizing-workers + customizing-labels Installing from sources Extending the Chart diff --git a/chart/templates/dag-processor/dag-processor-deployment.yaml b/chart/templates/dag-processor/dag-processor-deployment.yaml index b5490fcfe2c32..f628d94627d50 100644 --- a/chart/templates/dag-processor/dag-processor-deployment.yaml +++ b/chart/templates/dag-processor/dag-processor-deployment.yaml @@ -71,8 +71,8 @@ spec: tier: airflow component: dag-processor release: {{ .Release.Name }} - {{- with .Values.labels }} - {{- toYaml . | nindent 8 }} + {{- if or .Values.labels .Values.dagProcessor.labels }} + {{- mustMerge .Values.dagProcessor.labels .Values.labels | toYaml | nindent 8 }} {{- end }} annotations: checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} diff --git a/chart/templates/dag-processor/dag-processor-serviceaccount.yaml b/chart/templates/dag-processor/dag-processor-serviceaccount.yaml index 8fdae4abe1f32..acca4a6ec6791 100644 --- a/chart/templates/dag-processor/dag-processor-serviceaccount.yaml +++ b/chart/templates/dag-processor/dag-processor-serviceaccount.yaml @@ -37,8 +37,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.dagProcessor.labels }} + {{- mustMerge .Values.dagProcessor.labels .Values.labels | toYaml | nindent 4 }} {{- end }} {{- with .Values.dagProcessor.serviceAccount.annotations}} annotations: {{- toYaml . | nindent 4 }} diff --git a/chart/templates/redis/redis-networkpolicy.yaml b/chart/templates/redis/redis-networkpolicy.yaml index 6a186a4b6855c..8ae08e01f87a2 100644 --- a/chart/templates/redis/redis-networkpolicy.yaml +++ b/chart/templates/redis/redis-networkpolicy.yaml @@ -31,8 +31,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.redis.labels }} + {{- mustMerge .Values.redis.labels .Values.labels | toYaml | nindent 4 }} {{- end }} spec: podSelector: diff --git a/chart/templates/redis/redis-service.yaml b/chart/templates/redis/redis-service.yaml index 40424a7313e99..3ade825f28d52 100644 --- a/chart/templates/redis/redis-service.yaml +++ b/chart/templates/redis/redis-service.yaml @@ -31,8 +31,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.redis.labels }} + {{- mustMerge .Values.redis.labels .Values.labels | toYaml | nindent 4 }} {{- end }} spec: {{- if eq .Values.redis.service.type "ClusterIP" }} diff --git a/chart/templates/redis/redis-serviceaccount.yaml b/chart/templates/redis/redis-serviceaccount.yaml index 06f33e12f5d38..f645b4ee2f4e1 100644 --- a/chart/templates/redis/redis-serviceaccount.yaml +++ b/chart/templates/redis/redis-serviceaccount.yaml @@ -32,8 +32,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.redis.labels }} + {{- mustMerge .Values.redis.labels .Values.labels | toYaml | nindent 4 }} {{- end }} {{- with .Values.redis.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/chart/templates/redis/redis-statefulset.yaml b/chart/templates/redis/redis-statefulset.yaml index d1e1edef808eb..b8374d81e9d63 100644 --- a/chart/templates/redis/redis-statefulset.yaml +++ b/chart/templates/redis/redis-statefulset.yaml @@ -57,8 +57,8 @@ spec: tier: airflow component: redis release: {{ .Release.Name }} - {{- with .Values.labels }} - {{- toYaml . | nindent 8 }} + {{- if or .Values.labels .Values.redis.labels }} + {{- mustMerge .Values.redis.labels .Values.labels | toYaml | nindent 8 }} {{- end }} {{- if or .Values.redis.safeToEvict .Values.redis.podAnnotations }} annotations: diff --git a/chart/templates/statsd/statsd-deployment.yaml b/chart/templates/statsd/statsd-deployment.yaml index 1eab1fda8b8aa..ecbd1f80f4123 100644 --- a/chart/templates/statsd/statsd-deployment.yaml +++ b/chart/templates/statsd/statsd-deployment.yaml @@ -61,8 +61,8 @@ spec: tier: airflow component: statsd release: {{ .Release.Name }} - {{- with .Values.labels }} - {{- toYaml . | nindent 8 }} + {{- if or .Values.labels .Values.statsd.labels }} + {{- mustMerge .Values.statsd.labels .Values.labels | toYaml | nindent 8 }} {{- end }} {{- if or .Values.statsd.extraMappings .Values.statsd.podAnnotations }} annotations: diff --git a/chart/templates/statsd/statsd-ingress.yaml b/chart/templates/statsd/statsd-ingress.yaml index c01792643c487..d48ec29085a30 100644 --- a/chart/templates/statsd/statsd-ingress.yaml +++ b/chart/templates/statsd/statsd-ingress.yaml @@ -32,8 +32,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.statsd.labels }} + {{- mustMerge .Values.statsd.labels .Values.labels | toYaml | nindent 4 }} {{- end }} {{- with .Values.ingress.statsd.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/chart/templates/statsd/statsd-networkpolicy.yaml b/chart/templates/statsd/statsd-networkpolicy.yaml index 3690cda897155..9d4ccde72db7f 100644 --- a/chart/templates/statsd/statsd-networkpolicy.yaml +++ b/chart/templates/statsd/statsd-networkpolicy.yaml @@ -31,8 +31,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.statsd.labels }} + {{- mustMerge .Values.statsd.labels .Values.labels | toYaml | nindent 4 }} {{- end }} spec: podSelector: diff --git a/chart/templates/statsd/statsd-service.yaml b/chart/templates/statsd/statsd-service.yaml index 2486264c5cb77..c7bee0ea3f414 100644 --- a/chart/templates/statsd/statsd-service.yaml +++ b/chart/templates/statsd/statsd-service.yaml @@ -31,8 +31,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.statsd.labels }} + {{- mustMerge .Values.statsd.labels .Values.labels | toYaml | nindent 4 }} {{- end }} annotations: prometheus.io/scrape: "true" diff --git a/chart/templates/statsd/statsd-serviceaccount.yaml b/chart/templates/statsd/statsd-serviceaccount.yaml index 838cbdd857cac..e2659769516dc 100644 --- a/chart/templates/statsd/statsd-serviceaccount.yaml +++ b/chart/templates/statsd/statsd-serviceaccount.yaml @@ -32,8 +32,8 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- with .Values.labels }} - {{- toYaml . | nindent 4 }} + {{- if or .Values.labels .Values.statsd.labels }} + {{- mustMerge .Values.statsd.labels .Values.labels | toYaml | nindent 4 }} {{- end }} {{- with .Values.statsd.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/chart/values.schema.json b/chart/values.schema.json index d1bc354468e9a..0ed3298631403 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -4192,6 +4192,14 @@ } } }, + "labels": { + "description": "Labels specific to dag processor objects and pods", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, "env": { "description": "Add additional env vars to dag processor.", "type": "array", @@ -7317,6 +7325,14 @@ "--statsd.mapping-config=/etc/statsd-exporter/mappings.yml" ] }, + "labels": { + "description": "Labels specific to statsd objects and pods", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, "env": { "description": "Add additional env vars to statsd container.", "type": "array", @@ -8306,6 +8322,14 @@ } } }, + "labels": { + "description": "Labels to add to the redis objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, "uid": { "description": "Redis run as user parameter.", "type": "integer", diff --git a/chart/values.yaml b/chart/values.yaml index 904c0594c1ae5..0a92348cd56b0 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -2174,6 +2174,10 @@ dagProcessor: securityContexts: container: {} + # Labels specific to dag processor objects + labels: {} + + # Environment variables to add to dag processor container env: [] # Flower settings @@ -2404,6 +2408,10 @@ statsd: overrideMappings: [] podAnnotations: {} + + # Labels specific to statsd objects and pods + labels: {} + # Environment variables to add to statsd container env: [] # PgBouncer settings @@ -2717,6 +2725,9 @@ redis: # container level lifecycle hooks containerLifecycleHooks: {} + # Labels specific to redis objects and pods + labels: {} + podAnnotations: {} # Auth secret for a private registry # This is used if pulling airflow images from a private registry diff --git a/dev/breeze/doc/images/output-commands.svg b/dev/breeze/doc/images/output-commands.svg index 84ee1aa8caeab..d8ec4f40c1d95 100644 --- a/dev/breeze/doc/images/output-commands.svg +++ b/dev/breeze/doc/images/output-commands.svg @@ -345,8 +345,8 @@ localstack | mongo | mssql | openlineage | otel | pinot | qdrant | redis | redis | statsd | tinkerpop | trino | ydb)                                                    ---standalone-dag-processor/--no-standalone-dag-process…Run standalone dag processor for start-airflow          -(required for Airflow 3).                               +--standalone-dag-processor/--no-standalone-dag-processoRun standalone dag processor for start-airflow          +r(required for Airflow 3).                               [default: standalone-dag-processor]                     --auth-managerSpecify the auth manager to set        (>SimpleAuthManager< | FabAuthManager) diff --git a/dev/breeze/doc/images/output_testing_helm-tests.svg b/dev/breeze/doc/images/output_testing_helm-tests.svg index b5532a7ea1560..133234e5d15b1 100644 --- a/dev/breeze/doc/images/output_testing_helm-tests.svg +++ b/dev/breeze/doc/images/output_testing_helm-tests.svg @@ -1,4 +1,4 @@ - + Run Helm chart tests. ╭─ Flags for helms-tests command ──────────────────────────────────────────────────────────────────────────────────────╮ ---test-typeType of helm tests to run                                                     -(All | airflow_aux | airflow_core | apiserver | other | security | webserver) -[default: All]                                                                ---test-timeoutTest timeout in seconds. Set the pytest setup, execution and teardown timeouts to this value -(INTEGER RANGE)                                                                              -[default: 60; x>=0]                                                                          ---use-xdistUse xdist plugin for pytest ---parallelismMaximum number of processes to use while running the operation in parallel.(INTEGER RANGE) -[default: 4; 1<=x<=8]                                                       -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭─ Advanced flag for helm-test command ────────────────────────────────────────────────────────────────────────────────╮ ---github-repository-gGitHub repository used to pull, push run images.(TEXT)[default: apache/airflow] ---mount-sourcesChoose scope of local sources that should be mounted, skipped, or removed (default =        -selected).                                                                                  -(selected | all | skip | remove | tests | providers-and-tests)                              -[default: selected]                                                                         -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ ---verbose-vPrint verbose information about performed steps. ---dry-run-DIf dry-run is set, commands are only printed, not executed. ---help-hShow this message and exit. -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +--test-typeType of helm tests to run                                                                          +(All | airflow_aux | airflow_core | apiserver | dagprocessor | other | redis | security | statsd | +webserver)                                                                                         +[default: All]                                                                                     +--test-timeoutTest timeout in seconds. Set the pytest setup, execution and teardown timeouts to this value +(INTEGER RANGE)                                                                              +[default: 60; x>=0]                                                                          +--use-xdistUse xdist plugin for pytest +--parallelismMaximum number of processes to use while running the operation in parallel.(INTEGER RANGE) +[default: 4; 1<=x<=8]                                                       +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Advanced flag for helm-test command ────────────────────────────────────────────────────────────────────────────────╮ +--github-repository-gGitHub repository used to pull, push run images.(TEXT)[default: apache/airflow] +--mount-sourcesChoose scope of local sources that should be mounted, skipped, or removed (default =        +selected).                                                                                  +(selected | all | skip | remove | tests | providers-and-tests)                              +[default: selected]                                                                         +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Common options ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ +--verbose-vPrint verbose information about performed steps. +--dry-run-DIf dry-run is set, commands are only printed, not executed. +--help-hShow this message and exit. +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/dev/breeze/doc/images/output_testing_helm-tests.txt b/dev/breeze/doc/images/output_testing_helm-tests.txt index 14ca452d17ba6..cfa0314542d30 100644 --- a/dev/breeze/doc/images/output_testing_helm-tests.txt +++ b/dev/breeze/doc/images/output_testing_helm-tests.txt @@ -1 +1 @@ -f67f6341ee5ef1786505b25152a278cc +33c785aec11cf1a774057a69bb8364ba diff --git a/helm-tests/tests/helm_tests/dagprocessor/__init__.py b/helm-tests/tests/helm_tests/dagprocessor/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/helm-tests/tests/helm_tests/dagprocessor/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/helm-tests/tests/helm_tests/dagprocessor/test_labels_deployment.py b/helm-tests/tests/helm_tests/dagprocessor/test_labels_deployment.py new file mode 100644 index 0000000000000..7a044783353b9 --- /dev/null +++ b/helm-tests/tests/helm_tests/dagprocessor/test_labels_deployment.py @@ -0,0 +1,101 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestDagProcessorDeployment: + """Tests dag-processor deployment labels.""" + + AIRFLOW_VERSION = "3.0.0" + TEMPLATE_FILE = "templates/dag-processor/dag-processor-deployment.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.dagProcessor.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "dagProcessor": { + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.dagProcessor.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"test_global_label": "test_global_label_value"}, + "dagProcessor": { + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"common_label": "global_value"}, + "dagProcessor": { + "labels": {"common_label": "component_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert jmespath.search("spec.template.metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/dagprocessor/test_labels_service_account.py b/helm-tests/tests/helm_tests/dagprocessor/test_labels_service_account.py new file mode 100644 index 0000000000000..6f8bb8bf8b4be --- /dev/null +++ b/helm-tests/tests/helm_tests/dagprocessor/test_labels_service_account.py @@ -0,0 +1,95 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestDagProcessorServiceAccount: + """Tests dag-processor service account labels.""" + + AIRFLOW_VERSION = "3.0.0" + TEMPLATE_FILE = "templates/dag-processor/dag-processor-serviceaccount.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.dagProcessor.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "dagProcessor": { + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.dagProcessor.labels.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"test_global_label": "test_global_label_value"}, + "dagProcessor": { + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "airflowVersion": self.AIRFLOW_VERSION, + "labels": {"common_label": "global_value"}, + "dagProcessor": { + "labels": {"common_label": "component_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/redis/__init__.py b/helm-tests/tests/helm_tests/redis/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/helm-tests/tests/helm_tests/redis/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/helm-tests/tests/helm_tests/redis/test_labels_networkpolicy.py b/helm-tests/tests/helm_tests/redis/test_labels_networkpolicy.py new file mode 100644 index 0000000000000..54b324eb495c5 --- /dev/null +++ b/helm-tests/tests/helm_tests/redis/test_labels_networkpolicy.py @@ -0,0 +1,103 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestRedisNetworkPolicy: + """Tests redis network policy labels.""" + + AIRFLOW_EXECUTOR = "CeleryExecutor" + TEMPLATE_FILE = "templates/redis/redis-networkpolicy.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": {"enabled": True}, + "networkPolicies": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "networkPolicies": {"enabled": True}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "networkPolicies": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "networkPolicies": {"enabled": True}, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/redis/test_labels_service.py b/helm-tests/tests/helm_tests/redis/test_labels_service.py new file mode 100644 index 0000000000000..d8f6cd0c46503 --- /dev/null +++ b/helm-tests/tests/helm_tests/redis/test_labels_service.py @@ -0,0 +1,99 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestRedisService: + """Tests redis service labels.""" + + AIRFLOW_EXECUTOR = "CeleryExecutor" + TEMPLATE_FILE = "templates/redis/redis-service.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/redis/test_labels_serviceaccount.py b/helm-tests/tests/helm_tests/redis/test_labels_serviceaccount.py new file mode 100644 index 0000000000000..2c90b3d20be7f --- /dev/null +++ b/helm-tests/tests/helm_tests/redis/test_labels_serviceaccount.py @@ -0,0 +1,105 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestRedisServiceAccount: + """Tests redis service account labels.""" + + AIRFLOW_EXECUTOR = "CeleryExecutor" + TEMPLATE_FILE = "templates/redis/redis-serviceaccount.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "serviceAccount": {"create": True}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "serviceAccount": {"create": True}, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.redis.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "serviceAccount": {"create": True}, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "serviceAccount": {"create": True}, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/redis/test_labels_statefulset.py b/helm-tests/tests/helm_tests/redis/test_labels_statefulset.py new file mode 100644 index 0000000000000..e4e189e2c9fe0 --- /dev/null +++ b/helm-tests/tests/helm_tests/redis/test_labels_statefulset.py @@ -0,0 +1,119 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestRedisStatefulSet: + """Tests redis statefulset labels.""" + + AIRFLOW_EXECUTOR = "CeleryExecutor" + TEMPLATE_FILE = "templates/redis/redis-statefulset.yaml" + + def test_should_add_global_labels_to_metadata(self): + """Test adding only .Values.labels to metadata.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_global_labels_to_pod_template(self): + """Test adding only .Values.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + + def test_should_add_component_specific_labels_to_pod_template(self): + """Test adding only .Values.redis.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels_in_pod_template(self): + """Test adding both .Values.labels and .Values.redis.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "executor": self.AIRFLOW_EXECUTOR, + "redis": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert jmespath.search("spec.template.metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/statsd/__init__.py b/helm-tests/tests/helm_tests/statsd/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_deployment.py b/helm-tests/tests/helm_tests/statsd/test_labels_deployment.py new file mode 100644 index 0000000000000..867facb0fd337 --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/test_labels_deployment.py @@ -0,0 +1,113 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestStatsdDeployment: + """Tests statsd deployment labels.""" + + TEMPLATE_FILE = "templates/statsd/statsd-deployment.yaml" + + def test_should_add_global_labels_to_metadata(self): + """Test adding only .Values.labels to metadata.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_global_labels_to_pod_template(self): + """Test adding only .Values.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + + def test_should_add_component_specific_labels_to_pod_template(self): + """Test adding only .Values.statsd.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels_in_pod_template(self): + """Test adding both .Values.labels and .Values.statsd.labels to spec.template.metadata.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_global_label"] + == "test_global_label_value" + ) + assert "test_component_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert ( + jmespath.search("spec.template.metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("spec.template.metadata.labels", docs[0]) + assert jmespath.search("spec.template.metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_ingress.py b/helm-tests/tests/helm_tests/statsd/test_labels_ingress.py new file mode 100644 index 0000000000000..fb7c72365fe22 --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/test_labels_ingress.py @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestStatsdIngress: + """Tests statsd ingress labels.""" + + TEMPLATE_FILE = "templates/statsd/statsd-ingress.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "ingress": {"statsd": {"enabled": True}}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "ingress": {"statsd": {"enabled": True}}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "ingress": {"statsd": {"enabled": True}}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "ingress": {"statsd": {"enabled": True}}, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_networkpolicy.py b/helm-tests/tests/helm_tests/statsd/test_labels_networkpolicy.py new file mode 100644 index 0000000000000..0fbf3bb680b28 --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/test_labels_networkpolicy.py @@ -0,0 +1,98 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestStatsdNetworkPolicy: + """Tests statsd network policy labels.""" + + TEMPLATE_FILE = "templates/statsd/statsd-networkpolicy.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "networkPolicies": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "networkPolicies": {"enabled": True}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "networkPolicies": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "networkPolicies": {"enabled": True}, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_service.py b/helm-tests/tests/helm_tests/statsd/test_labels_service.py new file mode 100644 index 0000000000000..73ff5b49912df --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/test_labels_service.py @@ -0,0 +1,94 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestStatsdService: + """Tests statsd service labels.""" + + TEMPLATE_FILE = "templates/statsd/statsd-service.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value" diff --git a/helm-tests/tests/helm_tests/statsd/test_labels_serviceaccount.py b/helm-tests/tests/helm_tests/statsd/test_labels_serviceaccount.py new file mode 100644 index 0000000000000..73ff5b49912df --- /dev/null +++ b/helm-tests/tests/helm_tests/statsd/test_labels_serviceaccount.py @@ -0,0 +1,94 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import jmespath +from chart_utils.helm_template_generator import render_chart + + +class TestStatsdService: + """Tests statsd service labels.""" + + TEMPLATE_FILE = "templates/statsd/statsd-service.yaml" + + def test_should_add_global_labels(self): + """Test adding only .Values.labels.""" + docs = render_chart( + values={ + "statsd": {"enabled": True}, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + + def test_should_add_component_specific_labels(self): + """Test adding only .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_should_merge_global_and_component_specific_labels(self): + """Test adding both .Values.labels and .Values.statsd.labels.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"test_component_label": "test_component_label_value"}, + }, + "labels": {"test_global_label": "test_global_label_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "test_global_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["test_global_label"] == "test_global_label_value" + assert "test_component_label" in jmespath.search("metadata.labels", docs[0]) + assert ( + jmespath.search("metadata.labels", docs[0])["test_component_label"] + == "test_component_label_value" + ) + + def test_component_specific_labels_should_override_global_labels(self): + """Test that component-specific labels take precedence over global labels with the same key.""" + docs = render_chart( + values={ + "statsd": { + "enabled": True, + "labels": {"common_label": "component_value"}, + }, + "labels": {"common_label": "global_value"}, + }, + show_only=[self.TEMPLATE_FILE], + ) + + assert "common_label" in jmespath.search("metadata.labels", docs[0]) + assert jmespath.search("metadata.labels", docs[0])["common_label"] == "component_value"