commit 08e6f3b07344d51e5cb02004a60c0dd84288246a
Author: Stefan Nica <snica@suse.com>
Date:   Tue Oct 13 17:50:45 2020 +0200

    Generate password for internal redis
    
    To harden the security for the internal redis service, a strong
    redis password is generated if one is not explicitly configured
    in values.yaml.
    
    This requires several helm chart changes to ensure that the
    password is not re-generated with every `helm upgrade`:
    * a k8s secret is used to store not only the redis password, but
    also all other redis connection URL variables that incorporate it
    * the template logic gives preference to the redis password value
    in values.yaml, if one is present. To avoid re-generating the
    password during `helm upgrade`, the previous password value is
    extracted from the existing secret, if present.
    * an annotation is added to all deployments and stateful-sets that
    reference the redis password or one of the connection URLs, to ensure
    they are redeployed if the password changes. The fact that the
    password is not re-generated with each `helm upgrade` reduces the
    set of impacted workload objects that need to be updated during
    an upgrade.
    * the redis URL used for the jobservice component is removed
    from the configmap and replaced with an environment variable
    * remove the redis password from the registry config map. It's
    already covered by an environment variable
    * using a named template to generate the random password for redis
    is not a good solution when the password is referenced from multiple
    places, because the template generates a different password each time
    it is invoked. For this reason, all redis related named templates
    (e.g. `harbor.redis.urlForCore`, `harbor.redis.urlForJobservice`)
    have been modified to expect the password to be supplied as a
    `.password` parameter.
    
    Signed-off-by: Stefan Nica <snica@suse.com>

diff --git a/README.md b/README.md
index 7ae2904..8f498de 100644
--- a/README.md
+++ b/README.md
@@ -314,7 +314,7 @@ The following table lists the configurable parameters of the Harbor chart and th
 | `redis.type` | If external redis is used, set it to `external` | `internal` |
 | `redis.internal.image.repository` | Repository for redis image | `goharbor/redis-photon` |
 | `redis.internal.image.tag` | Tag for redis image | `dev` |
-| `redis.internal.password` | The password for redis | `changeit` |
+| `redis.internal.password` | The password for internal redis. If a password is not specified, Helm will generate one.  | |
 | `redis.internal.resources` | The [resources] to allocate for container | undefined |
 | `redis.internal.nodeSelector` | Node labels for pod assignment | `{}` |
 | `redis.internal.tolerations` | Tolerations for pod assignment | `[]` |
diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl
index 4c39906..acecd72 100644
--- a/templates/_helpers.tpl
+++ b/templates/_helpers.tpl
@@ -165,23 +165,20 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab
   {{- end }}
 {{- end -}}
 
-{{- define "harbor.redis.password" -}}
-  {{- with .Values.redis }}
-    {{- ternary .internal.password .external.password (eq .type "internal") }}
-  {{- end }}
-{{- end -}}
-
-{{- define "harbor.redis.encryptedPassword" -}}
-  {{- include "harbor.redis.password" . | b64enc | quote -}}
+{{- define "harbor.redis.internalPassword" -}}
+  {{- $prevSecret := (lookup "v1" "Secret" .Release.Namespace (include "harbor.redis" $)) }}
+  {{- if $prevSecret -}}
+    {{- $prevSecret.data.REDIS_PASSWORD | b64dec }}
+  {{- else -}}
+    {{- randAlphaNum 16 }}
+  {{- end -}}
 {{- end -}}
 
 /*scheme://[redis:password@]host:port[/master_set]*/
 {{- define "harbor.redis.url" -}}
-  {{- with .Values.redis }}
-    {{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }}
-    {{- $cred := ternary (printf "redis:%s@" ((include "harbor.redis.password" $) | urlquery)) "" (not (not (include "harbor.redis.addr" $))) }}
-    {{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) $cred (include "harbor.redis.addr" $) $path -}}
-  {{- end }}
+  {{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }}
+  {{- $cred := ternary (printf "redis:%s@" (.redisPassword | urlquery)) "" (not (not (include "harbor.redis.addr" $))) }}
+  {{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) $cred (include "harbor.redis.addr" $) $path -}}
 {{- end -}}
 
 /*scheme://[redis:password@]addr/db_index?idle_timeout_seconds=30*/
diff --git a/templates/chartmuseum/chartmuseum-dpl.yaml b/templates/chartmuseum/chartmuseum-dpl.yaml
index dc0157f..7335fe5 100644
--- a/templates/chartmuseum/chartmuseum-dpl.yaml
+++ b/templates/chartmuseum/chartmuseum-dpl.yaml
@@ -26,6 +26,7 @@ spec:
         checksum/configmap: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-cm.yaml") . | sha256sum }}
         checksum/secret: {{ include (print $.Template.BasePath "/chartmuseum/chartmuseum-secret.yaml") . | sha256sum }}
         checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -98,6 +99,11 @@ spec:
           - # Needed to make AWS' client connect correctly (see https://github.com/helm/chartmuseum/issues/280)
             name: AWS_SDK_LOAD_CONFIG
             value: "1"
+          - name: CACHE_REDIS_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: {{ template "harbor.redis" . }}
+                key: REDIS_PASSWORD
         ports:
         - containerPort: {{ template "harbor.chartmuseum.containerPort" . }}
         volumeMounts:
diff --git a/templates/chartmuseum/chartmuseum-secret.yaml b/templates/chartmuseum/chartmuseum-secret.yaml
index eefdf79..e1330f0 100644
--- a/templates/chartmuseum/chartmuseum-secret.yaml
+++ b/templates/chartmuseum/chartmuseum-secret.yaml
@@ -7,7 +7,6 @@ metadata:
 {{ include "harbor.labels" . | indent 4 }}
 type: Opaque
 data:
-  CACHE_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }}
 {{- $storage := .Values.persistence.imageChartStorage }}
 {{- $storageType := $storage.type }}
 {{- if eq $storageType "azure" }}
diff --git a/templates/clair/clair-dpl.yaml b/templates/clair/clair-dpl.yaml
index 35005e8..b95b067 100644
--- a/templates/clair/clair-dpl.yaml
+++ b/templates/clair/clair-dpl.yaml
@@ -19,6 +19,7 @@ spec:
         component: clair
       annotations:
         checksum/secret: {{ include (print $.Template.BasePath "/clair/clair-secret.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -103,14 +104,14 @@ spec:
           value: "http://127.0.0.1:6060"
         - name: SCANNER_STORE_REDIS_URL
           valueFrom:
-              secretKeyRef:
-                name: {{ template "harbor.clair" . }}
-                key: redis
+            secretKeyRef:
+              name: {{ template "harbor.redis" . }}
+              key: REDIS_URL_CLAIR
         - name: SCANNER_CLAIR_DATABASE_URL
           valueFrom:
-              secretKeyRef:
-                name: {{ template "harbor.clair" . }}
-                key: database
+            secretKeyRef:
+              name: {{ template "harbor.clair" . }}
+              key: database
         {{- if .Values.internalTLS.enabled }}
         - name: INTERNAL_TLS_ENABLED
           value: "true"
diff --git a/templates/clair/clair-secret.yaml b/templates/clair/clair-secret.yaml
index fa6e5dc..6b0bda5 100644
--- a/templates/clair/clair-secret.yaml
+++ b/templates/clair/clair-secret.yaml
@@ -8,6 +8,5 @@ metadata:
 type: Opaque
 data:
   config.yaml: {{ tpl (.Files.Get "conf/clair.yaml") . | b64enc }}
-  redis: {{ include "harbor.redis.urlForClair" . | b64enc }}
   database: {{ include "harbor.database.clair" . | b64enc }}
 {{- end }} 
\ No newline at end of file
diff --git a/templates/core/core-cm.yaml b/templates/core/core-cm.yaml
index d339ee2..c8536e7 100644
--- a/templates/core/core-cm.yaml
+++ b/templates/core/core-cm.yaml
@@ -39,8 +39,6 @@ data:
   LOG_LEVEL: "{{ .Values.logLevel }}"
   CONFIG_PATH: "/etc/core/app.conf"
   CHART_CACHE_DRIVER: "redis"
-  _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}"
-  _REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}"
   PORTAL_URL: "{{ template "harbor.portalURL" . }}"
   REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}"
   REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}"
diff --git a/templates/core/core-dpl.yaml b/templates/core/core-dpl.yaml
index 10002f1..13981f9 100644
--- a/templates/core/core-dpl.yaml
+++ b/templates/core/core-dpl.yaml
@@ -20,6 +20,7 @@ spec:
         checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }}
         checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
         checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -80,6 +81,16 @@ spec:
               secretKeyRef:
                 name: "{{ template "harbor.jobservice" . }}"
                 key: JOBSERVICE_SECRET
+          - name: _REDIS_URL_CORE
+            valueFrom:
+              secretKeyRef:
+                name: "{{ template "harbor.redis" . }}"
+                key: REDIS_URL_CORE
+          - name: _REDIS_URL_REG
+            valueFrom:
+              secretKeyRef:
+                name: "{{ template "harbor.redis" . }}"
+                key: REDIS_URL_REGISTRY
          {{- if .Values.internalTLS.enabled }}
           - name: INTERNAL_TLS_ENABLED
             value: "true"
diff --git a/templates/jobservice/jobservice-cm.yaml b/templates/jobservice/jobservice-cm.yaml
index f9eb51b..0fccdf6 100644
--- a/templates/jobservice/jobservice-cm.yaml
+++ b/templates/jobservice/jobservice-cm.yaml
@@ -18,7 +18,6 @@ data:
       workers: {{ .Values.jobservice.maxJobWorkers }}
       backend: "redis"
       redis_pool:
-        redis_url: "{{ template "harbor.redis.urlForJobservice" . }}"
         namespace: "harbor_job_service_namespace"
         idle_timeout_second: 3600
     job_loggers:
diff --git a/templates/jobservice/jobservice-dpl.yaml b/templates/jobservice/jobservice-dpl.yaml
index cafc6fb..c1bba2b 100644
--- a/templates/jobservice/jobservice-dpl.yaml
+++ b/templates/jobservice/jobservice-dpl.yaml
@@ -26,6 +26,7 @@ spec:
         checksum/configmap-env: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm-env.yaml") . | sha256sum }}
         checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
         checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -72,6 +73,11 @@ spec:
               secretKeyRef:
                 name: {{ template "harbor.core" . }}
                 key: secret
+          - name: JOB_SERVICE_POOL_REDIS_URL
+            valueFrom:
+              secretKeyRef:
+                name: {{ template "harbor.redis" . }}
+                key: REDIS_URL_JOBSERVICE
           {{- if .Values.internalTLS.enabled }}
           - name: INTERNAL_TLS_ENABLED
             value: "true"
diff --git a/templates/redis/secret.yaml b/templates/redis/secret.yaml
index 5fcc49b..9812502 100644
--- a/templates/redis/secret.yaml
+++ b/templates/redis/secret.yaml
@@ -1,11 +1,18 @@
-{{- if eq .Values.redis.type "internal" -}}
+{{- $secret := include "harbor.redis" . }}
 apiVersion: v1
 kind: Secret
 metadata:
-  name: "{{ template "harbor.redis" . }}"
+  name: "{{ $secret }}"
   labels:
 {{ include "harbor.labels" . | indent 4 }}
 type: Opaque
 data:
-  REDIS_PASSWORD: {{ template "harbor.redis.encryptedPassword" . }}
-{{- end -}}
+{{- $internalPassword := .Values.redis.internal.password | default (include "harbor.redis.internalPassword" .) }}
+{{- $password := ternary $internalPassword .Values.redis.external.password (eq .Values.redis.type "internal") }}
+{{- $passwordCtx := (merge (dict "redisPassword" $password) .) }}
+  REDIS_PASSWORD: {{ $password | b64enc | quote }}
+  REDIS_URL_CORE: {{ include "harbor.redis.urlForCore" $passwordCtx | b64enc }}
+  REDIS_URL_JOBSERVICE: {{ include "harbor.redis.urlForJobservice" $passwordCtx | b64enc }}
+  REDIS_URL_REGISTRY: {{ include "harbor.redis.urlForRegistry" $passwordCtx | b64enc }}
+  REDIS_URL_CLAIR: {{ include "harbor.redis.urlForClair" $passwordCtx | b64enc }}
+  REDIS_URL_TRIVY: {{ include "harbor.redis.urlForTrivy" $passwordCtx | b64enc }}
\ No newline at end of file
diff --git a/templates/redis/statefulset.yaml b/templates/redis/statefulset.yaml
index 6a952b1..8f51dc4 100644
--- a/templates/redis/statefulset.yaml
+++ b/templates/redis/statefulset.yaml
@@ -52,9 +52,12 @@ spec:
         resources:
 {{ toYaml .Values.redis.internal.resources | indent 10 }}
 {{- end }}
-        envFrom:
-          - secretRef:
-              name: "{{ template "harbor.redis" . }}"
+        env:
+          - name: REDIS_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: "{{ template "harbor.redis" . }}"
+                key: REDIS_PASSWORD
         volumeMounts:
         - name: data
           mountPath: /var/lib/redis
diff --git a/templates/registry/registry-cm.yaml b/templates/registry/registry-cm.yaml
index 9a12c07..8c92433 100644
--- a/templates/registry/registry-cm.yaml
+++ b/templates/registry/registry-cm.yaml
@@ -166,7 +166,6 @@ data:
       sentinelMasterSet: {{ template "harbor.redis.masterSet" . }}
       {{- end }}
       db: {{ template "harbor.redis.dbForRegistry" . }}
-      password: {{ template "harbor.redis.password" . }}
       readtimeout: 10s
       writetimeout: 10s
       dialtimeout: 10s
diff --git a/templates/registry/registry-dpl.yaml b/templates/registry/registry-dpl.yaml
index 24b6b60..a620470 100644
--- a/templates/registry/registry-dpl.yaml
+++ b/templates/registry/registry-dpl.yaml
@@ -26,6 +26,7 @@ spec:
         checksum/secret: {{ include (print $.Template.BasePath "/registry/registry-secret.yaml") . | sha256sum }}
         checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }}
         checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -89,6 +90,11 @@ spec:
         - name: INTERNAL_TLS_TRUST_CA_PATH
           value: /etc/harbor/ssl/registry/ca.crt
         {{- end }}
+        - name: REGISTRY_REDIS_PASSWORD
+          valueFrom:
+            secretKeyRef:
+              name: {{ template "harbor.redis" . }}
+              key: REDIS_PASSWORD
         ports:
         - containerPort: {{ template "harbor.registry.containerPort" . }}
         - containerPort: 5001
diff --git a/templates/registry/registry-secret.yaml b/templates/registry/registry-secret.yaml
index 96ad7b9..f49bd17 100644
--- a/templates/registry/registry-secret.yaml
+++ b/templates/registry/registry-secret.yaml
@@ -8,7 +8,6 @@ type: Opaque
 data:
   REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswd | b64enc | quote }}
   REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }}
-  REGISTRY_REDIS_PASSWORD: {{ (include "harbor.redis.password" .) | b64enc | quote }}
   {{- $storage := .Values.persistence.imageChartStorage }}
   {{- $type := $storage.type }}
   {{- if eq $type "azure" }}
diff --git a/templates/trivy/trivy-secret.yaml b/templates/trivy/trivy-secret.yaml
index 84652c7..9c756df 100644
--- a/templates/trivy/trivy-secret.yaml
+++ b/templates/trivy/trivy-secret.yaml
@@ -7,6 +7,5 @@ metadata:
 {{ include "harbor.labels" . | indent 4 }}
 type: Opaque
 data:
-  redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }}
   gitHubToken: {{  .Values.trivy.gitHubToken | default "" | b64enc | quote }}
 {{- end }}
diff --git a/templates/trivy/trivy-sts.yaml b/templates/trivy/trivy-sts.yaml
index 9e8e08a..ede4298 100644
--- a/templates/trivy/trivy-sts.yaml
+++ b/templates/trivy/trivy-sts.yaml
@@ -21,6 +21,7 @@ spec:
         component: trivy
       annotations:
         checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-secret.yaml") . | sha256sum }}
+        checksum/secret-redis: {{ include (print $.Template.BasePath "/redis/secret.yaml") . | sha256sum }}
 {{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }}
         checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }}
 {{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }}
@@ -94,18 +95,18 @@ spec:
             - name: "SCANNER_REDIS_URL"
               valueFrom:
                 secretKeyRef:
-                  name: {{ template "harbor.trivy" . }}
-                  key: redisURL
+                  name: {{ template "harbor.redis" . }}
+                  key: REDIS_URL_TRIVY
             - name: "SCANNER_STORE_REDIS_URL"
               valueFrom:
                 secretKeyRef:
-                  name: {{ template "harbor.trivy" . }}
-                  key: redisURL
+                  name: {{ template "harbor.redis" . }}
+                  key: REDIS_URL_TRIVY
             - name: "SCANNER_JOB_QUEUE_REDIS_URL"
               valueFrom:
                 secretKeyRef:
-                  name: {{ template "harbor.trivy" . }}
-                  key: redisURL
+                  name: {{ template "harbor.redis" . }}
+                  key: REDIS_URL_TRIVY
           ports:
             - name: api-server
               containerPort: {{ template "harbor.trivy.containerPort" . }}
diff --git a/values.yaml b/values.yaml
index bc0554d..e6d8ccc 100644
--- a/values.yaml
+++ b/values.yaml
@@ -717,7 +717,8 @@ redis:
       repository: goharbor/redis-photon
       tag: v2.1.2
     # The password for internal redis.
-    password: "changeit"
+    # If a password is not specified, Helm will generate one.
+    password: ""
     # resources:
     #  requests:
     #    memory: 256Mi
