diff --git a/chart/UPDATING.rst b/chart/UPDATING.rst index e5ea207429181..e98786976ca86 100644 --- a/chart/UPDATING.rst +++ b/chart/UPDATING.rst @@ -43,6 +43,16 @@ Default Airflow version is updated to ``2.1.2`` The default Airflow version that is installed with the Chart is now ``2.1.3``, previously it was ``2.1.2``. +Removed ``ingress.flower.precedingPaths`` and ``ingress.flower.succeedingPaths`` parameters +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``ingress.flower.precedingPaths`` and ``ingress.flower.succeedingPaths`` parameters have been removed as they had previously had no effect on rendered YAML output. + +Change of default ``path`` on Ingress +""""""""""""""""""""""""""""""""""" + +With the move to support the stable Kubernetes Ingress API the default path has been changed from being unset to ``/``. For most Ingress controllers this should not change the behavior of the resulting Ingress resource. + Airflow Helm Chart 1.1.0 ------------------------ diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index e52471f64d978..3887d0a24a13c 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -592,3 +592,13 @@ Create the name of the cleanup service account to use {{- $_ := set $config "auths" $auth -}} {{ $config | toJson | print }} {{- end }} + +{{/* Allow Kubernetes Version to be overridden. Credit to https://github.com/prometheus-community/helm-charts for Regex. */}} +{{- define "kubeVersion" -}} + {{- $kubeVersion := default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} + {{/* Special use case for Amazon EKS, Google GKE */}} + {{- if and (regexMatch "\\d+\\.\\d+\\.\\d+-(?:eks|gke).+" $kubeVersion) (not .Values.kubeVersionOverride) -}} + {{- $kubeVersion = regexFind "\\d+\\.\\d+\\.\\d+" $kubeVersion -}} + {{- end -}} + {{- $kubeVersion -}} +{{- end -}} diff --git a/chart/templates/cleanup/cleanup-cronjob.yaml b/chart/templates/cleanup/cleanup-cronjob.yaml index 4605dc7055e52..d3b8f93be3de6 100644 --- a/chart/templates/cleanup/cleanup-cronjob.yaml +++ b/chart/templates/cleanup/cleanup-cronjob.yaml @@ -22,7 +22,11 @@ {{- $nodeSelector := or .Values.cleanup.nodeSelector .Values.nodeSelector }} {{- $affinity := or .Values.cleanup.affinity .Values.affinity }} {{- $tolerations := or .Values.cleanup.tolerations .Values.tolerations }} +{{- if semverCompare ">= 1.21.x" (include "kubeVersion" .) }} +apiVersion: batch/v1 +{{- else }} apiVersion: batch/v1beta1 +{{- end }} kind: CronJob metadata: name: {{ .Release.Name }}-cleanup diff --git a/chart/templates/flower/flower-ingress.yaml b/chart/templates/flower/flower-ingress.yaml index 754494cf6b8a4..ad3b1d0429e70 100644 --- a/chart/templates/flower/flower-ingress.yaml +++ b/chart/templates/flower/flower-ingress.yaml @@ -20,7 +20,12 @@ ################################# {{- if .Values.flower.enabled }} {{- if and .Values.ingress.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +{{- $apiIsStable := semverCompare ">= 1.19.x" (include "kubeVersion" .) -}} +{{- if $apiIsStable }} +apiVersion: networking.k8s.io/v1 +{{- else }} apiVersion: networking.k8s.io/v1beta1 +{{- end }} kind: Ingress metadata: name: {{ .Release.Name }}-flower-ingress @@ -30,8 +35,9 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} - {{- if .Values.ingress.flower.annotations }} - annotations: {{ toYaml .Values.ingress.flower.annotations | nindent 4 }} + {{- with .Values.ingress.flower.annotations }} + annotations: + {{- toYaml . | nindent 4 }} {{- end }} spec: {{- if .Values.ingress.flower.tls.enabled }} @@ -44,13 +50,26 @@ spec: - http: paths: - backend: + {{- if $apiIsStable }} + service: + name: {{ .Release.Name }}-flower + port: + name: flower-ui + {{- else }} serviceName: {{ .Release.Name }}-flower servicePort: flower-ui + {{- end }} {{- if .Values.ingress.flower.path }} path: {{ .Values.ingress.flower.path }} + {{- if $apiIsStable }} + pathType: {{ .Values.ingress.flower.pathType }} + {{- end }} {{- end }} {{- if .Values.ingress.flower.host }} host: {{ .Values.ingress.flower.host }} {{- end }} + {{- if and .Values.ingress.flower.ingressClassName $apiIsStable }} + ingressClassName: {{ .Values.ingress.flower.ingressClassName }} + {{- end }} {{- end }} {{- end }} diff --git a/chart/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml b/chart/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml index 37c64c27f8afb..41999da145b51 100644 --- a/chart/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml +++ b/chart/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml @@ -20,7 +20,11 @@ ################################# {{- if and .Values.pgbouncer.enabled .Values.pgbouncer.podDisruptionBudget.enabled }} kind: PodDisruptionBudget +{{- if semverCompare ">= 1.21.x" (include "kubeVersion" .) }} +apiVersion: policy/v1 +{{- else }} apiVersion: policy/v1beta1 +{{- end }} metadata: name: {{ .Release.Name }}-pgbouncer-pdb labels: diff --git a/chart/templates/scheduler/scheduler-poddisruptionbudget.yaml b/chart/templates/scheduler/scheduler-poddisruptionbudget.yaml index 967c2cf041ce9..24a627f270e25 100644 --- a/chart/templates/scheduler/scheduler-poddisruptionbudget.yaml +++ b/chart/templates/scheduler/scheduler-poddisruptionbudget.yaml @@ -20,7 +20,11 @@ ################################# {{- if .Values.scheduler.podDisruptionBudget.enabled }} kind: PodDisruptionBudget +{{- if semverCompare ">= 1.21.x" (include "kubeVersion" .) }} +apiVersion: policy/v1 +{{- else }} apiVersion: policy/v1beta1 +{{- end }} metadata: name: {{ .Release.Name }}-scheduler-pdb labels: diff --git a/chart/templates/webserver/webserver-ingress.yaml b/chart/templates/webserver/webserver-ingress.yaml index 361ba8151dfed..fb46e18efc615 100644 --- a/chart/templates/webserver/webserver-ingress.yaml +++ b/chart/templates/webserver/webserver-ingress.yaml @@ -19,7 +19,12 @@ ## Airflow Webserver Ingress ################################# {{- if .Values.ingress.enabled }} +{{- $apiIsStable := semverCompare ">= 1.19.x" (include "kubeVersion" .) -}} +{{- if $apiIsStable }} +apiVersion: networking.k8s.io/v1 +{{- else }} apiVersion: networking.k8s.io/v1beta1 +{{- end }} kind: Ingress metadata: name: {{ .Release.Name }}-airflow-ingress @@ -29,12 +34,10 @@ metadata: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" heritage: {{ .Release.Service }} -{{- if .Values.ingress.web.annotations }} + {{- with .Values.ingress.web.annotations }} annotations: -{{- with .Values.ingress.web.annotations }} -{{ toYaml . | indent 4 }} -{{- end }} -{{- end}} + {{- toYaml . | nindent 4 }} + {{- end }} spec: {{- if .Values.ingress.web.tls.enabled }} tls: @@ -47,23 +50,56 @@ spec: paths: {{- range .Values.ingress.web.precedingPaths }} - path: {{ .path }} + {{- if $apiIsStable }} + pathType: {{ .pathType }} + {{- end }} backend: + {{- if $apiIsStable }} + service: + name: {{ .serviceName }} + port: + name: {{ .servicePort }} + {{- else }} serviceName: {{ .serviceName }} servicePort: {{ .servicePort }} + {{- end }} {{- end }} - backend: + {{- if $apiIsStable }} + service: + name: {{ .Release.Name }}-webserver + port: + name: airflow-ui + {{- else }} serviceName: {{ .Release.Name }}-webserver servicePort: airflow-ui -{{- if .Values.ingress.web.path }} + {{- end }} + {{- if .Values.ingress.web.path }} path: {{ .Values.ingress.web.path }} -{{- end }} + {{- if $apiIsStable }} + pathType: {{ .Values.ingress.web.pathType }} + {{- end }} + {{- end }} {{- range .Values.ingress.web.succeedingPaths }} - path: {{ .path }} + {{- if $apiIsStable }} + pathType: {{ .pathType }} + {{- end }} backend: + {{- if $apiIsStable }} + service: + name: {{ .serviceName }} + port: + name: {{ .servicePort }} + {{- else }} serviceName: {{ .serviceName }} servicePort: {{ .servicePort }} + {{- end }} {{- end }} -{{- if .Values.ingress.web.host }} + {{- if .Values.ingress.web.host }} host: {{ .Values.ingress.web.host }} -{{- end }} + {{- end }} + {{- if and .Values.ingress.web.ingressClassName $apiIsStable }} + ingressClassName: {{ .Values.ingress.web.ingressClassName }} + {{- end }} {{- end }} diff --git a/chart/tests/helm_template_generator.py b/chart/tests/helm_template_generator.py index 594d3385b2932..8c9aff53ea1ce 100644 --- a/chart/tests/helm_template_generator.py +++ b/chart/tests/helm_template_generator.py @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. +import json import subprocess import sys from functools import lru_cache @@ -30,26 +31,31 @@ api_client = ApiClient() -BASE_URL_SPEC = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.15.0" +BASE_URL_SPEC = "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v" +DEFAULT_KUBERNETES_VERSION = "1.22.0" crd_lookup = { 'keda.sh/v1alpha1::ScaledObject': 'https://raw.githubusercontent.com/kedacore/keda/v2.0.0/config/crd/bases/keda.sh_scaledobjects.yaml', # noqa: E501 } -def get_schema_k8s(api_version, kind): +def get_schema_k8s(api_version, kind, kubernetes_version): api_version = api_version.lower() kind = kind.lower() if '/' in api_version: ext, _, api_version = api_version.partition("/") ext = ext.split(".")[0] - url = f'{BASE_URL_SPEC}/{kind}-{ext}-{api_version}.json' + url = f'{BASE_URL_SPEC}{kubernetes_version}/{kind}-{ext}-{api_version}.json' else: - url = f'{BASE_URL_SPEC}/{kind}-{api_version}.json' + url = f'{BASE_URL_SPEC}{kubernetes_version}/{kind}-{api_version}.json' request = requests.get(url) request.raise_for_status() - schema = request.json() + schema = json.loads( + request.text.replace( + 'kubernetesjsonschema.dev', 'raw.githubusercontent.com/yannh/kubernetes-json-schema/master' + ) + ) return schema @@ -64,16 +70,16 @@ def get_schema_crd(api_version, kind): @lru_cache(maxsize=None) -def create_validator(api_version, kind): +def create_validator(api_version, kind, kubernetes_version): schema = get_schema_crd(api_version, kind) if not schema: - schema = get_schema_k8s(api_version, kind) + schema = get_schema_k8s(api_version, kind, kubernetes_version) jsonschema.Draft7Validator.check_schema(schema) validator = jsonschema.Draft7Validator(schema) return validator -def validate_k8s_object(instance): +def validate_k8s_object(instance, kubernetes_version): # Skip PostgresSQL chart labels = jmespath.search("metadata.labels", instance) if "helm.sh/chart" in labels: @@ -84,11 +90,17 @@ def validate_k8s_object(instance): if chart and 'postgresql' in chart: return - validate = create_validator(instance.get("apiVersion"), instance.get("kind")) + validate = create_validator(instance.get("apiVersion"), instance.get("kind"), kubernetes_version) validate.validate(instance) -def render_chart(name="RELEASE-NAME", values=None, show_only=None, chart_dir=None): +def render_chart( + name="RELEASE-NAME", + values=None, + show_only=None, + chart_dir=None, + kubernetes_version=DEFAULT_KUBERNETES_VERSION, +): """ Function that renders a helm chart into dictionaries. For helm chart testing only """ @@ -98,7 +110,16 @@ def render_chart(name="RELEASE-NAME", values=None, show_only=None, chart_dir=Non content = yaml.dump(values) tmp_file.write(content.encode()) tmp_file.flush() - command = ["helm", "template", name, chart_dir, '--values', tmp_file.name] + command = [ + "helm", + "template", + name, + chart_dir, + '--values', + tmp_file.name, + '--kube-version', + kubernetes_version, + ] if show_only: for i in show_only: command.extend(["--show-only", i]) @@ -106,7 +127,7 @@ def render_chart(name="RELEASE-NAME", values=None, show_only=None, chart_dir=Non k8s_objects = yaml.full_load_all(templates) k8s_objects = [k8s_object for k8s_object in k8s_objects if k8s_object] # type: ignore for k8s_object in k8s_objects: - validate_k8s_object(k8s_object) + validate_k8s_object(k8s_object, kubernetes_version) return k8s_objects diff --git a/chart/tests/test_cleanup_pods.py b/chart/tests/test_cleanup_pods.py index 018faa27e004a..e91eb6fcd5afd 100644 --- a/chart/tests/test_cleanup_pods.py +++ b/chart/tests/test_cleanup_pods.py @@ -48,6 +48,13 @@ def test_should_create_cronjob_for_enabled_cleanup(self): "readOnly": True, } in jmespath.search("spec.jobTemplate.spec.template.spec.containers[0].volumeMounts", docs[0]) + def test_should_pass_validation_with_v1beta1_api(self): + render_chart( + values={"cleanup": {"enabled": True}}, + show_only=["templates/cleanup/cleanup-cronjob.yaml"], + kubernetes_version='1.16.0', + ) # checks that no validation exception is raised + def test_should_change_image_when_set_airflow_image(self): docs = render_chart( values={ diff --git a/chart/tests/test_ingress_flower.py b/chart/tests/test_ingress_flower.py index 7b8d6c9da8c2e..58c4659b01563 100644 --- a/chart/tests/test_ingress_flower.py +++ b/chart/tests/test_ingress_flower.py @@ -23,12 +23,19 @@ class IngressFlowerTest(unittest.TestCase): - def test_should_pass_validation_with_just_ingress_enabled(self): + def test_should_pass_validation_with_just_ingress_enabled_v1(self): render_chart( values={"ingress": {"enabled": True}, "executor": "CeleryExecutor"}, show_only=["templates/flower/flower-ingress.yaml"], ) # checks that no validation exception is raised + def test_should_pass_validation_with_just_ingress_enabled_v1beta1(self): + render_chart( + values={"ingress": {"enabled": True}, "executor": "CeleryExecutor"}, + show_only=["templates/flower/flower-ingress.yaml"], + kubernetes_version='1.16.0', + ) # checks that no validation exception is raised + def test_should_allow_more_than_one_annotation(self): docs = render_chart( values={ @@ -38,3 +45,13 @@ def test_should_allow_more_than_one_annotation(self): show_only=["templates/flower/flower-ingress.yaml"], ) assert jmespath.search("metadata.annotations", docs[0]) == {"aa": "bb", "cc": "dd"} + + def test_should_set_ingress_class_name(self): + docs = render_chart( + values={ + "ingress": {"enabled": True, "flower": {"ingressClassName": "foo"}}, + "executor": "CeleryExecutor", + }, + show_only=["templates/flower/flower-ingress.yaml"], + ) + assert "foo" == jmespath.search("spec.ingressClassName", docs[0]) diff --git a/chart/tests/test_ingress_web.py b/chart/tests/test_ingress_web.py index 6d64b8b4b09ab..7b8590cd01fe8 100644 --- a/chart/tests/test_ingress_web.py +++ b/chart/tests/test_ingress_web.py @@ -23,15 +23,29 @@ class IngressWebTest(unittest.TestCase): - def test_should_pass_validation_with_just_ingress_enabled(self): + def test_should_pass_validation_with_just_ingress_enabled_v1(self): render_chart( values={"ingress": {"enabled": True}}, show_only=["templates/webserver/webserver-ingress.yaml"], ) # checks that no validation exception is raised + def test_should_pass_validation_with_just_ingress_enabled_v1beta1(self): + render_chart( + values={"ingress": {"enabled": True}}, + show_only=["templates/webserver/webserver-ingress.yaml"], + kubernetes_version='1.16.0', + ) # checks that no validation exception is raised + def test_should_allow_more_than_one_annotation(self): docs = render_chart( values={"ingress": {"enabled": True, "web": {"annotations": {"aa": "bb", "cc": "dd"}}}}, show_only=["templates/webserver/webserver-ingress.yaml"], ) assert {"aa": "bb", "cc": "dd"} == jmespath.search("metadata.annotations", docs[0]) + + def test_should_set_ingress_class_name(self): + docs = render_chart( + values={"ingress": {"enabled": True, "web": {"ingressClassName": "foo"}}}, + show_only=["templates/webserver/webserver-ingress.yaml"], + ) + assert "foo" == jmespath.search("spec.ingressClassName", docs[0]) diff --git a/chart/tests/test_pdb_pgbouncer.py b/chart/tests/test_pdb_pgbouncer.py new file mode 100644 index 0000000000000..ae1afa450c070 --- /dev/null +++ b/chart/tests/test_pdb_pgbouncer.py @@ -0,0 +1,35 @@ +# 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. + +import unittest + +from tests.helm_template_generator import render_chart + + +class PgbouncerPdbTest(unittest.TestCase): + def test_should_pass_validation_with_just_pdb_enabled_v1(self): + render_chart( + values={"pgbouncer": {"enabled": True, "podDisruptionBudget": {"enabled": True}}}, + show_only=["templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml"], + ) # checks that no validation exception is raised + + def test_should_pass_validation_with_just_pdb_enabled_v1beta1(self): + render_chart( + values={"pgbouncer": {"enabled": True, "podDisruptionBudget": {"enabled": True}}}, + show_only=["templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml"], + kubernetes_version='1.16.0', + ) # checks that no validation exception is raised diff --git a/chart/tests/test_pdb_scheduler.py b/chart/tests/test_pdb_scheduler.py new file mode 100644 index 0000000000000..2f4e173c423fd --- /dev/null +++ b/chart/tests/test_pdb_scheduler.py @@ -0,0 +1,35 @@ +# 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. + +import unittest + +from tests.helm_template_generator import render_chart + + +class SchedulerPdbTest(unittest.TestCase): + def test_should_pass_validation_with_just_pdb_enabled_v1(self): + render_chart( + values={"scheduler": {"podDisruptionBudget": {"enabled": True}}}, + show_only=["templates/scheduler/scheduler-poddisruptionbudget.yaml"], + ) # checks that no validation exception is raised + + def test_should_pass_validation_with_just_pdb_enabled_v1beta1(self): + render_chart( + values={"scheduler": {"podDisruptionBudget": {"enabled": True}}}, + show_only=["templates/scheduler/scheduler-poddisruptionbudget.yaml"], + kubernetes_version='1.16.0', + ) # checks that no validation exception is raised diff --git a/chart/values.schema.json b/chart/values.schema.json index a76947e291839..074c0caf95a18 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -34,6 +34,12 @@ "default": "", "x-docsSection": null }, + "kubeVersionOverride": { + "description": "Provide a Kubernetes version (used for API Version selection) to override the auto-detected version", + "type": "string", + "default": "", + "x-docsSection": null + }, "uid": { "description": "User of airflow user.", "type": "integer", @@ -123,13 +129,23 @@ "path": { "description": "The path for the web Ingress.", "type": "string", - "default": "" + "default": "/" + }, + "pathType": { + "description": "The pathType for the web Ingress (required for Kubernetes 1.19 and above).", + "type": "string", + "default": "ImplementationSpecific" }, "host": { "description": "The hostname for the web Ingress.", "type": "string", "default": "" }, + "ingressClassName": { + "description": "The Ingress Class for the web Ingress.", + "type": "string", + "default": "" + }, "tls": { "description": "Configuration for web Ingress TLS.", "type": "object", @@ -172,13 +188,23 @@ "path": { "description": "The path for the flower Ingress.", "type": "string", - "default": "" + "default": "/" + }, + "pathType": { + "description": "The pathType for the flower Ingress (required for Kubernetes 1.19 and above).", + "type": "string", + "default": "ImplementationSpecific" }, "host": { "description": "The hostname for the flower Ingress.", "type": "string", "default": "" }, + "ingressClassName": { + "description": "The Ingress Class for the flower Ingress.", + "type": "string", + "default": "" + }, "tls": { "description": "Configuration for flower Ingress TLS.", "type": "object", @@ -195,16 +221,6 @@ "default": "" } } - }, - "precedingPaths": { - "description": "HTTP paths to add to the flower Ingress before the default path.", - "type": "array", - "default": [] - }, - "succeedingPaths": { - "description": "HTTP paths to add to the flower Ingress after the default path.", - "type": "array", - "default": [] } } } diff --git a/chart/values.yaml b/chart/values.yaml index efc5db6af8930..cc3c9ce544683 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -25,6 +25,9 @@ fullnameOverride: "" # Provide a name to substitute for the name of the chart nameOverride: "" +# Provide a Kubernetes version (used for API Version selection) to override the auto-detected version +kubeVersionOverride: "" + # User and group of airflow user uid: 50000 gid: 0 @@ -96,11 +99,17 @@ ingress: annotations: {} # The path for the web Ingress - path: "" + path: "/" + + # The pathType for the above path (used only with Kubernetes v1.19 and above) + pathType: "ImplementationSpecific" # The hostname for the web Ingress host: "" + # The Ingress Class for the web Ingress (used only with Kubernetes v1.19 and above) + ingressClassName: "" + # configs for web Ingress TLS tls: # Enable TLS termination for the web Ingress @@ -120,11 +129,17 @@ ingress: annotations: {} # The path for the flower Ingress - path: "" + path: "/" + + # The pathType for the above path (used only with Kubernetes v1.19 and above) + pathType: "ImplementationSpecific" # The hostname for the flower Ingress host: "" + # The Ingress Class for the flower Ingress (used only with Kubernetes v1.19 and above) + ingressClassName: "" + # configs for web Ingress TLS tls: # Enable TLS termination for the flower Ingress @@ -132,12 +147,6 @@ ingress: # the name of a pre-created Secret containing a TLS private key and certificate secretName: "" - # HTTP paths to add to the flower Ingress before the default path - precedingPaths: [] - - # Http paths to add to the flower Ingress after the default path - succeedingPaths: [] - # Network policy configuration networkPolicies: # Enabled network policies