Repository: fluxcd/flux
Pull request #2738 (2020-01-13 12:52:04)

Release Flux 1.17.1


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 751f4b6c..fb3db83c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,21 @@
+## 1.17.1 (2020-01-13)
+
+This is a minor security patch release fixing a problem with the scoping
+of `imagePullSecret`s and removing git-URL HTTPS credentials server-side.
+
+### Fixes
+
+- Correctly scope imagePullSecrets by their namespace [fluxcd/flux#2728][]
+- Sanitize Git remote URLs on the server side [fluxcd/flux#2726][]
+
+### Thanks
+
+Thanks to @2opremio, @hiddeco and @bootc for contributing to this release.
+
+
+[fluxcd/flux#2726]: https://github.com/fluxcd/flux/pull/2726
+[fluxcd/flux#2728]: https://github.com/fluxcd/flux/pull/2728
+
 ## 1.17.0 (2019-12-16)
 
 This feature release adds support for encrypted manifests with
@@ -16,7 +34,7 @@ Instead, make sure to output cleartext manifests by explicitly invoking the
 This release also adds the new `fluxd` flag `--k8s-default-namespace`
 which overrides the namespace used for manifests which omit it.
 
-### Enhacements
+### Enhancements
 
 - Add support for SOPS [fluxcd/flux#2580][]
 - Add `--k8s-default-namespace` flag to override default namespace
@@ -113,7 +131,7 @@ numerous new end-to-end tests have been added.
 - Ignore timestamp labels during sorting and release of images [fluxcd/flux#2594][]
 - Security: Stop showing value of `GIT_AUTHKEY` in the `fluxctl` output [fluxcd/flux#2549][]
 
-### Enhacements
+### Enhancements
 
 - Improve experience with `.flux.yaml` files
   fluxcd/flux#{[2565][fluxcd/flux#2565], [2603][fluxcd/flux#2603],
diff --git a/chart/flux/CHANGELOG.md b/chart/flux/CHANGELOG.md
index 205fb44f..a3ad48ac 100644
--- a/chart/flux/CHANGELOG.md
+++ b/chart/flux/CHANGELOG.md
@@ -1,3 +1,21 @@
+## 1.0.0 (2019-12-16)
+
+**Note** The Helm Operator manifests have been **removed** from this chart.
+Please see the [install instruction](https://github.com/fluxcd/helm-operator/tree/master/chart/helm-operator)
+for Helm Operator v1.0.0. To keep using the same SSH key as Flux see the docs
+[here](https://github.com/fluxcd/helm-operator/tree/master/chart/helm-operator#use-fluxs-git-deploy-key).
+The upgrade procedure for `HelmReleases` from `v1beta1` to `v1` can be found
+[here](https://docs.fluxcd.io/projects/helm-operator/en/latest/guides/upgrading-to-ga.html).
+
+### Improvements
+
+ - Updated Flux to `1.17.0`
+   [fluxcd/flux#2693](https://github.com/fluxcd/flux/pull/2693)
+ - Add a ServiceMonitor template
+   [fluxcd/flux#2668](https://github.com/fluxcd/flux/pull/2668)
+ - Update the automation interval flag in the chart
+   [fluxcd/flux#2551](https://github.com/fluxcd/flux/pull/2551)
+
 ## 0.16.0 (2019-11-28)
 
 ### Improvements
diff --git a/chart/flux/Chart.yaml b/chart/flux/Chart.yaml
index 7034b771..69724df9 100644
--- a/chart/flux/Chart.yaml
+++ b/chart/flux/Chart.yaml
@@ -1,6 +1,6 @@
 apiVersion: v1
-appVersion: "1.16.0"
-version: 0.16.0
+appVersion: "1.17.0"
+version: 1.0.0
 kubeVersion: ">=1.9.0-0"
 name: flux
 description: Flux is a tool that automatically ensures that the state of a cluster matches what is specified in version control
diff --git a/chart/flux/templates/flux-helm-repositories.yaml b/chart/flux/templates/flux-helm-repositories.yaml
deleted file mode 100644
index ea62abc5..00000000
--- a/chart/flux/templates/flux-helm-repositories.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-{{- if .Values.helmOperator.configureRepositories.repositories -}}
-apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ .Values.helmOperator.configureRepositories.secretName }}
-type: Opaque
-data:
-  repositories.yaml: {{ include "flux.customRepositories" . | b64enc }}
-{{- end -}}
diff --git a/chart/flux/templates/helm-operator-crd.yaml b/chart/flux/templates/helm-operator-crd.yaml
deleted file mode 100644
index 8497d435..00000000
--- a/chart/flux/templates/helm-operator-crd.yaml
+++ /dev/null
@@ -1,149 +0,0 @@
-{{- if and .Values.helmOperator.create .Values.helmOperator.createCRD -}}
----
-apiVersion: apiextensions.k8s.io/v1beta1
-kind: CustomResourceDefinition
-metadata:
-  name: helmreleases.flux.weave.works
-  labels:
-    app: {{ template "flux.name" . }}
-    chart: {{ template "flux.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-  annotations:
-    "helm.sh/resource-policy": keep
-spec:
-  group: flux.weave.works
-  names:
-    kind: HelmRelease
-    listKind: HelmReleaseList
-    plural: helmreleases
-    shortNames:
-    - hr
-  scope: Namespaced
-  subresources:
-    status: {}
-  version: v1beta1
-  versions:
-    - name: v1beta1
-      served: true
-      storage: true
-  validation:
-    openAPIV3Schema:
-      properties:
-        spec:
-          required: ['chart']
-          properties:
-            releaseName:
-              type: string
-              pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
-            targetNamespace:
-              type: string
-              pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"
-            timeout:
-              type: integer
-              format: int64
-            resetValues:
-              type: boolean
-            forceUpgrade:
-              type: boolean
-            rollback:
-              type: object
-              properties:
-                enable:
-                  type: boolean
-                force:
-                  type: boolean
-                recreate:
-                  type: boolean
-                disableHooks:
-                  type: boolean
-                timeout:
-                  type: integer
-                  format: int64
-                wait:
-                  type: boolean
-            valueFileSecrets:
-              type: array
-              items:
-                type: object
-                required: ['name']
-                properties:
-                  name:
-                    type: string
-            valuesFrom:
-              type: array
-              items:
-                type: object
-                properties:
-                  configMapKeyRef:
-                    type: object
-                    required: ['name']
-                    properties:
-                      name:
-                        type: string
-                      key:
-                        type: string
-                      optional:
-                        type: boolean
-                  secretKeyRef:
-                    type: object
-                    required: ['name']
-                    properties:
-                      name:
-                        type: string
-                      key:
-                        type: string
-                      optional:
-                        type: boolean
-                  externalSourceRef:
-                    type: object
-                    required: ['url']
-                    properties:
-                      url:
-                        type: string
-                      optional:
-                        type: boolean
-                  chartFileRef:
-                    type: object
-                    required: ['path']
-                    properties:
-                      path:
-                        type: string
-                      optional:
-                        type: boolean
-                oneOf:
-                - required: ['configMapKeyRef']
-                - required: ['secretKeyRef']
-                - required: ['externalSourceRef']
-                - required: ['chartFileRef']
-            values:
-              type: object
-            chart:
-              oneOf:
-              - required: ['git', 'path']
-                properties:
-                  git:
-                    type: string
-                    format: git # not defined by OAS
-                  path:
-                    type: string
-                  ref:
-                    type: string
-                  skipDepUpdate:
-                    type: boolean
-              - required: ['repository', 'name', 'version']
-                properties:
-                  repository:
-                    type: string
-                    format: url # not defined by OAS
-                  name:
-                    type: string
-                  version:
-                    type: string
-                    format: semver # not defined by OAS
-                  chartPullSecret:
-                    properties:
-                      name:
-                        type: string
-{{- end -}}
-
diff --git a/chart/flux/templates/helm-operator-deployment.yaml b/chart/flux/templates/helm-operator-deployment.yaml
deleted file mode 100644
index e297759f..00000000
--- a/chart/flux/templates/helm-operator-deployment.yaml
+++ /dev/null
@@ -1,173 +0,0 @@
-{{- $gitTimeout := default .Values.git.timeout .Values.helmOperator.git.timeout }}
-{{- $gitPollInterval := default .Values.git.pollInterval .Values.helmOperator.git.pollInterval }}
-{{- if .Values.helmOperator.create -}}
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: {{ template "flux.fullname" . }}-helm-operator
-  labels:
-    app: {{ template "flux.name" . }}-helm-operator
-    chart: {{ template "flux.chart" . }}
-    release: {{ .Release.Name }}
-    heritage: {{ .Release.Service }}
-spec:
-  replicas: {{ .Values.helmOperator.replicaCount }}
-  selector:
-    matchLabels:
-      app: {{ template "flux.name" . }}-helm-operator
-      release: {{ .Release.Name }}
-  template:
-    metadata:
-      annotations:
-      {{- if .Values.prometheus.enabled }}
-        prometheus.io/scrape: "true"
-      {{- end }}
-      {{- if .Values.helmOperator.annotations }}
-      {{- .Values.helmOperator.annotations | toYaml | trimSuffix "\n" | nindent 8 }}
-      {{- end }}
-      labels:
-        app: {{ template "flux.name" . }}-helm-operator
-        release: {{ .Release.Name }}
-    spec:
-      serviceAccountName: {{ template "flux.serviceAccountName" . }}
-      {{- if .Values.helmOperator.pullSecret }}
-      imagePullSecrets:
-        - name: {{ .Values.helmOperator.pullSecret }}
-      {{- end }}
-      volumes:
-      {{- if .Values.ssh.known_hosts }}
-      - name: sshdir
-        configMap:
-          name: {{ template "flux.fullname" . }}-ssh-config
-          defaultMode: 0600
-      {{- end }}
-      {{- if .Values.git.config.enabled }}
-      - name: git-config
-        secret:
-          secretName: {{ include "git.config.secretName" . }}
-          defaultMode: 0400
-      {{- end }}
-      - name: git-key
-        secret:
-          {{- if .Values.helmOperator.git.secretName }}
-          secretName: {{ .Values.helmOperator.git.secretName }}
-          {{- else if .Values.git.secretName }}
-          secretName: {{ .Values.git.secretName }}
-          {{- else }}
-          secretName: {{ template "flux.fullname" . }}-git-deploy
-          {{- end }}
-          defaultMode: 0400
-      {{- if .Values.helmOperator.tls.enable }}
-      - name: helm-tls-certs
-        secret:
-          secretName: {{ .Values.helmOperator.tls.secretName }}
-          defaultMode: 0400
-      {{- if .Values.helmOperator.tls.verify }}
-      - name: helm-tls-ca
-        configMap:
-          name: {{ template "flux.fullname" . }}-helm-tls-ca-config
-          defaultMode: 0600
-      {{- end }}
-      {{- end }}
-      {{- if .Values.helmOperator.configureRepositories.enable }}
-      - name: {{ .Values.helmOperator.configureRepositories.volumeName | quote }}
-        secret:
-          secretName: {{ .Values.helmOperator.configureRepositories.secretName | quote }}
-      - name: {{ .Values.helmOperator.configureRepositories.cacheVolumeName | quote }}
-        emptyDir: {}
-      {{- end }}
-      containers:
-      - name: flux-helm-operator
-        image: "{{ .Values.helmOperator.repository }}:{{ .Values.helmOperator.tag }}"
-        imagePullPolicy: {{ .Values.helmOperator.pullPolicy }}
-        ports:
-        - name: http
-          containerPort: 3030
-        volumeMounts:
-        {{- if .Values.ssh.known_hosts }}
-        - name: sshdir
-          mountPath: /root/.ssh/known_hosts
-          subPath: known_hosts
-          readOnly: true
-        {{- end }}
-        {{- if .Values.git.config.enabled }}
-        - name: git-config
-          mountPath: /root/.gitconfig
-          subPath: gitconfig
-          readOnly: true
-        {{- end }}
-        - name: git-key
-          mountPath: /etc/fluxd/ssh
-          readOnly: true
-        {{- if .Values.helmOperator.tls.enable }}
-        - name: helm-tls-certs
-          mountPath: /etc/fluxd/helm
-          readOnly: true
-        {{- if .Values.helmOperator.tls.verify }}
-        - name: helm-tls-ca
-          mountPath: /etc/fluxd/helm-ca
-          readOnly: true
-        {{- end }}
-        {{- end }}
-        {{- if .Values.helmOperator.configureRepositories.enable }}
-        - name: {{ .Values.helmOperator.configureRepositories.volumeName | quote }}
-          mountPath: /var/fluxd/helm/repository/repositories.yaml
-          subPath: repositories.yaml
-          readOnly: true
-        - name: {{ .Values.helmOperator.configureRepositories.cacheVolumeName | quote }}
-          mountPath: /var/fluxd/helm/repository/cache
-        {{- end }}
-        args:
-        {{- if .Values.logFormat }}
-        - --log-format={{ .Values.logFormat }}
-        {{end}}
-        - --git-timeout={{ $gitTimeout }}
-        - --git-poll-interval={{ $gitPollInterval }}
-        - --charts-sync-interval={{ .Values.helmOperator.chartsSyncInterval }}
-        - --update-chart-deps={{ .Values.helmOperator.updateChartDeps }}
-        - --log-release-diffs={{ .Values.helmOperator.logReleaseDiffs }}
-        {{- if .Values.helmOperator.workers }}
-        - --workers={{ .Values.helmOperator.workers }}
-        {{- end }}
-        {{- if not .Values.clusterRole.create }}
-        - --allow-namespace={{ .Release.Namespace }}
-        {{- else if .Values.helmOperator.allowNamespace }}
-        - --allow-namespace={{ .Values.helmOperator.allowNamespace }}
-        {{- end }}
-        {{- if .Values.helmOperator.tillerHost }}
-        - --tiller-ip={{ .Values.helmOperator.tillerHost }}
-        - --tiller-port={{ .Values.helmOperator.tillerPort }}
-        {{- else }}
-        - --tiller-namespace={{ .Values.helmOperator.tillerNamespace }}
-        {{- end }}
-        {{- if .Values.helmOperator.tls.enable }}
-        - --tiller-tls-enable={{ .Values.helmOperator.tls.enable }}
-        - --tiller-tls-key-path=/etc/fluxd/helm/{{ .Values.helmOperator.tls.keyFile }}
-        - --tiller-tls-cert-path=/etc/fluxd/helm/{{ .Values.helmOperator.tls.certFile }}
-        {{- if .Values.helmOperator.tls.verify }}
-        - --tiller-tls-verify={{ .Values.helmOperator.tls.verify }}
-        - --tiller-tls-ca-cert-path=/etc/fluxd/helm-ca/ca.crt
-        {{- if .Values.helmOperator.tls.hostname }}
-        - --tiller-tls-hostname={{ .Values.helmOperator.tls.hostname }}
-        {{- end }}
-        {{- end }}
-        {{- end }}
-      {{- if .Values.helmOperator.extraEnvs }}
-        env:
-{{ toYaml .Values.helmOperator.extraEnvs | indent 8 }}
-      {{- end }}
-        resources:
-{{ toYaml .Values.helmOperator.resources | indent 10 }}
-      {{- with .Values.helmOperator.nodeSelector }}
-      nodeSelector:
-{{ toYaml . | indent 8 }}
-      {{- end }}
-      {{- with .Values.helmOperator.affinity }}
-      affinity:
-{{ toYaml . | indent 8 }}
-      {{- end }}
-      {{- with .Values.helmOperator.tolerations }}
-      tolerations:
-{{ toYaml . | indent 8 }}
-      {{- end }}
-{{- end -}}
diff --git a/chart/flux/templates/helm-tls.yaml b/chart/flux/templates/helm-tls.yaml
deleted file mode 100644
index eb946f39..00000000
--- a/chart/flux/templates/helm-tls.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-{{- if and .Values.helmOperator.tls.enable .Values.helmOperator.tls.verify .Values.helmOperator.tls.caContent -}}
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ template "flux.fullname" . }}-helm-tls-ca-config
-data:
-  ca.crt: |
-{{ .Values.helmOperator.tls.caContent | indent 4 }}
-{{- end -}}
diff --git a/chart/flux/values.yaml b/chart/flux/values.yaml
index dec84d92..3b7956fe 100644
--- a/chart/flux/values.yaml
+++ b/chart/flux/values.yaml
@@ -9,7 +9,7 @@ logFormat: fmt
 
 image:
   repository: docker.io/fluxcd/flux
-  tag: 1.16.0
+  tag: 1.17.0
   pullPolicy: IfNotPresent
   pullSecret:
 
@@ -17,77 +17,6 @@ service:
   type: ClusterIP
   port: 3030
 
-helmOperator:
-  replicaCount: 1
-  create: false
-  createCRD: false
-  repository: docker.io/fluxcd/helm-operator
-  tag: 0.10.1
-  pullPolicy: IfNotPresent
-  pullSecret:
-  # Limit the operator scope to a single namespace
-  allowNamespace:
-  # Update dependencies for charts
-  updateChartDeps: true
-  # Log the diff when a chart release diverges
-  logReleaseDiffs: false
-  # Interval at which to check for changed charts
-  chartsSyncInterval: "3m"
-  # (Experimental) amount of workers processing releases
-  workers:
-
-  # Tiller settings
-
-  # If a hostname or IP is given here, that will be combined with the
-  # tillerPort and used for connecting to Tiller. Otherwise, the
-  # cluster-ip of the `tiller-deploy` service in .tillerNamespace is
-  # looked up.
-  tillerHost:
-  tillerPort: 44134
-  tillerNamespace: kube-system
-  tls:
-    secretName: "helm-client-certs"
-    verify: false
-    enable: false
-    keyFile: "tls.key"
-    certFile: "tls.crt"
-    caContent: ""
-    hostname: ""
-  # Mount repositories.yaml configuration in a volume
-  configureRepositories:
-    enable: false
-    volumeName: repositories-yaml
-    secretName: flux-helm-repositories
-    cacheVolumeName: repositories-cache
-    repositories:
-      # - name: bitnami
-      #   url: https://charts.bitnami.com
-      #   username:
-      #   password:
-  # Override Flux git settings
-  git:
-    pollInterval: ""
-    timeout: ""
-    # generate a SSH key named identity: ssh-keygen -q -N "" -f ./identity
-    # create a Kubernetes secret: kubectl -n flux create secret generic helm-ssh --from-file=./identity
-    # delete the private key: rm ./identity
-    # add ./identity.pub as a read-only deployment key in your Git repo where the charts are
-    # set the secret name (helm-ssh) below
-    secretName: ""
-  # Additional environment variables to set
-  extraEnvs: []
-  # extraEnvs:
-  #   - name: FOO
-  #     value: bar
-  nodeSelector: {}
-  annotations: {}
-  tolerations: []
-  affinity: {}
-  resources:
-    requests:
-      cpu: 50m
-      memory: 64Mi
-
 rbac:
   # Specifies whether RBAC resources should be created
   create: true
diff --git a/cmd/fluxctl/sync_cmd.go b/cmd/fluxctl/sync_cmd.go
index f01e6368..c3d3880f 100644
--- a/cmd/fluxctl/sync_cmd.go
+++ b/cmd/fluxctl/sync_cmd.go
@@ -46,10 +46,10 @@ func (opts *syncOpts) RunE(cmd *cobra.Command, args []string) error {
 	case git.RepoReady:
 		break
 	default:
-		return fmt.Errorf("git repository %s is not ready to sync (status: %s)", gitConfig.Remote.SafeURL(), string(gitConfig.Status))
+		return fmt.Errorf("git repository %s is not ready to sync (status: %s)", gitConfig.Remote.URL, string(gitConfig.Status))
 	}
 
-	fmt.Fprintf(cmd.OutOrStderr(), "Synchronizing with %s\n", gitConfig.Remote.SafeURL())
+	fmt.Fprintf(cmd.OutOrStderr(), "Synchronizing with %s\n", gitConfig.Remote.URL)
 
 	updateSpec := update.Spec{
 		Type: update.Sync,
diff --git a/deploy/flux-deployment.yaml b/deploy/flux-deployment.yaml
index 5325535e..8b3a0dff 100644
--- a/deploy/flux-deployment.yaml
+++ b/deploy/flux-deployment.yaml
@@ -64,7 +64,7 @@ spec:
         # There are no ":latest" images for flux. Find the most recent
         # release or image version at https://hub.docker.com/r/fluxcd/flux/tags
         # and replace the tag here.
-        image: docker.io/fluxcd/flux:1.17.0
+        image: docker.io/fluxcd/flux:1.17.1
         imagePullPolicy: IfNotPresent
         resources:
           requests:
diff --git a/docs/tutorials/get-started-helm.md b/docs/tutorials/get-started-helm.md
index efbd48c2..20870223 100644
--- a/docs/tutorials/get-started-helm.md
+++ b/docs/tutorials/get-started-helm.md
@@ -58,7 +58,7 @@ helm repo add fluxcd https://charts.fluxcd.io
 Apply the Helm Release CRD:
 
 ```sh
-kubectl apply -f https://raw.githubusercontent.com/fluxcd/flux/helm-0.10.1/deploy-helm/flux-helm-release-crd.yaml
+kubectl apply -f https://raw.githubusercontent.com/fluxcd/helm-operator/master/deploy/flux-helm-release-crd.yaml
 ```
 
 In this next step you install Flux using `helm`. Simply
@@ -75,11 +75,14 @@ In this next step you install Flux using `helm`. Simply
 
       ```sh
       helm upgrade -i flux \
-      --set helmOperator.create=true \
-      --set helmOperator.createCRD=false \
       --set git.url=git@github.com:YOURUSER/flux-get-started \
       --namespace flux \
       fluxcd/flux
+      
+      helm upgrade -i helm-operator \
+      --set git.ssh.secretName=flux-git-deploy \
+      --namespace flux \
+      fluxcd/helm-operator
       ```
 
     - Using a private git server:
diff --git a/internal/cmd/changelog/main.go b/internal/cmd/changelog/main.go
index dd4e5d24..f83026bf 100644
--- a/internal/cmd/changelog/main.go
+++ b/internal/cmd/changelog/main.go
@@ -196,7 +196,7 @@ func main() {
 	gitHubOrg := pflag.String("gh-org", "fluxcd", "GitHub organization of the repository for which to generate the changelog entry")
 	gitHubRepo := pflag.String("gh-repo", "flux", "GitHub repository for which to generate the changelog entry")
 	excludeLabelStrings := pflag.StringSlice("exclude-labels", []string{"helm-chart"}, "Exclude pull requests tagged with any of these labels")
-	sectionSpecStrings := pflag.StringSlice("section-spec", []string{"bug:Fixes", "enhacement:Enhacement", "docs:Documentation"}, "`label:Title` section specifications. `label:Title` indicates to create a section with `Title` in which to include all the pull requests tagged with label `label`")
+	sectionSpecStrings := pflag.StringSlice("section-spec", []string{"bug:Fixes", "enhacement:Enhancements", "docs:Documentation"}, "`label:Title` section specifications. `label:Title` indicates to create a section with `Title` in which to include all the pull requests tagged with label `label`")
 	pflag.Parse()
 
 	token := os.Getenv("GITHUB_TOKEN")
diff --git a/pkg/cluster/kubernetes/images.go b/pkg/cluster/kubernetes/images.go
index 1da1a55c..60eb4229 100644
--- a/pkg/cluster/kubernetes/images.go
+++ b/pkg/cluster/kubernetes/images.go
@@ -21,7 +21,7 @@ func mergeCredentials(log func(...interface{}) error,
 	client ExtendedClient,
 	namespace string, podTemplate apiv1.PodTemplateSpec,
 	imageCreds registry.ImageCreds,
-	seenCreds map[string]registry.Credentials) {
+	imagePullSecretCache map[string]registry.Credentials) {
 	var images []image.Name
 	for _, container := range podTemplate.Spec.InitContainers {
 		r, err := image.ParseRef(container.Image)
@@ -68,7 +68,8 @@ func mergeCredentials(log func(...interface{}) error,
 	}
 
 	for _, name := range imagePullSecrets {
-		if seen, ok := seenCreds[name]; ok {
+		namespacedSecretName := fmt.Sprintf("%s/%s", namespace, name)
+		if seen, ok := imagePullSecretCache[namespacedSecretName]; ok {
 			creds.Merge(seen)
 			continue
 		}
@@ -76,7 +77,7 @@ func mergeCredentials(log func(...interface{}) error,
 		secret, err := client.CoreV1().Secrets(namespace).Get(name, meta_v1.GetOptions{})
 		if err != nil {
 			log("err", errors.Wrapf(err, "getting secret %q from namespace %q", name, namespace))
-			seenCreds[name] = registry.NoCredentials()
+			imagePullSecretCache[namespacedSecretName] = registry.NoCredentials()
 			continue
 		}
 
@@ -91,13 +92,13 @@ func mergeCredentials(log func(...interface{}) error,
 			decoded, ok = secret.Data[apiv1.DockerConfigJsonKey]
 		default:
 			log("skip", "unknown type", "secret", namespace+"/"+secret.Name, "type", secret.Type)
-			seenCreds[name] = registry.NoCredentials()
+			imagePullSecretCache[namespacedSecretName] = registry.NoCredentials()
 			continue
 		}
 
 		if !ok {
 			log("err", errors.Wrapf(err, "retrieving pod secret %q", secret.Name))
-			seenCreds[name] = registry.NoCredentials()
+			imagePullSecretCache[namespacedSecretName] = registry.NoCredentials()
 			continue
 		}
 
@@ -105,10 +106,10 @@ func mergeCredentials(log func(...interface{}) error,
 		crd, err := registry.ParseCredentials(fmt.Sprintf("%s:secret/%s", namespace, name), decoded)
 		if err != nil {
 			log("err", err.Error())
-			seenCreds[name] = registry.NoCredentials()
+			imagePullSecretCache[namespacedSecretName] = registry.NoCredentials()
 			continue
 		}
-		seenCreds[name] = crd
+		imagePullSecretCache[namespacedSecretName] = crd
 
 		// Merge into the credentials for this PodSpec
 		creds.Merge(crd)
@@ -132,7 +133,7 @@ func (c *Cluster) ImagesToFetch() registry.ImageCreds {
 	}
 
 	for _, ns := range namespaces {
-		seenCreds := make(map[string]registry.Credentials)
+		imagePullSecretCache := make(map[string]registry.Credentials) // indexed by the namespace/name of pullImageSecrets
 		for kind, resourceKind := range resourceKinds {
 			workloads, err := resourceKind.getWorkloads(ctx, c, ns)
 			if err != nil {
@@ -146,7 +147,7 @@ func (c *Cluster) ImagesToFetch() registry.ImageCreds {
 			imageCreds := make(registry.ImageCreds)
 			for _, workload := range workloads {
 				logger := log.With(c.logger, "resource", resource.MakeID(workload.GetNamespace(), kind, workload.GetName()))
-				mergeCredentials(logger.Log, c.includeImage, c.client, workload.GetNamespace(), workload.podTemplate, imageCreds, seenCreds)
+				mergeCredentials(logger.Log, c.includeImage, c.client, workload.GetNamespace(), workload.podTemplate, imageCreds, imagePullSecretCache)
 			}
 
 			// Merge creds
diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go
index cbad4867..777b2997 100644
--- a/pkg/daemon/daemon.go
+++ b/pkg/daemon/daemon.go
@@ -622,6 +622,8 @@ func (d *Daemon) GitRepoConfig(ctx context.Context, regenerate bool) (v6.GitConf
 	}
 
 	origin := d.Repo.Origin()
+	// Sanitize the URL before sharing it
+	origin.URL = origin.SafeURL()
 	status, _ := d.Repo.Status()
 	path := ""
 	if len(d.GitConfig.Paths) > 0 {
diff --git a/pkg/install/generated_templates.gogen.go b/pkg/install/generated_templates.gogen.go
index af075f59..37644811 100644
--- a/pkg/install/generated_templates.gogen.go
+++ b/pkg/install/generated_templates.gogen.go
@@ -33,7 +33,7 @@ var templates = func() http.FileSystem {
 			modTime:          time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC),
 			uncompressedSize: 7129,
 
-			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x59\x6d\x6f\x1b\x37\xf2\x7f\xef\x4f\x31\x50\xfe\x40\x62\x40\x5a\xd9\x75\xdb\xff\x61\x7b\x2a\x2e\xcd\x83\x9b\x4b\x93\x1a\x71\x72\x87\xbe\xaa\x29\xee\x48\x4b\x88\x4b\xee\x71\xb8\x52\x05\xa1\xdf\xfd\x30\xe4\x3e\x70\x65\xd9\x2e\xf2\xee\xf2\x22\x96\x76\x67\x86\xf3\x3c\xbf\xa1\x66\xb3\xd9\x99\xa8\xd5\xbf\xd0\x91\xb2\x26\x07\x51\xd7\x34\xdf\x5e\x9e\x6d\x94\x29\x72\x78\x8d\xb5\xb6\xfb\x0a\x8d\x3f\xab\xd0\x8b\x42\x78\x91\x9f\x01\x18\x51\x61\x0e\x2b\xdd\xfc\x71\x38\x80\x5a\x41\xf6\x51\x54\x48\xb5\x90\x08\x7f\xfe\xd9\xbe\x0f\x5f\x73\x38\x1c\xc6\x6f\x0f\x07\x40\x53\x30\x19\xd5\x28\x59\x98\xc3\x5a\x2b\x29\x28\x87\xcb\x33\x00\x42\x8d\xd2\x5b\xc7\x6f\x00\x2a\xe1\x65\xf9\x8b\x58\xa2\xa6\xf8\x20\x3d\x9b\xa9\xbd\x13\x1e\xd7\xfb\xf8\xd2\xef\x6b\xcc\xe1\x13\x4a\x87\xc2\xe3\x19\x80\xc7\xaa\xd6\xc2\x63\x2b\x2c\xb1\x80\xff\x09\x63\xac\x17\x5e\x59\xd3\x0b\x07\xa8\x9d\xad\xd0\x97\xd8\x50\xa6\xec\xbc\xb6\xce\xe7\x30\xb9\xba\xb8\xba\x9c\xc0\x33\xf0\xa8\x75\x42\x01\xde\x02\x49\x27\x6a\x84\x79\x85\xde\x29\x49\x6c\x5c\x6d\x95\xf1\xcf\x09\x98\x39\x6b\x05\xeb\x91\x0d\x47\x56\x00\x74\xbe\x08\x9f\xd1\x6d\x95\xc4\x97\x52\xda\xc6\xf8\x8f\x63\x42\x80\xad\xd5\x4d\x85\xbd\xa8\x59\x2b\x6a\xad\xfc\x6c\x83\xfb\xfe\x00\x62\x2f\xf8\xe1\xc0\xee\xc9\x20\x6f\xc6\x2c\x45\x08\x70\x42\x55\xe0\x4a\x34\xda\x7f\xb0\x05\xe6\x70\xf1\xed\xc5\x05\x3c\x83\x5d\x89\x06\x2a\xd6\x06\x0b\x70\x28\x8a\x99\x35\x7a\x3f\x85\x1d\xc2\xce\x9a\xe7\x1e\x96\x08\x62\xa9\x91\xfd\x21\xcb\xca\x16\x67\xad\xc0\x67\xf0\xb9\x54\x04\x8a\x40\x80\xaf\xea\x15\x41\x43\x58\xc0\xca\x3a\x58\xa3\x41\x27\xbc\x32\x6b\xb8\xbd\xfd\x19\x36\xb8\xa7\x0c\xde\x19\x78\xff\x37\x82\x1f\x17\x70\x99\x5d\x5e\x4c\x7b\x29\xdd\xd9\xd1\x04\x02\xe1\x30\xd5\x83\x2c\xab\x62\x10\x0b\x10\x40\x58\x0b\x4e\x8a\xd6\x51\xb0\xc3\x5e\x8c\x14\x06\x76\x4e\x79\x56\x34\x3b\xed\xbf\x35\x9a\xde\x19\x58\xd5\x7e\xff\x5a\xb9\xd4\x89\x15\x16\xaa\xa9\x72\xf8\x80\x95\x75\xfb\xd4\x4e\x84\x95\xd5\xda\xee\xd8\xa2\xf6\x68\x45\xc1\xd4\x86\xf8\x99\x00\xd9\x90\xb7\x95\x62\x0f\x6c\x8c\xdd\x99\xdf\x4b\x4b\x9e\x7a\x11\x2b\xa5\x71\x0a\xbb\x52\xc9\x12\xf6\xb6\x81\x9d\xd2\x3a\x1a\xe5\x2d\x14\x96\xeb\x8c\x1f\x33\x13\x7f\x70\x60\x77\x86\xd5\xee\x05\x38\xac\x2d\x38\xe1\x4b\x74\xe0\x4b\x61\xda\x83\xd7\xca\x97\xcd\x12\x2c\x3f\x44\xd0\x6a\x83\x19\xfc\x66\x9b\xe7\x5a\x83\xd0\x64\xbb\x23\xc6\xce\x06\xe5\x41\x19\x6f\x03\x8f\xb4\xc6\x0b\x65\xd0\x4d\x61\x89\xda\xee\x32\xb8\xc5\xc1\xab\xa5\xf7\x35\xe5\xf3\x79\x61\x25\x65\x9c\x58\xb2\xe0\xd2\x41\x33\xe7\xd2\x23\x3f\x5f\x37\xaa\x40\x9a\x37\x84\xb3\xda\xa9\xad\xf0\x18\x52\x8f\x0d\xc9\x4a\x5f\xe9\x5e\x52\x17\x0b\xa2\x72\x26\xad\x59\xa9\x75\xff\x0a\x20\x3e\xf8\x20\xea\x3c\x79\x98\x16\xd2\x2c\x61\xfb\xda\xb8\x64\x9b\x66\x89\xf3\x28\x64\x48\xbf\x27\x63\xb2\x53\x54\xf2\x93\x52\x6c\x11\x04\x14\x6a\xb5\x42\xc7\x4d\xb3\x93\xd0\x56\xd5\xd0\x18\x43\x08\xa2\xb8\x34\x08\xdc\x5c\xb6\xaa\xc0\xce\xed\x2b\xb5\xae\x44\x3d\x28\xa2\x7c\x09\xc2\x00\x1a\xef\xf6\xc1\x86\xbb\x48\x74\x37\x05\x61\x0a\x68\x8c\xb4\x15\x77\xeb\xc0\x1f\xad\xfd\x10\xc2\x29\x4c\xd1\x4b\x41\xb3\x0d\x12\x14\x52\x1b\xcf\x7b\x11\x60\x37\x7c\x45\x04\x12\xb6\x27\x23\x10\x3a\x81\xb7\xa0\x2a\xee\x93\x70\x7d\x73\x1d\x9a\x00\xbc\x60\xb3\x48\xad\x8d\x32\xc3\xe1\x6c\xdc\x16\x9d\x5a\x29\x19\x1a\x36\xd4\x8d\xab\x2d\x21\x9d\xff\x05\x47\xf6\x52\x62\xfb\x88\x5e\x64\x07\xf1\x79\x7f\xc1\x71\x20\xdc\x7a\x28\xd3\x07\x3c\xb6\xae\xd7\xdc\x3f\x28\x71\xcd\xb8\x05\x3f\x7b\xa0\x09\xdf\xe7\x3b\xd1\x84\x3b\x77\xf6\x95\x78\xaf\xff\x27\x13\xa2\xf5\xba\xc3\xd0\x27\x8d\x85\x49\x1e\x2b\x71\x02\xaa\x12\x6b\x8c\xd9\xcf\x0c\x19\xbc\x55\xa6\x08\x36\x57\xdc\x56\x1c\xca\x21\x6b\x63\x4b\xd1\x28\x08\xb9\x79\x04\x56\x0e\x02\xe3\x04\x10\xbe\xaf\xfb\xb2\x59\x66\x85\x95\x1b\x74\x99\xb4\xd5\xdc\xcd\x63\x0f\x08\x7f\xe6\x5e\xf4\xae\xeb\xe2\xc8\xf3\x9e\xb1\x00\x9f\xea\xc5\x1a\x58\xd3\xac\xa7\x09\xc7\xe4\xd0\x0a\x54\x36\x95\x96\x5f\x66\x97\xff\x9f\x5d\x8c\x69\x6f\x1a\xad\x6f\xac\x56\x72\x9f\xc3\xbb\xd5\x47\xeb\x6f\x1c\x52\x6a\x85\x43\xb2\x8d\x93\x48\x69\x1f\x77\xf8\x9f\x06\xc9\x8f\x9e\x01\xc8\xba\xc9\xe1\xbb\x8b\x6a\xf4\xb0\x0a\xad\x3e\x87\xef\xbf\xfd\xa0\x06\x98\x60\x5d\xca\x3c\x1b\x22\x73\x13\x20\xc3\xd5\xc5\x15\x4f\x4e\x65\x56\xd6\x55\x21\x65\x85\xee\xa9\xb5\xda\xa2\x41\xa2\x1b\x67\x97\x98\x6a\xc0\x2e\xbd\x1e\x4f\xed\x78\x54\x14\x38\x7e\x2c\x7c\x99\xc3\x5c\xd4\x2a\x7a\x7a\xfb\xfd\x5c\x15\x68\xbc\xf2\xfb\xac\x6e\x96\x09\xad\x32\xca\x2b\xa1\x5f\xa3\x16\xfb\x5b\xae\xcf\x82\x72\xf8\x2e\x21\xf0\xaa\x42\xdb\xf8\x13\xef\x78\xc8\xaa\xff\x0d\x55\x93\xa2\x1d\x05\xe6\x34\x3c\x82\x38\xe6\x6e\xa2\x66\xe8\x65\xd0\xac\x98\x13\x95\x8c\xf3\x6c\x44\x9e\xa0\x6d\xdb\x6f\xd6\x1c\x32\x50\x26\xe6\xdc\x73\x8a\x3c\x44\xe5\x7c\xd4\x26\x3b\x9f\xfd\x6a\xf4\x3e\x07\xef\x1a\x64\x69\x8c\x81\x42\x87\x5a\xb6\x8d\x9d\x4b\xaa\x46\xb7\xb2\x4e\x22\x0b\x8d\xa0\x87\x31\xcf\x43\x8a\xa7\xb8\x64\xac\xfb\x56\xb8\x56\xf7\x48\xf6\x75\xea\x27\x35\xfa\xce\x48\xdd\x84\xce\xc9\xd0\x2d\x0e\xb8\xae\xab\x46\x6c\xf0\x04\x94\xe9\xc0\xcc\x0f\xcc\x7a\x04\x33\xfa\xee\x0a\x05\x4a\x2d\x1c\x43\xb6\xa5\xdd\x26\x0d\xe0\x11\x18\x10\xdb\x63\x6a\xbc\xb3\xd6\xcf\x33\xa2\xf2\x41\x03\x84\x19\x9d\x3a\x19\x46\xd4\x24\x9e\x3c\xed\x48\x12\x09\x68\xb6\xca\x59\x13\x06\x42\x9c\xb5\x93\xf7\x5f\x7e\x7a\xf3\xea\xd7\x8f\x6f\xdf\x5d\x4f\xe2\x08\x98\xb2\x3f\xec\x16\x9d\x1b\xcf\xeb\x44\x4c\x18\x71\xcb\x7d\x9c\xa6\x5e\x9f\xb2\xf1\xde\xa0\xbd\x6f\xe3\x90\x9c\x4c\xfc\xa0\xa1\x3c\xf3\x78\xf1\xe8\x4e\xe3\x16\x9d\x40\x91\x56\xbb\x10\x93\x44\xc4\x31\xa0\x49\x83\x1e\xd0\x4c\x07\xbd\x85\x01\xa1\x3d\x3a\xc3\xd0\xfa\x9e\xc6\x2b\x67\x2b\x4e\x8b\x0e\xb1\x4c\x41\x10\xa7\x5b\x3b\x55\xd9\x0d\xda\xca\x0d\xdd\x0f\x36\x9a\x6d\x7e\xc2\x2f\x83\xbb\x47\x7e\xd9\x0a\xdd\xe0\x3d\x9f\x3c\x95\xc4\xc7\x39\xd0\xcd\xdc\x47\x32\x80\x47\xfe\x78\xd4\x3f\x32\xec\x1f\xc8\x4b\xa6\x8a\xe8\x66\x44\x37\xee\x0f\x4f\x55\xde\x4e\x30\x28\xb1\x40\x4d\x5d\xeb\x3d\xfc\xfc\xf9\xf3\x0d\x2c\x05\x29\x09\xa2\xf1\x25\x48\x87\xa1\x93\x0a\x1d\xa7\xfa\xb0\x0f\xb0\xc0\xad\x12\xc1\xf0\xbb\xeb\x77\x9f\x7f\x7f\xf9\xe5\xf3\xcf\x5f\x6e\xdf\x7c\xba\x0b\xe6\xf6\x8f\xde\xbf\xf9\xed\x6e\x94\xf0\x5b\xe1\x14\x6f\x73\xd4\x01\xe4\x44\x60\x84\x2f\x47\xf1\x7b\xeb\x6c\x35\x8e\x61\x24\xfb\x84\xab\x7c\x64\xf9\x08\x2b\x72\x63\x63\x13\x06\x07\xb0\xcf\xf3\x91\x3f\xa2\x0b\xe2\x8e\x8a\x05\x4f\x62\x29\x64\x89\x05\xa7\x56\x9a\xdb\x3d\xac\x66\x4f\xb1\xf4\x69\x22\xc5\xba\x16\x37\x27\x0c\xed\x8e\x1d\x18\xa7\xe1\x10\xde\x0d\x5b\x1f\xfb\x12\x29\xcd\x85\x01\xbd\xfa\x9d\x65\x2d\x1b\xf6\x53\xa8\xb8\x70\x21\x10\x12\x11\x4a\xbb\x0b\xfb\xaf\x35\x06\x65\x08\x99\xf2\xe3\xdc\x99\xcd\x7a\x03\xc2\xf2\xc3\x87\x2f\xfa\x47\x59\x0b\xfa\x32\xda\xca\x4c\xea\x86\x3c\xba\x8c\x1b\xb8\x4e\x5d\xf2\x85\x62\xaf\x19\x5c\xf1\x2a\x92\xbe\xbb\x19\x19\xc5\x6d\x87\xd0\x87\xfd\x7a\x9c\xd9\x83\x0e\x1d\x3d\x67\x97\x77\x4c\x19\x36\xde\x64\x04\xa5\x1a\xb7\xd4\x8b\xb3\x11\xca\x54\x04\x55\x43\xe1\x06\x20\x78\x4f\x61\x11\xcb\x69\x19\x06\x5b\xc0\x78\x61\xf1\x7f\xd1\x6d\xd3\xe7\xa9\x2e\x5d\x73\x89\x65\xc8\x09\x9c\xec\xff\x23\x45\x78\x18\xc4\x01\x37\x2b\x94\x5b\xdc\x1b\x7b\xa9\x5a\x9f\x12\x84\x39\x04\xef\xcb\xa7\x5f\xe2\x05\x85\x30\xeb\xf8\xee\x5a\xf9\xb0\x34\x93\xf2\xd6\xed\xfb\x76\xfd\x96\x91\x71\x22\xee\xb1\x9a\xe3\xb4\x49\x6c\x6f\x4b\xe6\x64\x39\xa5\xb5\xd0\x61\xe7\xff\x7b\x91\x56\xe6\x79\x3e\x7c\x7f\xff\xe6\xb7\xf3\x7f\xc4\xd5\x3d\xc0\xea\x86\xd0\xcd\x07\x65\xb3\xb4\xd0\xd9\x3f\x5c\x4e\x8d\xd3\x8b\xc3\x01\xb2\x6b\xe5\xd9\xd8\x70\x15\x37\xa6\x58\x3a\x61\x64\xd9\x11\xfd\x14\xbe\xc5\x4b\x39\xb5\x0a\x8f\xb8\x7f\xd1\x29\x4e\xc6\x70\xcc\x77\x1b\x32\x85\xfe\x69\x95\x49\x18\x26\xd3\x49\x7b\xb7\xa7\x09\x53\xf6\xc7\x9b\x9a\x43\x4e\x3c\x19\xb7\xae\x4a\x18\xb5\x62\x4c\xce\x35\x44\xaa\x40\x17\xc3\x71\xb4\xd9\x84\x3b\x09\x4b\x08\x8d\x29\xd0\x1d\xc5\xd8\xa1\x16\x5e\x6d\x31\x40\x4e\xea\x32\x70\x3d\x8a\xf3\x51\x4d\xf6\xc6\x51\xb3\x2c\x94\xbb\x9c\xc6\xbf\xdf\xf4\x17\x95\x83\x73\xc2\x45\xe4\x29\xe7\x84\xdb\xbd\xce\xab\x1d\xd5\x09\x01\x5f\x08\xdd\x29\x7e\x0e\x6e\x1f\x39\xa6\x81\xd3\xfc\x6f\x2a\xa1\x4e\x2a\x80\xfc\xa2\x93\xd0\x51\x0d\x57\xad\x27\xc3\x81\xdc\x4a\x76\x96\x1d\x8a\x26\x5c\xdf\xb1\x9f\x78\x62\x2b\x7f\xb4\x80\xa7\xbe\x6a\x67\x5f\x3b\xd9\x16\x8f\x8c\xba\x8e\xa3\x95\xc5\x5c\x8b\xbf\x6f\x70\x0f\xaa\xf8\xb1\x27\x7b\x04\xce\x24\x5a\xb1\x08\xe1\x1b\x87\xa3\x5b\x80\x13\x67\x85\xd7\xfb\x59\x4f\x4f\xa3\x76\xd5\x75\x6b\x50\x1e\x4a\x41\x61\x14\x5b\xa3\xf7\x20\xa4\x44\x8a\x1d\xbd\xc4\x78\x91\xf6\xa2\xbb\xb3\xb9\x5b\x09\x4d\x78\x77\x7e\x76\x38\xcc\xba\x40\x7c\x6a\x67\xf8\xa9\x58\x74\x42\x03\xfd\xfd\x7a\x38\x4d\x76\x22\x4e\xe4\x5d\x23\x7d\xd4\x77\x17\xd6\x79\x86\x78\x8d\x07\xda\x1b\x09\x4b\x6b\x37\x1b\xc4\x9a\xb3\xbe\x57\x75\xb2\x56\x7e\x32\x85\x0a\x05\x3b\x9c\x1b\x1a\x88\xb0\x63\xb7\x85\xd0\xd4\xe4\x1d\x8a\xaa\xaf\x88\xf3\x23\xc5\x58\xf4\x8c\xbc\xf0\xb8\xe0\x06\xf3\x60\xde\x18\xfc\xc3\x77\xc9\x93\x4c\x3c\x61\x60\xd2\x9d\x31\xe9\xe6\x51\x22\xe4\x05\x66\xeb\x6c\x0a\xff\x46\x46\x96\xaf\xb4\x6d\x8a\xf3\x2c\x5c\x10\x79\xbb\xe1\xfd\x84\xa0\x16\xce\x2b\xd9\x68\xe1\xba\x60\xb4\x52\x8e\x47\x69\x7b\xea\x62\x47\xdc\x47\x25\xcb\xca\x76\x2c\x37\xdb\x59\xb7\xa1\x7e\xd9\x3c\x62\x0b\x07\x2d\xc4\x52\x5e\x7e\x73\x75\xff\xff\xd4\xe0\x37\x31\xfb\xba\xae\xd4\x5f\x58\x5b\xf3\x48\x6a\x7c\x68\xa9\xaf\x07\xe2\xa3\x0c\xe9\xe4\xcd\x06\x79\x8b\x80\x03\x1f\xce\x96\x53\x2c\xe1\xe0\x07\x52\xe7\x16\xdd\xf6\xc4\x2f\x12\xbc\x10\x0c\x08\x88\x6b\xf5\x87\x74\x14\x8b\x0d\x8f\xb1\x98\x65\x84\x3e\xf9\x99\xe3\x79\xf2\x4b\x49\xf2\x93\x07\x07\x27\x5c\xdd\x05\x50\x9e\x8d\xac\xd4\x8a\x3c\x9a\x59\xab\xc2\x22\xbf\xba\xb8\xba\x3c\x6b\xfb\xd8\xcb\xa2\x50\xf1\x42\x84\x07\xed\x4b\x06\xda\x23\x93\x87\xf7\x03\xd6\x3a\x1c\xc0\x85\xb1\xfd\x04\xf7\x2c\xfc\xde\x34\xea\x7d\xc3\xa7\xee\x80\x5f\xeb\x56\xfc\xeb\x8f\xb7\x1d\x48\xa2\x69\xbb\xbc\x34\xae\x85\x4c\x60\x0a\xeb\x09\x6c\x20\x86\x4a\xec\xc3\x45\x92\xde\x0e\xd7\x89\x86\xb4\xb5\x9b\xa6\x06\x45\xd4\x20\x81\x35\x40\xb6\x42\x78\xdf\x2c\xd1\x19\xf4\x48\x2c\xbd\xa9\x69\xb8\x2d\x2c\x0c\x75\x77\x55\x93\x8f\xd6\xe0\x24\x7d\xf3\x2a\x28\x90\xde\x17\xc6\xc3\x69\x7c\x85\xd8\x2d\x21\x41\xbf\xd1\x9b\x7e\x3f\x9a\x5c\x4e\xce\xfe\x1b\x00\x00\xff\xff\x67\x51\x58\x04\xd9\x1b\x00\x00"),
+			compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x59\x6d\x6f\x1b\x37\xf2\x7f\xef\x4f\x31\x50\xfe\x40\x62\x40\x5a\xd9\x75\xdb\xff\x61\x7b\x2a\x2e\xcd\x83\x9b\x4b\x93\x1a\x71\x72\x87\xbe\xaa\x29\xee\x48\x4b\x88\x4b\xee\x71\xb8\x52\x05\xa1\xdf\xfd\x30\xe4\x3e\x70\x65\xd9\x2e\xf2\xee\xf2\x22\x96\x76\x67\x86\xf3\x3c\xbf\xa1\x66\xb3\xd9\x99\xa8\xd5\xbf\xd0\x91\xb2\x26\x07\x51\xd7\x34\xdf\x5e\x9e\x6d\x94\x29\x72\x78\x8d\xb5\xb6\xfb\x0a\x8d\x3f\xab\xd0\x8b\x42\x78\x91\x9f\x01\x18\x51\x61\x0e\x2b\xdd\xfc\x71\x38\x80\x5a\x41\xf6\x51\x54\x48\xb5\x90\x08\x7f\xfe\xd9\xbe\x0f\x5f\x73\x38\x1c\xc6\x6f\x0f\x07\x40\x53\x30\x19\xd5\x28\x59\x98\xc3\x5a\x2b\x29\x28\x87\xcb\x33\x00\x42\x8d\xd2\x5b\xc7\x6f\x00\x2a\xe1\x65\xf9\x8b\x58\xa2\xa6\xf8\x20\x3d\x9b\xa9\xbd\x13\x1e\xd7\xfb\xf8\xd2\xef\x6b\xcc\xe1\x13\x4a\x87\xc2\xe3\x19\x80\xc7\xaa\xd6\xc2\x63\x2b\x2c\xb1\x80\xff\x09\x63\xac\x17\x5e\x59\xd3\x0b\x07\xa8\x9d\xad\xd0\x97\xd8\x50\xa6\xec\xbc\xb6\xce\xe7\x30\xb9\xba\xb8\xba\x9c\xc0\x33\xf0\xa8\x75\x42\x01\xde\x02\x49\x27\x6a\x84\x79\x85\xde\x29\x49\x6c\x5c\x6d\x95\xf1\xcf\x09\x98\x39\x6b\x05\xeb\x91\x0d\x47\x56\x00\x74\xbe\x08\x9f\xd1\x6d\x95\xc4\x97\x52\xda\xc6\xf8\x8f\x63\x42\x80\xad\xd5\x4d\x85\xbd\xa8\x59\x2b\x6a\xad\xfc\x6c\x83\xfb\xfe\x00\x62\x2f\xf8\xe1\xc0\xee\xc9\x20\x6f\xc6\x2c\x45\x08\x70\x42\x55\xe0\x4a\x34\xda\x7f\xb0\x05\xe6\x70\xf1\xed\xc5\x05\x3c\x83\x5d\x89\x06\x2a\xd6\x06\x0b\x70\x28\x8a\x99\x35\x7a\x3f\x85\x1d\xc2\xce\x9a\xe7\x1e\x96\x08\x62\xa9\x91\xfd\x21\xcb\xca\x16\x67\xad\xc0\x67\xf0\xb9\x54\x04\x8a\x40\x80\xaf\xea\x15\x41\x43\x58\xc0\xca\x3a\x58\xa3\x41\x27\xbc\x32\x6b\xb8\xbd\xfd\x19\x36\xb8\xa7\x0c\xde\x19\x78\xff\x37\x82\x1f\x17\x70\x99\x5d\x5e\x4c\x7b\x29\xdd\xd9\xd1\x04\x02\xe1\x30\xd5\x83\x2c\xab\x62\x10\x0b\x10\x40\x58\x0b\x4e\x8a\xd6\x51\xb0\xc3\x5e\x8c\x14\x06\x76\x4e\x79\x56\x34\x3b\xed\xbf\x35\x9a\xde\x19\x58\xd5\x7e\xff\x5a\xb9\xd4\x89\x15\x16\xaa\xa9\x72\xf8\x80\x95\x75\xfb\xd4\x4e\x84\x95\xd5\xda\xee\xd8\xa2\xf6\x68\x45\xc1\xd4\x86\xf8\x99\x00\xd9\x90\xb7\x95\x62\x0f\x6c\x8c\xdd\x99\xdf\x4b\x4b\x9e\x7a\x11\x2b\xa5\x71\x0a\xbb\x52\xc9\x12\xf6\xb6\x81\x9d\xd2\x3a\x1a\xe5\x2d\x14\x96\xeb\x8c\x1f\x33\x13\x7f\x70\x60\x77\x86\xd5\xee\x05\x38\xac\x2d\x38\xe1\x4b\x74\xe0\x4b\x61\xda\x83\xd7\xca\x97\xcd\x12\x2c\x3f\x44\xd0\x6a\x83\x19\xfc\x66\x9b\xe7\x5a\x83\xd0\x64\xbb\x23\xc6\xce\x06\xe5\x41\x19\x6f\x03\x8f\xb4\xc6\x0b\x65\xd0\x4d\x61\x89\xda\xee\x32\xb8\xc5\xc1\xab\xa5\xf7\x35\xe5\xf3\x79\x61\x25\x65\x9c\x58\xb2\xe0\xd2\x41\x33\xe7\xd2\x23\x3f\x5f\x37\xaa\x40\x9a\x37\x84\xb3\xda\xa9\xad\xf0\x18\x52\x8f\x0d\xc9\x4a\x5f\xe9\x5e\x52\x17\x0b\xa2\x72\x26\xad\x59\xa9\x75\xff\x0a\x20\x3e\xf8\x20\xea\x3c\x79\x98\x16\xd2\x2c\x61\xfb\xda\xb8\x64\x9b\x66\x89\xf3\x28\x64\x48\xbf\x27\x63\xb2\x53\x54\xf2\x93\x52\x6c\x11\x04\x14\x6a\xb5\x42\xc7\x4d\xb3\x93\xd0\x56\xd5\xd0\x18\x43\x08\xa2\xb8\x34\x08\xdc\x5c\xb6\xaa\xc0\xce\xed\x2b\xb5\xae\x44\x3d\x28\xa2\x7c\x09\xc2\x00\x1a\xef\xf6\xc1\x86\xbb\x48\x74\x37\x05\x61\x0a\x68\x8c\xb4\x15\x77\xeb\xc0\x1f\xad\xfd\x10\xc2\x29\x4c\xd1\x4b\x41\xb3\x0d\x12\x14\x52\x1b\xcf\x7b\x11\x60\x37\x7c\x45\x04\x12\xb6\x27\x23\x10\x3a\x81\xb7\xa0\x2a\xee\x93\x70\x7d\x73\x1d\x9a\x00\xbc\x60\xb3\x48\xad\x8d\x32\xc3\xe1\x6c\xdc\x16\x9d\x5a\x29\x19\x1a\x36\xd4\x8d\xab\x2d\x21\x9d\xff\x05\x47\xf6\x52\x62\xfb\x88\x5e\x64\x07\xf1\x79\x7f\xc1\x71\x20\xdc\x7a\x28\xd3\x07\x3c\xb6\xae\xd7\xdc\x3f\x28\x71\xcd\xb8\x05\x3f\x7b\xa0\x09\xdf\xe7\x3b\xd1\x84\x3b\x77\xf6\x95\x78\xaf\xff\x27\x13\xa2\xf5\xba\xc3\xd0\x27\x8d\x85\x49\x1e\x2b\x71\x02\xaa\x12\x6b\x8c\xd9\xcf\x0c\x19\xbc\x55\xa6\x08\x36\x57\xdc\x56\x1c\xca\x21\x6b\x63\x4b\xd1\x28\x08\xb9\x79\x04\x56\x0e\x02\xe3\x04\x10\xbe\xaf\xfb\xb2\x59\x66\x85\x95\x1b\x74\x99\xb4\xd5\xdc\xcd\x63\x0f\x08\x7f\xe6\x5e\xf4\xae\xeb\xe2\xc8\xf3\x9e\xb1\x00\x9f\xea\xc5\x1a\x58\xd3\xac\xa7\x09\xc7\xe4\xd0\x0a\x54\x36\x95\x96\x5f\x66\x97\xff\x9f\x5d\x8e\x69\x6f\x1a\xad\x6f\xac\x56\x72\x9f\xc3\xbb\xd5\x47\xeb\x6f\x1c\x52\x6a\x85\x43\xb2\x8d\x93\x48\x69\x1f\x77\xf8\x9f\x06\xc9\x8f\x9e\x01\xc8\xba\xc9\xe1\xbb\x8b\x6a\xf4\xb0\x0a\xad\x3e\x87\xef\xbf\xfd\xa0\x06\x98\x60\x5d\xca\x3c\x1b\x22\x73\x13\x20\xc3\xd5\xc5\x15\x4f\x4e\x65\x56\xd6\x55\x21\x65\x85\xee\xa9\xb5\xda\xa2\x41\xa2\x1b\x67\x97\x98\x6a\xc0\x2e\xbd\x1e\x4f\xed\x78\x54\x14\x38\x7e\x2c\x7c\x99\xc3\x5c\xd4\x2a\x7a\x7a\xfb\xfd\x5c\x15\x68\xbc\xf2\xfb\xac\x6e\x96\x09\xad\x32\xca\x2b\xa1\x5f\xa3\x16\xfb\x5b\xae\xcf\x82\x72\xf8\x2e\x21\xf0\xaa\x42\xdb\xf8\x13\xef\x78\xc8\xaa\xff\x0d\x55\x93\xa2\x1d\x05\xe6\x34\x3c\x82\x38\xe6\x6e\xa2\x66\xe8\x65\xd0\xac\x98\x13\x95\x8c\xf3\x6c\x44\x9e\xa0\x6d\xdb\x6f\xd6\x1c\x32\x50\x26\xe6\xdc\x73\x8a\x3c\x44\xe5\x7c\xd4\x26\x3b\x9f\xfd\x6a\xf4\x3e\x07\xef\x1a\x64\x69\x8c\x81\x42\x87\x5a\xb6\x8d\x9d\x4b\xaa\x46\xb7\xb2\x4e\x22\x0b\x8d\xa0\x87\x31\xcf\x43\x8a\xa7\xb8\x64\xac\xfb\x56\xb8\x56\xf7\x48\xf6\x75\xea\x27\x35\xfa\xce\x48\xdd\x84\xce\xc9\xd0\x2d\x0e\xb8\xae\xab\x46\x6c\xf0\x04\x94\xe9\xc0\xcc\x0f\xcc\x7a\x04\x33\xfa\xee\x0a\x05\x4a\x2d\x1c\x43\xb6\xa5\xdd\x26\x0d\xe0\x11\x18\x10\xdb\x63\x6a\xbc\xb3\xd6\xcf\x33\xa2\xf2\x41\x03\x84\x19\x9d\x3a\x19\x46\xd4\x24\x9e\x3c\xed\x48\x12\x09\x68\xb6\xca\x59\x13\x06\x42\x9c\xb5\x93\xf7\x5f\x7e\x7a\xf3\xea\xd7\x8f\x6f\xdf\x5d\x4f\xe2\x08\x98\xb2\x3f\xec\x16\x9d\x1b\xcf\xeb\x44\x4c\x18\x71\xcb\x7d\x9c\xa6\x5e\x9f\xb2\xf1\xde\xa0\xbd\x6f\xe3\x90\x9c\x4c\xfc\xa0\xa1\x3c\xf3\x78\xf1\xe8\x4e\xe3\x16\x9d\x40\x91\x56\xbb\x10\x93\x44\xc4\x31\xa0\x49\x83\x1e\xd0\x4c\x07\xbd\x85\x01\xa1\x3d\x3a\xc3\xd0\xfa\x9e\xc6\x2b\x67\x2b\x4e\x8b\x0e\xb1\x4c\x41\x10\xa7\x5b\x3b\x55\xd9\x0d\xda\xca\x0d\xdd\x0f\x36\x9a\x6d\x7e\xc2\x2f\x83\xbb\x47\x7e\xd9\x0a\xdd\xe0\x3d\x9f\x3c\x95\xc4\xc7\x39\xd0\xcd\xdc\x47\x32\x80\x47\xfe\x78\xd4\x3f\x32\xec\x1f\xc8\x4b\xa6\x8a\xe8\x66\x44\x37\xee\x0f\x4f\x55\xde\x4e\x30\x28\xb1\x40\x4d\x5d\xeb\x3d\xfc\xfc\xf9\xf3\x0d\x2c\x05\x29\x09\xa2\xf1\x25\x48\x87\xa1\x93\x0a\x1d\xa7\xfa\xb0\x0f\xb0\xc0\xad\x12\xc1\xf0\xbb\xeb\x77\x9f\x7f\x7f\xf9\xe5\xf3\xcf\x5f\x6e\xdf\x7c\xba\x0b\xe6\xf6\x8f\xde\xbf\xf9\xed\x6e\x94\xf0\x5b\xe1\x14\x6f\x73\xd4\x01\xe4\x44\x60\x84\x2f\x47\xf1\x7b\xeb\x6c\x35\x8e\x61\x24\xfb\x84\xab\x7c\x64\xf9\x08\x2b\x72\x63\x63\x13\x06\x07\xb0\xcf\xf3\x91\x3f\xa2\x0b\xe2\x8e\x8a\x05\x4f\x62\x29\x64\x89\x05\xa7\x56\x9a\xdb\x3d\xac\x66\x4f\xb1\xf4\x69\x22\xc5\xba\x16\x37\x27\x0c\xed\x8e\x1d\x18\xa7\xe1\x10\xde\x0d\x5b\x1f\xfb\x12\x29\xcd\x85\x01\xbd\xfa\x9d\x65\x2d\x1b\xf6\x53\xa8\xb8\x70\x21\x10\x12\x11\x4a\xbb\x0b\xfb\xaf\x35\x06\x65\x08\x99\xf2\xe3\xdc\x99\xcd\x7a\x03\xc2\xf2\xc3\x87\x2f\xfa\x47\x59\x0b\xfa\x32\xda\xca\x4c\xea\x86\x3c\xba\x8c\x1b\xb8\x4e\x5d\xf2\x85\x62\xaf\x19\x5c\xf1\x2a\x92\xbe\xbb\x19\x19\xc5\x6d\x87\xd0\x87\xfd\x7a\x9c\xd9\x83\x0e\x1d\x3d\x67\x97\x77\x4c\x19\x36\xde\x64\x04\xa5\x1a\xb7\xd4\x8b\xb3\x11\xca\x54\x04\x55\x43\xe1\x06\x20\x78\x4f\x61\x11\xcb\x69\x19\x06\x5b\xc0\x78\x61\xf1\x7f\xd1\x6d\xd3\xe7\xa9\x2e\x5d\x73\x89\x65\xc8\x09\x9c\xec\xff\x23\x45\x78\x18\xc4\x01\x37\x2b\x94\x5b\xdc\x1b\x7b\xa9\x5a\x9f\x12\x84\x39\x04\xef\xcb\xa7\x5f\xe2\x05\x85\x30\xeb\xf8\xee\x5a\xf9\xb0\x34\x93\xf2\xd6\xed\xfb\x76\xfd\x96\x91\x71\x22\xee\xb1\x9a\xe3\xb4\x49\x6c\x6f\x4b\xe6\x64\x39\xa5\xb5\xd0\x61\xe7\xff\x7b\x91\x56\xe6\x79\x3e\x7c\x7f\xff\xe6\xb7\xf3\x7f\xc4\xd5\x3d\xc0\xea\x86\xd0\xcd\x07\x65\xb3\xb4\xd0\xd9\x3f\x5c\x4e\x8d\xd3\x8b\xc3\x01\xb2\x6b\xe5\xd9\xd8\x70\x15\x37\xa6\x58\x3a\x61\x64\xd9\x11\xfd\x14\xbe\xc5\x4b\x39\xb5\x0a\x8f\xb8\x7f\xd1\x29\x4e\xc6\x70\xcc\x77\x1b\x32\x85\xfe\x69\x95\x49\x18\x26\xd3\x49\x7b\xb7\xa7\x09\x53\xf6\xc7\x9b\x9a\x43\x4e\x3c\x19\xb7\xae\x4a\x18\xb5\x62\x4c\xce\x35\x44\xaa\x40\x17\xc3\x71\xb4\xd9\x84\x3b\x09\x4b\x08\x8d\x29\xd0\x1d\xc5\xd8\xa1\x16\x5e\x6d\x31\x40\x4e\xea\x32\x70\x3d\x8a\xf3\x51\x4d\xf6\xc6\x51\xb3\x2c\x94\xbb\x9c\xc6\xbf\xdf\xf4\x17\x95\x83\x73\xc2\x45\xe4\x29\xe7\x84\xdb\xbd\xce\xab\x1d\xd5\x09\x01\x5f\x08\xdd\x29\x7e\x0e\x6e\x1f\x39\xa6\x81\xd3\xfc\x6f\x2a\xa1\x4e\x2a\x80\xfc\xa2\x93\xd0\x51\x0d\x57\xad\x27\xc3\x81\xdc\x4a\x76\x96\x1d\x8a\x26\x5c\xdf\xb1\x9f\x78\x62\x2b\x7f\xb4\x80\xa7\xbe\x6a\x67\x5f\x3b\xd9\x16\x8f\x8c\xba\x8e\xa3\x95\xc5\x5c\x8b\xbf\x6f\x70\x0f\xaa\xf8\xb1\x27\x7b\x04\xce\x24\x5a\xb1\x08\xe1\x1b\x87\xa3\x5b\x80\x13\x67\x85\xd7\xfb\x59\x4f\x4f\xa3\x76\xd5\x75\x6b\x50\x1e\x4a\x41\x61\x14\x5b\xa3\xf7\x20\xa4\x44\x8a\x1d\xbd\xc4\x78\x91\xf6\xa2\xbb\xb3\xb9\x5b\x09\x4d\x78\x77\x7e\x76\x38\xcc\xba\x40\x7c\x6a\x67\xf8\xa9\x58\x74\x42\x03\xfd\xfd\x7a\x38\x4d\x76\x22\x4e\xe4\x5d\x23\x7d\xd4\x77\x17\xd6\x79\x86\x78\x8d\x07\xda\x1b\x09\x4b\x6b\x37\x1b\xc4\x9a\xb3\xbe\x57\x75\xb2\x56\x7e\x32\x85\x0a\x05\x3b\x9c\x1b\x1a\x88\xb0\x63\xb7\x85\xd0\xd4\xe4\x1d\x8a\xaa\xaf\x88\xf3\x23\xc5\x58\xf4\x8c\xbc\xf0\xb8\xe0\x06\xf3\x60\xde\x18\xfc\xc3\x77\xc9\x93\x4c\x3c\x61\x60\xd2\x9d\x31\xe9\xe6\x51\x22\xe4\x05\x66\xeb\x6c\x0a\xff\x46\x46\x96\xaf\xb4\x6d\x8a\xf3\x2c\x5c\x10\x79\xbb\xe1\xfd\x84\xa0\x16\xce\x2b\xd9\x68\xe1\xba\x60\xb4\x52\x8e\x47\x69\x7b\xea\x62\x47\xdc\x47\x25\xcb\xca\x76\x2c\x37\xdb\x59\xb7\xa1\x7e\xd9\x3c\x62\x0b\x07\x2d\xc4\x52\x5e\x7e\x73\x75\xff\xff\xd4\xe0\x37\x31\xfb\xba\xae\xd4\x5f\x58\x5b\xf3\x48\x6a\x7c\x68\xa9\xaf\x07\xe2\xa3\x0c\xe9\xe4\xcd\x06\x79\x8b\x80\x03\x1f\xce\x96\x53\x2c\xe1\xe0\x07\x52\xe7\x16\xdd\xf6\xc4\x2f\x12\xbc\x10\x0c\x08\x88\x6b\xf5\x87\x74\x14\x8b\x0d\x8f\xb1\x98\x65\x84\x3e\xf9\x99\xe3\x79\xf2\x4b\x49\xf2\x93\x07\x07\x27\x5c\xdd\x05\x50\x9e\x8d\xac\xd4\x8a\x3c\x9a\x59\xab\xc2\x22\xbf\xba\xb8\xba\x3c\x6b\xfb\xd8\xcb\xa2\x50\xf1\x42\x84\x07\xed\x4b\x06\xda\x23\x93\x87\xf7\x03\xd6\x3a\x1c\xc0\x85\xb1\xfd\x04\xf7\x2c\xfc\xde\x34\xea\x7d\xc3\xa7\xee\x80\x5f\xeb\x56\xfc\xeb\x8f\xb7\x1d\x48\xa2\x69\xbb\xbc\x34\xae\x85\x4c\x60\x0a\xeb\x09\x6c\x20\x86\x4a\xec\xc3\x45\x92\xde\x0e\xd7\x89\x86\xb4\xb5\x9b\xa6\x06\x45\xd4\x20\x81\x35\x40\xb6\x42\x78\xdf\x2c\xd1\x19\xf4\x48\x2c\xbd\xa9\x69\xb8\x2d\x2c\x0c\x75\x77\x55\x93\x8f\xd6\xe0\x24\x7d\xf3\x2a\x28\x90\xde\x17\xc6\xc3\x69\x7c\x85\xd8\x2d\x21\x41\xbf\xd1\x9b\x7e\x3f\x9a\x5c\x4e\xce\xfe\x1b\x00\x00\xff\xff\xbd\x03\x83\x41\xd9\x1b\x00\x00"),
 		},
 		"/flux-secret.yaml.tmpl": &vfsgen۰CompressedFileInfo{
 			name:             "flux-secret.yaml.tmpl",
diff --git a/pkg/install/templates/flux-deployment.yaml.tmpl b/pkg/install/templates/flux-deployment.yaml.tmpl
index 1cc4dce1..70baabff 100644
--- a/pkg/install/templates/flux-deployment.yaml.tmpl
+++ b/pkg/install/templates/flux-deployment.yaml.tmpl
@@ -64,7 +64,7 @@ spec:
         # There are no ":latest" images for flux. Find the most recent
         # release or image version at https://hub.docker.com/r/fluxcd/flux/tags
         # and replace the tag here.
-        image: docker.io/fluxcd/flux:1.17.0
+        image: docker.io/fluxcd/flux:1.17.1
         imagePullPolicy: IfNotPresent
         resources:
           requests:


Test patch:
diff --git a/pkg/cluster/kubernetes/images_test.go b/pkg/cluster/kubernetes/images_test.go
index 018734f0..859d0dc1 100644
--- a/pkg/cluster/kubernetes/images_test.go
+++ b/pkg/cluster/kubernetes/images_test.go
@@ -2,6 +2,7 @@ package kubernetes
 
 import (
 	"encoding/base64"
+	"fmt"
 	"testing"
 
 	"github.com/ryanuber/go-glob"
@@ -13,7 +14,8 @@ import (
 	"github.com/fluxcd/flux/pkg/registry"
 )
 
-func noopLog(...interface{}) error {
+func noopLog(e ...interface{}) error {
+	fmt.Println(e...)
 	return nil
 }
 
@@ -78,6 +80,44 @@ func TestMergeCredentials(t *testing.T) {
 	assert.ElementsMatch(t, []string{"docker.io", "quay.io"}, hosts)
 }
 
+func TestMergeCredentials_SameSecretSameNameDifferentNamespace(t *testing.T) {
+	ns1, ns2, secretName := "foo-ns", "bar-ns", "pull-secretname"
+	saName := "service-account"
+	ref, _ := image.ParseRef("foo/bar:tag")
+	spec := apiv1.PodTemplateSpec{
+		Spec: apiv1.PodSpec{
+			ServiceAccountName: saName,
+			ImagePullSecrets: []apiv1.LocalObjectReference{
+				{Name: secretName},
+			},
+			Containers: []apiv1.Container{
+				{Name: "container1", Image: ref.String()},
+			},
+		},
+	}
+
+	clientset := fake.NewSimpleClientset(
+		makeServiceAccount(ns1, saName, []string{secretName}),
+		makeServiceAccount(ns2, saName, []string{secretName}),
+		makeImagePullSecret(ns1, secretName, "docker.io"),
+		makeImagePullSecret(ns2, secretName, "quay.io"))
+	client := ExtendedClient{coreClient: clientset}
+
+	creds := registry.ImageCreds{}
+
+	pullImageSecretCache := make(map[string]registry.Credentials)
+	mergeCredentials(noopLog, func(imageName string) bool { return true },
+		client, ns1, spec, creds, pullImageSecretCache)
+	mergeCredentials(noopLog, func(imageName string) bool { return true },
+		client, ns2, spec, creds, pullImageSecretCache)
+	// check that we accumulated some credentials
+	assert.Contains(t, creds, ref.Name)
+	c := creds[ref.Name]
+	hosts := c.Hosts()
+	// Make sure we get the host from the second secret
+	assert.ElementsMatch(t, []string{"quay.io"}, hosts)
+}
+
 func TestMergeCredentials_ImageExclusion(t *testing.T) {
 	creds := registry.ImageCreds{}
 	gcrImage, _ := image.ParseRef("gcr.io/foo/bar:tag")
diff --git a/test/e2e/10_helm_chart.bats b/test/e2e/10_helm_chart.bats
index 5c9d39bb..68a22989 100644
--- a/test/e2e/10_helm_chart.bats
+++ b/test/e2e/10_helm_chart.bats
@@ -18,7 +18,6 @@ function setup() {
   # Test that the resources from https://github.com/fluxcd/flux-get-started are deployed
   poll_until_true 'namespace demo' 'kubectl describe ns/demo'
   poll_until_true 'workload podinfo' 'kubectl -n demo describe deployment/podinfo'
-  poll_until_true 'mongodb HelmRelease' 'kubectl -n demo describe helmrelease/mongodb'
 }
 
 function teardown() {
diff --git a/test/e2e/lib/install.bash b/test/e2e/lib/install.bash
index 9a133d99..c97d5187 100755
--- a/test/e2e/lib/install.bash
+++ b/test/e2e/lib/install.bash
@@ -22,12 +22,8 @@ function uninstall_tiller() {
 }
 
 function install_flux_with_helm() {
-  local create_crds='true'
-  if kubectl get crd fluxhelmreleases.helm.integrations.flux.weave.works helmreleases.flux.weave.works > /dev/null 2>&1; then
-    # CRDs existed, don't try to create them
-    echo 'CRDs existed, setting helmOperator.createCRD=false'
-    create_crds='false'
-  fi
+
+  kubectl apply -f https://raw.githubusercontent.com/fluxcd/helm-operator/v1.0.0-rc4/deploy/flux-helm-release-crd.yaml
 
   helm install --name flux --wait \
     --namespace "${FLUX_NAMESPACE}" \
@@ -39,9 +35,6 @@ function install_flux_with_helm() {
     --set git.config.secretName=gitconfig \
     --set git.config.enabled=true \
     --set-string git.config.data="${GITCONFIG}" \
-    --set helmOperator.create=true \
-    --set helmOperator.git.secretName=flux-git-deploy \
-    --set helmOperator.createCRD="${create_crds}" \
     --set registry.excludeImage=* \
     --set-string ssh.known_hosts="${KNOWN_HOSTS}" \
     "${FLUX_ROOT_DIR}/chart/flux"
@@ -49,7 +42,7 @@ function install_flux_with_helm() {
 
 function uninstall_flux_with_helm() {
   helm delete --purge flux > /dev/null 2>&1
-  kubectl delete crd helmreleases.flux.weave.works > /dev/null 2>&1
+  kubectl delete crd helmreleases.fluxcd.io > /dev/null 2>&1
 }
 
 fluxctl_install_cmd="fluxctl install --git-url=ssh://git@gitsrv/git-server/repos/cluster.git --git-email=foo"