[COMMON] Use common secret template in dgbuilder 56/101856/2
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Mon, 17 Feb 2020 21:05:51 +0000 (22:05 +0100)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 18 Feb 2020 11:33:20 +0000 (12:33 +0100)
Taken into account how "easy" it would be to modify the dgbuilder
which is written in JavaScript (which is not my mother tongue to say
the least) let's try to remove hardcoded passwords from config files
without modifying the application container itself.

In order to achieve this:

1) Remove createReleaseDir.sh script from the container as it is never
used and contains a ton of passwords

2) Replace all sensitive values in config files with references to
respective environment variables

3) Introduce init container that will run envsubst command on config
files and copy them from ConfigMap value to the new volume which is
backed by tmpfs so that the plain text passwords are never written to
the disk

For now all the hardcoded values are still there to minimize the risk
of breaking the deployment but step by step they will be removed in
next commits.

Issue-ID: OOM-2247
Change-Id: I5a428e3415713857084ba6aaa6be9b04a8eb8c0f
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
kubernetes/common/dgbuilder/resources/config/customSettings.js [moved from kubernetes/common/dgbuilder/resources/scripts/customSettings.js with 78% similarity]
kubernetes/common/dgbuilder/resources/config/svclogic.properties
kubernetes/common/dgbuilder/resources/scripts/createReleaseDir.sh [deleted file]
kubernetes/common/dgbuilder/templates/configmap.yaml
kubernetes/common/dgbuilder/templates/deployment.yaml
kubernetes/common/dgbuilder/templates/secrets.yaml
kubernetes/common/dgbuilder/values.yaml

@@ -26,31 +26,31 @@ module.exports={
     "sharedDir": "releases/sdnc1.0/flows/shared",
     "userDir": "releases/sdnc1.0",
     "httpAuth": {
-        "user": "dguser",
-        "pass": "{{.Values.config.dgUserPassword}}"
+        "user": "${HTTP_USER}",
+        "pass": "${HTTP_PASSWORD}"
     },
     "dbHost": "{{.Values.config.dbServiceName}}.{{ include "common.namespace" . }}",
     "dbPort": "3306",
-    "dbName": "sdnctl",
-    "dbUser": "sdnctl",
-    "dbPassword": "{{.Values.config.dbSdnctlPassword}}",
+    "dbName": "{{.Values.config.db.dbName}}",
+    "dbUser": "${DB_USER}",
+    "dbPassword": "${DB_PASSWORD}",
     "gitLocalRepository": "",
     "restConfUrl": "http://localhost:8181/restconf/operations/SLI-API:execute-graph",
-    "restConfUser": "admin",
-    "restConfPassword": "admin",
+    "restConfUser": "${REST_CONF_USER}",
+    "restConfPassword": "${REST_CONF_PASSWORD}",
     "formatXML": "Y",
     "formatJSON": "Y",
     "httpRoot": "/",
     "disableEditor": false,
     "httpAdminRoot": "/",
     "httpAdminAuth": {
-        "user": "dguser",
-        "pass": "{{.Values.config.dgUserPassword}}"
+        "user": "${HTTP_ADMIN_USER}",
+        "pass": "${HTTP_ADMIN_PASSWORD}"
     },
     "httpNodeRoot": "/",
     "httpNodeAuth": {
-        "user": "dguser",
-        "pass": "{{.Values.config.dgUserPassword}}"
+        "user": "${HTTP_NODE_USER}",
+        "pass": "${HTTP_NODE_PASSWORD}"
     },
     "uiHost": "0.0.0.0",
     "version": "0.9.1",
index b780caf..28612a2 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 org.onap.ccsdk.sli.dbtype=jdbc
-org.onap.ccsdk.sli.jdbc.url=jdbc:mysql://{{.Values.config.dbServiceName}}.{{ include "common.namespace" . }}:3306/sdnctl
-org.onap.ccsdk.sli.jdbc.database=sdnctl
-org.onap.ccsdk.sli.jdbc.user=sdnctl
-org.onap.ccsdk.sli.jdbc.password={{.Values.config.dbSdnctlPassword}}
+org.onap.ccsdk.sli.jdbc.url=jdbc:mysql://{{.Values.config.dbServiceName}}.{{ include "common.namespace" . }}:3306/{{.Values.config.db.dbName}}
+org.onap.ccsdk.sli.jdbc.database={{.Values.config.db.dbName}}
+org.onap.ccsdk.sli.jdbc.user=${DB_USER}
+org.onap.ccsdk.sli.jdbc.password=${DB_PASSWORD}
diff --git a/kubernetes/common/dgbuilder/resources/scripts/createReleaseDir.sh b/kubernetes/common/dgbuilder/resources/scripts/createReleaseDir.sh
deleted file mode 100755 (executable)
index b037058..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright © 2018 AT&T, Amdocs, Bell Canada
-#
-# 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.
-
-#!/bin/bash
-export PATH=$PATH:.
-appDir=$(pwd)
-if [ "$#" != 3 -a "$#" != 4 ]
-then
-       echo "Usage $0 releaseDir  loginId emailAddress [gitLocalRepository]"
-       echo "Note: Specify the gitLocalRepository path if you would want to be able to import flows from your local git repository"
-       exit
-fi
-if [ ! -e "releases" ]
-then
-       mkdir releases
-fi
-releaseDir="$1"
-name="Release $releaseDir"
-loginId="$2"
-emailid="$3"
-dbHost="{{.Values.config.dbServiceName}}.{{.Release.Namespace}}"
-dbPort="3306"
-dbName="sdnctl"
-dbUser="sdnctl"
-dbPassword="{{.Values.config.dbSdnctlPassword}}"
-gitLocalRepository="$4"
-
-lastPort=$(find "releases/" -name "customSettings.js" |xargs grep uiPort|cut -d: -f2|sed -e s/,//|sort|tail -1)
-echo $lastPort|grep uiPort >/dev/null 2>&1
-if [ "$?" == "0" ]
-then
-lastPort=$(find "releases/" -name "customSettings.js" |xargs grep uiPort|cut -d: -f3|sed -e s/,//|sort|tail -1)
-fi
-#echo $lastPort
-if [ "${lastPort}" == "" ]
-then
-       lastPort="3099"
-fi
-let nextPort=$(expr $lastPort+1)
-#echo $nextPort
-if [ ! -e "releases/$releaseDir" ]
-then
-mkdir releases/$releaseDir
-cd releases/$releaseDir
-mkdir flows
-mkdir flows/shared
-mkdir flows/shared/backups
-mkdir html
-mkdir xml
-mkdir lib
-mkdir lib/flows
-mkdir logs
-mkdir conf
-mkdir codecloud
-customSettingsFile="customSettings.js"
-if [ ! -e "./$customSettingsFile" ]
-then
-       echo "module.exports = {" >$customSettingsFile
-       echo "          'name' : '$name'," >>$customSettingsFile
-       echo "          'emailAddress' :'$emailid'," >>$customSettingsFile
-       echo "          'uiPort' :$nextPort," >>$customSettingsFile
-       echo "          'mqttReconnectTime': 15000," >>$customSettingsFile
-       echo "          'serialReconnectTime' : 15000,"  >>$customSettingsFile
-       echo "          'debugMaxLength': 1000," >>$customSettingsFile
-       echo "          'htmlPath': 'releases/$releaseDir/html/'," >>$customSettingsFile
-       echo "          'xmlPath': 'releases/$releaseDir/xml/'," >>$customSettingsFile
-       echo "          'flowFile' : 'releases/$releaseDir/flows/flows.json'," >>$customSettingsFile
-       echo "          'sharedDir': 'releases/$releaseDir/flows/shared'," >>$customSettingsFile
-       echo "          'userDir' : 'releases/$releaseDir'," >>$customSettingsFile
-       echo "          'httpAuth': {user:'$loginId',pass:'cc03e747a6afbbcbf8be7668acfebee5'}," >>$customSettingsFile
-       echo "          'dbHost': '$dbHost'," >>$customSettingsFile
-       echo "          'dbPort': '$dbPort'," >>$customSettingsFile
-       echo "          'dbName': '$dbName'," >>$customSettingsFile
-       echo "          'dbUser': '$dbUser'," >>$customSettingsFile
-       echo "          'dbPassword': '$dbPassword'," >>$customSettingsFile
-       echo "          'gitLocalRepository': '$gitLocalRepository'" >>$customSettingsFile
-       echo "          'restConfUrl': '$restConfUrl'," >>$customSettingsFile
-       echo "          'restConfUser': '$restConfUser'," >>$customSettingsFile
-       echo "          'restConfPassword': '$restConfPassword'," >>$customSettingsFile
-       echo "          'formatXML': '$formatXML'," >>$customSettingsFile
-       echo "          'formatJSON': '$formatJSON'," >>$customSettingsFile
-       echo "          'enableHttps': true" >>$customSettingsFile
-       echo "          }" >>$customSettingsFile
-fi
-       #echo "Created custom settings  file $customSettingsFile"
-       echo "Done ....."
-else
-       echo "ERROR:customSettings file $customSettingsFile already exists for $releaseDir"
-       exit
-fi
-#echo "Content of custom settings file"
-#echo "============================================================================"
-#      cat $customSettingsFile
-#echo "============================================================================"
-svclogicPropFile="./conf/svclogic.properties"
-if [ ! -d "${appDir}/yangFiles" ]
-then
-       mkdir -p "${appDir}/yangFiles"
-fi
-if [ ! -d "${appDir}/generatedJS" ]
-then
-       mkdir -p "${appDir}/generatedJS"
-fi
-
-if [ ! -e "./$svclogicPropFile" ]
-then
-       echo "org.onap.ccsdk.sli.dbtype=jdbc" >$svclogicPropFile
-       echo "org.onap.ccsdk.sli.jdbc.url=jdbc:mysql://{{.Values.config.dbServiceName}}.{{.Release.Namespace}}:3306/sdnctl" >>$svclogicPropFile
-       echo "org.onap.ccsdk.sli.jdbc.database=sdnctl" >>$svclogicPropFile
-       echo "org.onap.ccsdk.sli.jdbc.user=sdnctl" >>$svclogicPropFile
-       echo "org.onap.ccsdk.sli.jdbc.password={{.Values.config.dbSdnctlPassword}}" >>$svclogicPropFile
-fi
-if [ ! -e "${appDir}/flowShareUsers.js" ]
-then
-       echo "module.exports = {\"flowShareUsers\":" >${appDir}/flowShareUsers.js
-        echo " [" >>${appDir}/flowShareUsers.js
-        echo " ]" >>${appDir}/flowShareUsers.js
-        echo "}" >>${appDir}/flowShareUsers.js
-fi
-grep "$releaseDir" ${appDir}/flowShareUsers.js >/dev/null 2>&1
-if [ "$?" != "0" ]
-then
-       num_of_lines=$(cat ${appDir}/flowShareUsers.js|wc -l)
-       if [ $num_of_lines -gt 4 ]
-       then
-               content=$(head -n -2 ${appDir}/flowShareUsers.js)
-               echo "${content}," > ${appDir}/flowShareUsers.js
-       else
-               content=$(head -n -2 ${appDir}/flowShareUsers.js)
-               echo "$content" > ${appDir}/flowShareUsers.js
-       fi
-       echo "  {" >> ${appDir}/flowShareUsers.js
-       echo "          \"name\" : \"$name\"," >> ${appDir}/flowShareUsers.js
-       echo "          \"rootDir\" : \"$releaseDir\"" >> ${appDir}/flowShareUsers.js
-       echo "  }" >> ${appDir}/flowShareUsers.js
-       echo "  ]" >> ${appDir}/flowShareUsers.js
-       echo "}" >> ${appDir}/flowShareUsers.js
-fi
index 24f61b5..828818c 100644 (file)
@@ -24,16 +24,3 @@ metadata:
     heritage: {{ .Release.Service }}
 data:
 {{ tpl (.Files.Glob "resources/config/*").AsConfig . | indent 2 }}
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "common.fullname" . }}-scripts
-  namespace: {{ include "common.namespace" . }}
-  labels:
-    app: {{ include "common.name" . }}
-    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
-    release: {{ include "common.release" . }}
-    heritage: {{ .Release.Service }}
-data:
-{{ tpl (.Files.Glob "resources/scripts/*").AsConfig . | indent 2 }}
index 495c4c6..b3f0ab0 100644 (file)
@@ -31,6 +31,40 @@ spec:
         release: {{ include "common.release" . }}
     spec:
       initContainers:
+      - command:
+        - sh
+        args:
+        - -c
+        - "cd /config-input && for PFILE in `ls -1 .`; do envsubst <${PFILE} >/config/${PFILE}; done"
+        env:
+        - name: DB_USER
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "db-user-creds" "key" "login") | indent 10 }}
+        - name: DB_PASSWORD
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "db-user-creds" "key" "password") | indent 10 }}
+        - name: HTTP_USER
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "http-user-creds" "key" "login") | indent 10 }}
+        - name: HTTP_PASSWORD
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "http-user-creds" "key" "password") | indent 10 }}
+        - name: HTTP_ADMIN_USER
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "admin-creds" "key" "login") | indent 10 }}
+        - name: HTTP_ADMIN_PASSWORD
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "admin-creds" "key" "password") | indent 10 }}
+        - name: HTTP_NODE_USER
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "node-creds" "key" "login") | indent 10 }}
+        - name: HTTP_NODE_PASSWORD
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "node-creds" "key" "password") | indent 10 }}
+        - name: REST_CONF_USER
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "restconf-creds" "key" "login") | indent 10 }}
+        - name: REST_CONF_PASSWORD
+          {{- include "common.secret.envFromSecret" (dict "global" . "uid" "restconf-creds" "key" "password") | indent 10 }}
+        volumeMounts:
+        - mountPath: /config-input
+          name: config-input
+        - mountPath: /config
+          name: config
+        image: "{{ .Values.global.envsubstImage }}"
+        imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
+        name: {{ include "common.name" . }}-update-config
       - command:
         - /root/ready.py
         args:
@@ -59,11 +93,6 @@ spec:
             initialDelaySeconds: {{ .Values.readiness.initialDelaySeconds }}
             periodSeconds: {{ .Values.readiness.periodSeconds }}
           env:
-          - name: MYSQL_ROOT_PASSWORD
-            valueFrom:
-              secretKeyRef:
-                name: {{ template "common.fullname" . }}
-                key: db-root-password
           - name: SDNC_CONFIG_DIR
             value: /opt/onap/sdnc/data/properties
           volumeMounts:
@@ -79,10 +108,7 @@ spec:
           - name: config
             mountPath: /opt/onap/ccsdk/dgbuilder/svclogic/svclogic.properties
             subPath: svclogic.properties
-          - name: scripts
-            mountPath: /opt/onap/ccsdk/dgbuilder/createReleaseDir.sh
-            subPath: createReleaseDir.sh
-          - name: scripts
+          - name: config
             mountPath: /opt/onap/ccsdk/dgbuilder/releases/sdnc1.0/customSettings.js
             subPath: customSettings.js
           resources:
@@ -99,12 +125,11 @@ spec:
         - name: localtime
           hostPath:
             path: /etc/localtime
-        - name: config
+        - name: config-input
           configMap:
             name: {{ include "common.fullname" . }}-config
-        - name: scripts
-          configMap:
-            name: {{ include "common.fullname" . }}-scripts
-            defaultMode: 0755
+        - name: config
+          emptyDir:
+            medium: Memory
       imagePullSecrets:
       - name: "{{ include "common.namespace" . }}-docker-registry-key"
index e00d7cf..c9a409f 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright © 2018 AT&T, Amdocs, Bell Canada
+# Copyright © 2020 Samsung Electronics
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ include "common.fullname" . }}
-  namespace: {{ include "common.namespace" . }}
-  labels:
-    app: {{ include "common.fullname" . }}
-    chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
-    release: {{ include "common.release" . }}
-    heritage: {{ .Release.Service }}
-type: Opaque
-data:
-  db-root-password: {{ .Values.config.dbRootPassword | b64enc | quote }}
\ No newline at end of file
+{{ include "common.secret" . }}
index fa205e2..96d7dff 100644 (file)
@@ -31,6 +31,9 @@ global:
   loggingRepository: docker.elastic.co
   loggingImage: beats/filebeat:5.5.0
 
+  # envsusbt
+  envsubstImage: dibi/envsubst
+
   # image pull policy
   pullPolicy: Always
 
@@ -42,6 +45,40 @@ global:
   # flag to enable debugging - application support required
   debugEnabled: true
 
+#################################################################
+# Secrets metaconfig
+#################################################################
+secrets:
+  - uid: 'db-root-password'
+    type: password
+    externalSecret: '{{ tpl (default "" .Values.config.db.rootPasswordExternalSecret) . }}'
+    password: '{{ .Values.config.dbRootPassword }}'
+  - uid: 'db-user-creds'
+    type: basicAuth
+    externalSecret: '{{ tpl (default "" .Values.config.db.userCredentialsExternalSecret) . }}'
+    login: '{{ .Values.config.db.userName }}'
+    password: '{{ .Values.config.dbSdnctlPassword }}'
+  - uid: 'http-user-creds'
+    type: basicAuth
+    externalSecret: '{{ tpl (default "" .Values.config.httpCredsExternalSecret) . }}'
+    login: '{{ .Values.config.httpUser }}'
+    password: '{{ .Values.config.dgUserPassword }}'
+  - uid: 'admin-creds'
+    type: basicAuth
+    externalSecret: '{{ tpl (default "" .Values.config.adminCredsExternalSecret) . }}'
+    login: '{{ .Values.config.adminUser }}'
+    password: '{{ .Values.config.dgUserPassword }}'
+  - uid: 'node-creds'
+    type: basicAuth
+    externalSecret: '{{ tpl (default "" .Values.config.nodeCredsExternalSecret) . }}'
+    login: '{{ .Values.config.nodeUser }}'
+    password: '{{ .Values.config.dgUserPassword }}'
+  - uid: 'restconf-creds'
+    type: basicAuth
+    externalSecret: '{{ tpl (default "" .Values.config.restconfCredsExternalSecret) . }}'
+    login: '{{ .Values.config.restconfUser }}'
+    password: '{{ .Values.config.restconfPassword }}'
+
 #################################################################
 # Application configuration defaults.
 #################################################################
@@ -55,6 +92,32 @@ debugEnabled: false
 
 # application configuration
 config:
+  db:
+    dbName: sdnctl
+    # unused for now to preserve the API
+    rootPassword: openECOMP1.0
+    # rootPasswordExternalSecret: some secret
+    userName: sdnctl
+    # unused for now to preserve the API
+    userPassword: gamma
+    # userCredentialsExternalSecret: some secret
+  httpUser: dguser
+  # unused for now to preserve the API
+  httpPassword: cc03e747a6afbbcbf8be7668acfebee5
+  # httpCredsExternalSecret: some secret
+  adminUser: dguser
+  # unused for now to preserve the API
+  adminPassword: cc03e747a6afbbcbf8be7668acfebee5
+  # adminCredsExternalSecret: some secret
+  nodeUser: dguser
+  # unused for now to preserve the API
+  nodePassword: cc03e747a6afbbcbf8be7668acfebee5
+  # nodeCredsExternalSecret: some secret
+  restconfUser: admin
+  # unused for now to preserve the API
+  restconfPassword: admin
+  # restconfCredsExternalSecret: some secret
+
   dbRootPassword: openECOMP1.0
   dbSdnctlPassword: gamma
   dbPodName: mysql-db