From e066274b8bff385ffccaa47a2349d15582a7855c Mon Sep 17 00:00:00 2001
From: Prateek Dodda <prateek.reddy.dodda@att.com>
Date: Thu, 16 Apr 2020 05:37:03 -0500
Subject: [PATCH] Implement Security Context for Airflow_Scheduler

This adds the container security context to set readOnlyRootFilesystem
to true

Change-Id: Ia9cad50decfcf9638e8fc1cf5d652ee72d978a40
---
 .../templates/configmap-airflow-usr.yaml      | 25 ++++++++++++++++++
 .../deployment-airflow-scheduler.yaml         | 10 +++++++
 .../templates/statefulset-airflow-worker.yaml | 26 +++++++++++++++----
 charts/shipyard/values.yaml                   | 13 ++++++++++
 4 files changed, 69 insertions(+), 5 deletions(-)
 create mode 100644 charts/shipyard/templates/configmap-airflow-usr.yaml

diff --git a/charts/shipyard/templates/configmap-airflow-usr.yaml b/charts/shipyard/templates/configmap-airflow-usr.yaml
new file mode 100644
index 00000000..584bc11c
--- /dev/null
+++ b/charts/shipyard/templates/configmap-airflow-usr.yaml
@@ -0,0 +1,25 @@
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+#
+# Licensed 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.
+
+{{- if .Values.manifests.configmap_airflow_usr }}
+{{- $envAll := . }}
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: airflow-usr
+data:
+  unittests.cfg: |+
+{{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.airflow | indent 4 }}
+{{- end }}
diff --git a/charts/shipyard/templates/deployment-airflow-scheduler.yaml b/charts/shipyard/templates/deployment-airflow-scheduler.yaml
index 9cbd9694..9de44a6b 100644
--- a/charts/shipyard/templates/deployment-airflow-scheduler.yaml
+++ b/charts/shipyard/templates/deployment-airflow-scheduler.yaml
@@ -53,6 +53,7 @@ spec:
     spec:
       serviceAccountName: {{ $serviceAccountName }}
       affinity:
+{{ dict "envAll" $envAll "application" "airflow_scheduler" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
 {{ tuple $envAll "airflow" "scheduler" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
       nodeSelector:
         {{ .Values.labels.airflow.node_selector_key }}: {{ .Values.labels.airflow.node_selector_value }}
@@ -65,6 +66,7 @@ spec:
           image: {{ .Values.images.tags.airflow }}
           imagePullPolicy: {{ .Values.images.pull_policy }}
 {{ tuple $envAll $envAll.Values.pod.resources.airflow.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+{{ dict "envAll" $envAll "application" "airflow_scheduler" "container" "airflow_scheduler" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
           env:
           - name: AIRFLOW_CONN_AIRFLOWS_OWN_DB
             valueFrom:
@@ -78,6 +80,10 @@ spec:
               mountPath: {{ .Values.conf.airflow_config_file.path }}
               subPath: airflow.cfg
               readOnly: true
+            - name: airflow-usr
+              mountPath: {{ .Values.conf.airflow_unittests_file.path }}
+              subPath: unittests.cfg
+              readOnly: true
             - name: shipyard-etc
               mountPath: /usr/local/airflow/plugins/shipyard.conf
               subPath: shipyard.conf
@@ -90,6 +96,10 @@ spec:
           configMap:
             name: airflow-etc
             defaultMode: 0444
+        - name: airflow-usr
+          configMap:
+            name: airflow-usr
+            defaultMode: 0444
         - name: shipyard-etc
           configMap:
             name: shipyard-etc
diff --git a/charts/shipyard/templates/statefulset-airflow-worker.yaml b/charts/shipyard/templates/statefulset-airflow-worker.yaml
index 5eb6cc87..ee9a9a33 100644
--- a/charts/shipyard/templates/statefulset-airflow-worker.yaml
+++ b/charts/shipyard/templates/statefulset-airflow-worker.yaml
@@ -124,14 +124,14 @@ spec:
           # Set to -1 to stop scheduler from going into crash loops
           args: ["scheduler", "-n", "-1" ]
           volumeMounts:
-            - name: airflow-usr
-              mountPath: /usr/local/airflow/unittests.cfg
-              subPath: unittests.cfg
-              readOnly: false
             - name: airflow-etc
               mountPath: {{ .Values.conf.airflow_config_file.path }}
               subPath: airflow.cfg
               readOnly: true
+            - name: airflow-usr
+              mountPath: {{ .Values.conf.airflow_unittests_file.path }}
+              subPath: unittests.cfg
+              readOnly: true
             - name: shipyard-etc
               mountPath: /usr/local/airflow/plugins/shipyard.conf
               subPath: shipyard.conf
@@ -142,6 +142,7 @@ spec:
           image: {{ .Values.images.tags.airflow }}
           imagePullPolicy: {{ .Values.images.pull_policy }}
 {{ tuple $envAll $envAll.Values.pod.resources.airflow.worker | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+{{ dict "envAll" $envAll "application" "airflow_worker" "container" "airflow_worker" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
           env:
           - name: AIRFLOW_CONN_AIRFLOWS_OWN_DB
             valueFrom:
@@ -155,10 +156,16 @@ spec:
             tcpSocket:
               port: {{ .Values.network.airflow.worker.port }}
           volumeMounts:
+            - name: pod-tmp
+              mountPath: /tmp
             - name: airflow-etc
               mountPath: {{ .Values.conf.airflow_config_file.path }}
               subPath: airflow.cfg
               readOnly: true
+            - name: airflow-usr
+              mountPath: {{ .Values.conf.airflow_unittests_file.path }}
+              subPath: unittests.cfg
+              readOnly: true
             - name: shipyard-etc
               mountPath: /usr/local/airflow/plugins/shipyard.conf
               subPath: shipyard.conf
@@ -193,7 +200,7 @@ spec:
             - name: airflow-logs
               mountPath: {{ .Values.conf.airflow.core.base_log_folder }}
       volumes:
-        - name: airflow-usr
+        - name: pod-tmp
           emptyDir: {}
         - name: airflow-etc
           projected:
@@ -204,6 +211,15 @@ spec:
                   items:
                     - key: airflow.cfg
                       path: airflow.cfg
+        - name: airflow-usr
+          projected:
+            defaultMode: 0444
+            sources:
+              - configMap:
+                  name: airflow-usr
+                  items:
+                    - key: unittests.cfg
+                      path: unittests.cfg
         - name: shipyard-etc
           projected:
             defaultMode: 0444
diff --git a/charts/shipyard/values.yaml b/charts/shipyard/values.yaml
index 9adf17bd..4b037428 100644
--- a/charts/shipyard/values.yaml
+++ b/charts/shipyard/values.yaml
@@ -450,6 +450,8 @@ conf:
       deployment_version_commit: Skip
   airflow_config_file:
     path: /usr/local/airflow/airflow.cfg
+  airflow_unittests_file:
+    path: /usr/local/airflow/unittests.cfg
   airflow:
     # NOTE: Airflow 1.10 introduces a need to declare all config options:
     #     https://issues.apache.org/jira/browse/AIRFLOW-3099
@@ -736,6 +738,13 @@ pod:
           allowPrivilegeEscalation: false
         airflow_web:
           allowPrivilegeEscalation: false
+    airflow_scheduler:
+      pod:
+        runAsUser: 1000
+      container:
+        airflow_scheduler:
+          readOnlyRootFilesystem: true
+          allowPrivilegeEscalation: false
     airflow_worker:
       pod:
         runAsUser: 1000
@@ -746,6 +755,9 @@ pod:
         airflow_scheduler:
           readOnlyRootFilesystem: true
           allowPrivilegeEscalation: false
+        airflow_worker:
+          readOnlyRootFilesystem: true
+          allowPrivilegeEscalation: false
         airflow_logrotate:
           readOnlyRootFilesystem: true
           allowPrivilegeEscalation: false
@@ -923,6 +935,7 @@ manifests:
   configmap_shipyard_etc: true
   configmap_airflow_bin: true
   configmap_airflow_etc: true
+  configmap_airflow_usr: true
   # TODO: Set this to false only if a new deployment, or if the worker pod is
   #   running the scheduler
   deployment_airflow_scheduler: true