[DCAEGEN2-SVCS] Support config update via configMap
[oom.git] / kubernetes / dcaegen2-services / common / dcaegen2-services-common / templates / _deployment.tpl
index db58726..6c742c0 100644 (file)
@@ -1,8 +1,10 @@
 {{/*
 #============LICENSE_START========================================================
 # ================================================================================
-# Copyright (c) 2021 J. F. Lucas. All rights reserved.
+# Copyright (c) 2021-2022 J. F. Lucas. All rights reserved.
 # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2021 Nokia. All rights reserved.
+# Copyright (c) 2021 Nordix Foundation.
 # ================================================================================
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -31,7 +33,7 @@ provided to all microservices.
 The template expects a single argument, pointing to the caller's global context.
 
 Microservice-specific environment variables can be specified in two ways:
-  1. As literal string values.
+  1. As literal string values. (The values can also be Helm template fragments.)
   2. As values that are sourced from a secret, identified by the secret's
      uid and the key within the secret that provides the value.
 
@@ -56,7 +58,7 @@ the the literal string "An example value".
     {{- range $envName, $envValue := .Values.applicationEnv }}
       {{- if kindIs "string" $envValue }}
 - name: {{ $envName }}
-  value: {{ $envValue | quote }}
+  value: {{ tpl $envValue $global | quote }}
       {{- else }}
         {{ if or (not $envValue.secretUid) (not $envValue.key) }}
           {{ fail (printf "Env %s definition is not a string and does not contain secretUid or key fields" $envName) }}
@@ -68,6 +70,91 @@ the the literal string "An example value".
   {{- end }}
 {{- end -}}
 {{/*
+For internal use only!
+
+dcaegen2-services-common._externalVolumes:
+This template generates a list of volumes associated with the pod,
+based on information provided in .Values.externalVolumes.  This
+template works in conjunction with dcaegen2-services-common._externalVolumeMounts
+to give the microservice access to data in volumes created else.
+This initial implementation supports ConfigMaps only, as this is the only
+external volume mounting required by current microservices.
+
+.Values.externalVolumes is a list of objects.  Each object has 3 required fields and 2 optional fields:
+   - name: the name of the resource (in the current implementation, it must be a ConfigMap)
+     that is to be set up as a volume.  The value is a case sensitive string.  Because the
+     names of resources are sometimes set at deployment time (for instance, to prefix the Helm
+     release to the name), the string can be a Helm template fragment that will be expanded at
+     deployment time.
+   - type: the type of the resource (in the current implementation, only "ConfigMap" is supported).
+     The value is a case-INsensitive string.
+   - mountPoint: the path to the mount point for the volume in the container file system.  The
+     value is a case-sensitive string.
+   - readOnly: (Optional) Boolean flag.  Set to true to mount the volume as read-only.
+     Defaults to false.
+   - optional: (Optional) Boolean flag.  Set to true to make the configMap optional (i.e., to allow the
+     microservice's pod to start even if the configMap doesn't exist).  If set to false, the configMap must
+     be present in order for the microservice's pod to start. Defaults to true.  (Note that this
+     default is the opposite of the Kubernetes default.  We've done this to be consistent with the behavior
+     of the DCAE Cloudify plugin for Kubernetes [k8splugin], which always set "optional" to true.)
+
+Here is an example fragment from a values.yaml file for a microservice:
+
+externalVolumes:
+  - name: my-example-configmap
+    type: configmap
+    mountPath: /opt/app/config
+  - name: '{{ include "common.release" . }}-another-example'
+    type: configmap
+    mountPath: /opt/app/otherconfig
+    optional: false
+*/}}
+{{- define "dcaegen2-services-common._externalVolumes" -}}
+  {{- $global := . -}}
+  {{- if .Values.externalVolumes }}
+    {{- range $vol := .Values.externalVolumes }}
+      {{- if eq (lower $vol.type) "configmap" }}
+        {{- $vname := (tpl $vol.name $global) -}}
+        {{- $opt := hasKey $vol "optional" | ternary $vol.optional true }}
+- configMap:
+    defaultMode: 420
+    name: {{ $vname }}
+    optional: {{ $opt }}
+  name: {{ $vname }}
+      {{- end }}
+    {{- end }}
+  {{- end }}
+{{- end }}
+{{/*
+For internal use only!
+
+dcaegen2-services-common._externalVolumeMounts:
+This template generates a list of volume mounts for the microservice container,
+based on information provided in .Values.externalVolumes.  This
+template works in conjunction with dcaegen2-services-common._externalVolumes
+to give the microservice access to data in volumes created else.
+This initial implementation supports ConfigMaps only, as this is the only
+external volume mounting required by current microservices.
+
+See the documentation for dcaegen2-services-common._externalVolumes for
+details on how external volumes are specified in the values.yaml file for
+the microservice.
+*/}}
+{{- define "dcaegen2-services-common._externalVolumeMounts" -}}
+  {{- $global := . -}}
+  {{- if .Values.externalVolumes }}
+    {{- range $vol := .Values.externalVolumes }}
+      {{- if eq (lower $vol.type) "configmap" }}
+        {{- $vname := (tpl $vol.name $global) -}}
+        {{- $readOnly := $vol.readOnly | default false }}
+- mountPath: {{ $vol.mountPath }}
+  name: {{ $vname }}
+  readOnly: {{ $readOnly }}
+      {{- end }}
+    {{- end }}
+  {{- end }}
+{{- end }}
+{{/*
 dcaegen2-services-common.microserviceDeployment:
 This template produces a Kubernetes Deployment for a DCAE microservice.
 
@@ -89,21 +176,42 @@ The Deployment always includes a single Pod, with a container that uses
 the DCAE microservice image.
 
 The Deployment Pod may also include a logging sidecar container.
-The sidecar is included if .Values.logDirectory is set.  The
+The sidecar is included if .Values.log.path is set.  The
 logging sidecar and the DCAE microservice container share a
 volume where the microservice logs are written.
 
-The Deployment includes an initContainer that pushes the
-microservice's initial configuration (from .Values.applicationConfig)
-into Consul.  All DCAE microservices retrieve their initial
-configurations by making an API call to a DCAE platform component called
-the  config-binding-service.  The config-binding-service currently
-retrieves configuration information from Consul.
+Deployed POD may also include a Policy-sync sidecar container.
+The sidecar is included if .Values.policies is set.  The
+Policy-sync sidecar polls PolicyEngine (PDP) periodically based
+on .Values.policies.duration and configuration retrieved is shared with
+DCAE Microservice container by common volume. Policy can be retrieved based on
+list of policyID or filter. An optional policyRelease parameter can be specified
+to override the default policy helm release (used for retreiving the secret containing
+pdp username and password)
+
+Following is example policy config override
 
-The Deployment also includes an initContainer that checks for the
+dcaePolicySyncImage: onap/org.onap.dcaegen2.deployments.dcae-services-policy-sync:1.0.1
+policies:
+  duration: 300
+  policyRelease: "onap"
+  policyID: |
+    '["onap.vfirewall.tca","onap.vdns.tca"]'
+
+The Deployment includes an initContainer that checks for the
 readiness of other components that the microservice relies on.
 This container is generated by the "common.readinessCheck.waitfor"
-template.
+template. See the documentation for this template
+(oom/kubernetes/common/readinessCheck/templates/_readinessCheck.tpl).
+
+If the microservice uses a DMaaP Data Router (DR) feed, the Deployment
+includes an initContainer that makes provisioning requests to the DMaaP
+bus controller (dmaap-bc) to create the feed and to set up a publisher
+and/or subscriber to the feed.  The Deployment also includes a second
+initContainer that merges the information returned by the provisioning
+process into the microservice's configuration.  See the documentation for
+the common DMaaP provisioning template
+(oom/kubernetes/common/common/templates/_dmaapProvisioning.tpl).
 
 If the microservice acts as a TLS client or server, the Deployment will
 include an initContainer that retrieves certificate information from
@@ -115,23 +223,26 @@ formats.  It will also include the AAF CA cert.   If the microservice is
 a TLS client only (indicated by setting .Values.tlsServer to false), the
 certificate information includes only the AAF CA cert.
 
-Deployed POD may also include a Policy-sync sidecar container.
-The sidecar is included if .Values.policies is set.  The
-Policy-sync sidecar polls PolicyEngine (PDP) periodically based
-on .Values.policies.duration and configuration retrieved is shared with
-DCAE Microservice container by common volume. Policy can be retrieved based on
-list of policyID or filter
+If the microservice uses certificates from an external CMPv2 provider,
+the Deployment will include an initContainer that performs certificate
+post-processing.
 */}}
 
 {{- define "dcaegen2-services-common.microserviceDeployment" -}}
-{{- $logDir :=  default "" .Values.logDirectory -}}
+{{- $log := default dict .Values.log -}}
+{{- $logDir :=  default "" $log.path -}}
 {{- $certDir := default "" .Values.certDirectory . -}}
 {{- $tlsServer := default "" .Values.tlsServer -}}
-{{- $policy := default "" .Values.policies -}}
-
+{{- $commonRelease :=  print (include "common.release" .) -}}
+{{- $policy := default dict .Values.policies -}}
+{{- $policyRls := default $commonRelease $policy.policyRelease -}}
+{{- $drFeedConfig := default "" .Values.drFeedConfig -}}
+{{- $dcaeName := print (include "common.fullname" .) }}
+{{- $dcaeLabel := (dict "dcaeMicroserviceName" $dcaeName) -}}
+{{- $dot := . -}}
 apiVersion: apps/v1
 kind: Deployment
-metadata: {{- include "common.resourceMetadata" . | nindent 2 }}
+metadata: {{- include "common.resourceMetadata" (dict "dot" $dot "labels" $dcaeLabel) | nindent 2 }}
 spec:
   replicas: 1
   selector: {{- include "common.selectors" . | nindent 4 }}
@@ -139,40 +250,8 @@ spec:
     metadata: {{- include "common.templateMetadata" . | nindent 6 }}
     spec:
       initContainers:
-      - command:
-        - sh
-        args:
-        - -c
-        - |
-        {{- range $var := .Values.customEnvVars }}
-          export {{ $var.name }}="{{ $var.value }}";
-        {{- end }}
-          cd /config-input && for PFILE in `ls -1`; do envsubst <${PFILE} >/config/${PFILE}; done
-        env:
-        {{- range $cred := .Values.credentials }}
-        - name: {{ $cred.name }}
-          {{- include "common.secret.envFromSecretFast" (dict "global" $ "uid" $cred.uid "key" $cred.key) | indent 10 }}
-        {{- end }}
-        volumeMounts:
-        - mountPath: /config-input
-          name: app-config-input
-        - mountPath: /config
-          name: app-config
-        image: {{ include "repositoryGenerator.image.envsubst" . }}
-        imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
-        name: {{ include "common.name" . }}-update-config
-
       {{ include "common.readinessCheck.waitFor" . | indent 6 | trim }}
-      - name: init-consul
-        image: {{ include "repositoryGenerator.repository" . }}/{{ .Values.consulLoaderImage }}
-        imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
-        args:
-        - --key-yaml
-        - "{{ include "common.name" . }}|/app-config/application_config.yaml"
-        resources: {{ include "common.resources" . | nindent 2 }}
-        volumeMounts:
-          - mountPath: /app-config
-            name: app-config
+      {{- include "common.dmaap.provisioning.initContainer" . | nindent 6 }}
       {{- if $certDir }}
       - name: init-tls
         image: {{ include "repositoryGenerator.repository" . }}/{{ .Values.tlsImage }}
@@ -196,6 +275,10 @@ spec:
         imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
         name: {{ include "common.name" . }}
         env:
+        {{- range $cred := .Values.credentials }}
+        - name: {{ $cred.name }}
+          {{- include "common.secret.envFromSecretFast" (dict "global" $ "uid" $cred.uid "key" $cred.key) | indent 10 }}
+        {{- end }}
         {{- if $certDir }}
         - name: DCAE_CA_CERTPATH
           value: {{ $certDir }}/cacert.pem
@@ -238,15 +321,17 @@ spec:
         resources: {{ include "common.resources" . | nindent 2 }}
         volumeMounts:
         - mountPath: /app-config
-          name: app-config
+          name: {{ ternary "app-config-input" "app-config" (not $drFeedConfig) }}
+        - mountPath: /app-config-input
+          name: app-config-input
         {{- if $logDir }}
         - mountPath: {{ $logDir}}
-          name: component-log
+          name: logs
         {{- end }}
         {{- if $certDir }}
         - mountPath: {{ $certDir }}
           name: tls-info
-          {{- if and .Values.certificates .Values.global.cmpv2Enabled .Values.global.CMPv2CertManagerIntegration -}}
+          {{- if (include "dcaegen2-services-common.shouldUseCmpv2Certificates" .) -}}
           {{- include "common.certManager.volumeMountsReadOnly" . | nindent 8 -}}
           {{- end -}}
         {{- end }}
@@ -254,25 +339,9 @@ spec:
         - name: policy-shared
           mountPath: /etc/policies
         {{- end }}
+        {{- include "dcaegen2-services-common._externalVolumeMounts" . | nindent 8 }}
       {{- if $logDir }}
-      - image: {{ include "repositoryGenerator.image.logging" . }}
-        imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }}
-        name: filebeat
-        env:
-        - name: POD_IP
-          valueFrom:
-            fieldRef:
-              apiVersion: v1
-              fieldPath: status.podIP
-        resources: {{ include "common.resources" . | nindent 2 }}
-        volumeMounts:
-        - mountPath: /var/log/onap/{{ include "common.name" . }}
-          name: component-log
-        - mountPath: /usr/share/filebeat/data
-          name: filebeat-data
-        - mountPath: /usr/share/filebeat/filebeat.yml
-          name: filebeat-conf
-          subPath: filebeat.yml
+      {{ include "common.log.sidecar" . | nindent 6 }}
       {{- end }}
       {{- if $policy }}
       - image: {{ include "repositoryGenerator.repository" . }}/{{ .Values.dcaePolicySyncImage }}
@@ -287,15 +356,15 @@ spec:
         - name: POLICY_SYNC_PDP_USER
           valueFrom:
             secretKeyRef:
-              name: onap-policy-xacml-pdp-api-creds
+              name: {{ $policyRls }}-policy-xacml-pdp-restserver-creds
               key: login
         - name: POLICY_SYNC_PDP_PASS
           valueFrom:
             secretKeyRef:
-              name: onap-policy-xacml-pdp-api-creds
+              name: {{ $policyRls }}-policy-xacml-pdp-restserver-creds
               key: password
         - name: POLICY_SYNC_PDP_URL
-          value : http{{ if (include "common.needTLS" .) }}s{{ end }}://policy-xacml-pdp:6969 
+          value : http{{ if (include "common.needTLS" .) }}s{{ end }}://policy-xacml-pdp:6969
         - name: POLICY_SYNC_OUTFILE
           value : "/etc/policies/policies.json"
         - name: POLICY_SYNC_V1_DECISION_ENDPOINT
@@ -310,7 +379,7 @@ spec:
         {{- end -}}
         {{- if $policy.duration }}
         - name: POLICY_SYNC_DURATION
-          value: {{ $policy.duration }}
+          value: "{{ $policy.duration }}"
         {{- end }}
         resources: {{ include "common.resources" . | nindent 2 }}
         volumeMounts:
@@ -322,6 +391,7 @@ spec:
         {{- end }}
       {{- end }}
       hostname: {{ include "common.name" . }}
+      serviceAccountName: {{ include "common.fullname" (dict "suffix" "read" "dot" . )}}
       volumes:
       - configMap:
           defaultMode: 420
@@ -332,18 +402,13 @@ spec:
         name: app-config
       {{- if $logDir }}
       - emptyDir: {}
-        name: component-log
-      - emptyDir: {}
-        name: filebeat-data
-      - configMap:
-          defaultMode: 420
-          name: {{ include "common.fullname" . }}-filebeat-configmap
-        name: filebeat-conf
+        name: logs
+      {{ include "common.log.volumes" (dict "dot" . "configMapNamePrefix" (tpl .Values.logConfigMapNamePrefix . )) | nindent 6 }}
       {{- end }}
       {{- if $certDir }}
       - emptyDir: {}
         name: tls-info
-        {{ if and .Values.certificates .Values.global.cmpv2Enabled .Values.global.CMPv2CertManagerIntegration -}}
+        {{ if (include "dcaegen2-services-common.shouldUseCmpv2Certificates" .) -}}
         {{ include "common.certManager.volumesReadOnly" . | nindent 6 }}
         {{- end }}
       {{- end }}
@@ -351,6 +416,8 @@ spec:
       - name: policy-shared
         emptyDir: {}
       {{- end }}
+      {{- include "common.dmaap.provisioning._volumes" . | nindent 6 -}}
+      {{- include "dcaegen2-services-common._externalVolumes" . | nindent 6 }}
       imagePullSecrets:
       - name: "{{ include "common.namespace" . }}-docker-registry-key"
 {{ end -}}
@@ -363,16 +430,16 @@ spec:
 */}}
 {{- define "dcaegen2-services-common._certPostProcessor" -}}
   {{- $certDir := default "" .Values.certDirectory . -}}
-  {{- if and $certDir .Values.certificates .Values.global.cmpv2Enabled .Values.global.CMPv2CertManagerIntegration -}}
+  {{- if (include "dcaegen2-services-common.shouldUseCmpv2Certificates" .) -}}
     {{- $cmpv2Certificate := (index .Values.certificates 0) -}}
     {{- $cmpv2CertificateDir := $cmpv2Certificate.mountPath -}}
     {{- $certType := "pem" -}}
     {{- if $cmpv2Certificate.keystore -}}
       {{- $certType = (index $cmpv2Certificate.keystore.outputType 0) -}}
     {{- end -}}
-    {{- $truststoresPaths := printf "%s/%s:%s/%s" $certDir "cacert.pem" $cmpv2CertificateDir "ca.crt" -}}
-    {{- $truststoresPasswordPaths := "" -}}
-    {{- $keystoreSourcePaths := printf "%s/%s:%s/%s" $cmpv2CertificateDir "tls.crt" $cmpv2CertificateDir "tls.key" -}}
+    {{- $truststoresPaths := printf "%s/%s:%s/%s" $certDir "cacert.pem" $cmpv2CertificateDir "cacert.pem" -}}
+    {{- $truststoresPasswordPaths := ":" -}}
+    {{- $keystoreSourcePaths := printf "%s/%s:%s/%s" $cmpv2CertificateDir "cert.pem" $cmpv2CertificateDir "key.pem" -}}
     {{- $keystoreDestinationPaths := printf "%s/%s:%s/%s" $certDir "cert.pem" $certDir "key.pem" -}}
     {{- if not (eq $certType "pem") -}}
       {{- $truststoresPaths = printf "%s/%s:%s/%s.%s" $certDir "trust.jks" $cmpv2CertificateDir "truststore" $certType -}}
@@ -400,3 +467,16 @@ spec:
       value: {{ $keystoreDestinationPaths | quote }}
   {{- end }}
 {{- end -}}
+
+{{/*
+  Template returns string "true" if CMPv2 certificates should be used and nothing (so it can be used in with statements)
+  when they shouldn't. Example use:
+    {{- if (include "dcaegen2-services-common.shouldUseCmpv2Certificates" .) -}}
+
+*/}}
+{{- define "dcaegen2-services-common.shouldUseCmpv2Certificates" -}}
+  {{- $certDir := default "" .Values.certDirectory . -}}
+  {{- if (and $certDir .Values.certificates .Values.global.cmpv2Enabled .Values.useCmpv2Certificates) -}}
+  true
+  {{- end -}}
+{{- end -}}