You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by po...@apache.org on 2020/11/15 02:52:03 UTC

[airflow] 20/32: Add Flower Authentication to Helm Chart (#11836)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch v1-10-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit a01bd324b11382f87f61c3ae1b96bdcc700c7f89
Author: Songkran Nethan <ka...@gmail.com>
AuthorDate: Sun Nov 1 00:37:45 2020 +0700

    Add Flower Authentication to Helm Chart (#11836)
    
    (cherry picked from commit 644ac1b06019bcd1c1c540373051c31b766efccf)
---
 chart/templates/_helpers.yaml                 |  4 ++
 chart/templates/flower/flower-deployment.yaml | 29 +++++++++---
 chart/templates/secrets/flower-secret.yaml    | 36 ++++++++++++++
 chart/tests/test_flower_authorization.py      | 68 +++++++++++++++++++++++++++
 chart/values.schema.json                      | 21 +++++++++
 chart/values.yaml                             |  7 +++
 6 files changed, 159 insertions(+), 6 deletions(-)

diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml
index beb26a7..9914127 100644
--- a/chart/templates/_helpers.yaml
+++ b/chart/templates/_helpers.yaml
@@ -252,6 +252,10 @@
 {{ default (printf "%s-elasticsearch" .Release.Name) .Values.elasticsearch.secretName }}
 {{- end }}
 
+{{ define "flower_secret" -}}
+{{ default (printf "%s-flower" .Release.Name) .Values.flower.secretName }}
+{{- end }}
+
 {{ define "kerberos_keytab_secret" -}}
 {{ .Release.Name }}-kerberos-keytab
 {{- end }}
diff --git a/chart/templates/flower/flower-deployment.yaml b/chart/templates/flower/flower-deployment.yaml
index 887b70d..c5d1f91 100644
--- a/chart/templates/flower/flower-deployment.yaml
+++ b/chart/templates/flower/flower-deployment.yaml
@@ -81,19 +81,36 @@ spec:
               containerPort: {{ .Values.ports.flowerUI }}
           livenessProbe:
             failureThreshold: 10
-            httpGet:
-              path: /
-              port: {{ .Values.ports.flowerUI }}
+            exec:
+              command:
+                - curl
+                {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}}
+                - "--user"
+                - $AIRFLOW__CELERY__FLOWER_BASIC_AUTH
+                {{- end }}
+                - {{ printf "localhost:%s" (.Values.ports.flowerUI | toString) }}
             initialDelaySeconds: 10
             periodSeconds: 5
           readinessProbe:
             failureThreshold: 10
-            httpGet:
-              path: /
-              port: {{ .Values.ports.flowerUI }}
+            exec:
+              command:
+                - curl
+                {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}}
+                - "--user"
+                - $AIRFLOW__CELERY__FLOWER_BASIC_AUTH
+                {{- end }}
+                - {{ printf "localhost:%s" (.Values.ports.flowerUI | toString) }}
             initialDelaySeconds: 10
             periodSeconds: 5
           env:
+            {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}}
+            - name: AIRFLOW__CELERY__FLOWER_BASIC_AUTH
+              valueFrom:
+                secretKeyRef:
+                  name: {{ template "flower_secret" . }}
+                  key: basicAuth
+            {{- end }}
           {{- include "standard_airflow_environment" . | indent 10 }}
       volumes:
         - name: config
diff --git a/chart/templates/secrets/flower-secret.yaml b/chart/templates/secrets/flower-secret.yaml
new file mode 100644
index 0000000..c88734d
--- /dev/null
+++ b/chart/templates/secrets/flower-secret.yaml
@@ -0,0 +1,36 @@
+# 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.
+
+################################
+## Flower Secret
+#################################
+{{- if (and (not .Values.flower.secretName) .Values.flower.username .Values.flower.password) }}
+kind: Secret
+apiVersion: v1
+metadata:
+  name: {{ .Release.Name }}-flower
+  labels:
+    release: {{ .Release.Name }}
+    chart: {{ .Chart.Name }}
+    heritage: {{ .Release.Service }}
+{{- with .Values.labels }}
+{{ toYaml . | indent 4 }}
+{{- end }}
+type: Opaque
+data:
+  basicAuth: {{ (printf "%s:%s" .Values.flower.username .Values.flower.password) | b64enc | quote }}
+{{- end }}
diff --git a/chart/tests/test_flower_authorization.py b/chart/tests/test_flower_authorization.py
new file mode 100644
index 0000000..f0cc5b0
--- /dev/null
+++ b/chart/tests/test_flower_authorization.py
@@ -0,0 +1,68 @@
+# 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
+
+import jmespath
+from tests.helm_template_generator import render_chart
+
+
+class FlowerAuthorizationTest(unittest.TestCase):
+    def test_should_create_flower_deployment_with_authorization(self):
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "flower": {"username": "flower", "password": "fl0w3r"},
+                "ports": {"flowerUI": 7777},
+            },
+            show_only=["templates/flower/flower-deployment.yaml"],
+        )
+
+        self.assertEqual(
+            "AIRFLOW__CELERY__FLOWER_BASIC_AUTH",
+            jmespath.search("spec.template.spec.containers[0].env[0].name", docs[0]),
+        )
+        self.assertEqual(
+            ['curl', '--user', '$AIRFLOW__CELERY__FLOWER_BASIC_AUTH', 'localhost:7777'],
+            jmespath.search("spec.template.spec.containers[0].livenessProbe.exec.command", docs[0]),
+        )
+        self.assertEqual(
+            ['curl', '--user', '$AIRFLOW__CELERY__FLOWER_BASIC_AUTH', 'localhost:7777'],
+            jmespath.search("spec.template.spec.containers[0].readinessProbe.exec.command", docs[0]),
+        )
+
+    def test_should_create_flower_deployment_without_authorization(self):
+        docs = render_chart(
+            values={
+                "executor": "CeleryExecutor",
+                "ports": {"flowerUI": 7777},
+            },
+            show_only=["templates/flower/flower-deployment.yaml"],
+        )
+
+        self.assertEqual(
+            "AIRFLOW__CORE__FERNET_KEY",
+            jmespath.search("spec.template.spec.containers[0].env[0].name", docs[0]),
+        )
+        self.assertEqual(
+            ['curl', 'localhost:7777'],
+            jmespath.search("spec.template.spec.containers[0].livenessProbe.exec.command", docs[0]),
+        )
+        self.assertEqual(
+            ['curl', 'localhost:7777'],
+            jmespath.search("spec.template.spec.containers[0].readinessProbe.exec.command", docs[0]),
+        )
diff --git a/chart/values.schema.json b/chart/values.schema.json
index 2f25892..7881c82 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -784,6 +784,27 @@
                 "resources": {
                     "type": "object"
                 },
+                "secretName": {
+                    "description": "A secret containing the user and password pair.",
+                    "type": [
+                        "string",
+                        "null"
+                    ]
+                },
+                "username": {
+                    "description": "Username use to access flower.",
+                    "type": [
+                        "string",
+                        "null"
+                    ]
+                },
+                "password": {
+                    "description": "Password use to access flower.",
+                    "type": [
+                        "string",
+                        "null"
+                    ]
+                },
                 "service": {
                     "description": "Flower service configuration.",
                     "type": "object",
diff --git a/chart/values.yaml b/chart/values.yaml
index 4855214..1e3b81f 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -409,6 +409,13 @@ flower:
   #     cpu: 100m
   #     memory: 128Mi
 
+  # A secret containing the connection
+  secretName: ~
+
+  # Else, if username and password are set, create secret from username and password
+  username: ~
+  password: ~
+
   service:
     type: ClusterIP