diff --git a/charts/consul/templates/client-snapshot-agent-deployment.yaml b/charts/consul/templates/client-snapshot-agent-deployment.yaml index 7b7e953c98..e5202644cd 100644 --- a/charts/consul/templates/client-snapshot-agent-deployment.yaml +++ b/charts/consul/templates/client-snapshot-agent-deployment.yaml @@ -41,14 +41,14 @@ spec: {{- end }} {{- if .Values.global.secretsBackend.vault.agentAnnotations }} {{ tpl .Values.global.secretsBackend.vault.agentAnnotations . | nindent 8 | trim }} - {{- end }} + {{- end }} {{- end }} {{- if .Values.global.enterpriseLicense.secretName }} {{- with .Values.global.enterpriseLicense }} "vault.hashicorp.com/agent-inject-secret-enterpriselicense.txt": "{{ .secretName }}" "vault.hashicorp.com/agent-inject-template-enterpriselicense.txt": {{ template "consul.vaultSecretTemplate" . }} {{- end }} - {{- end }} + {{- end }} {{- end }} spec: {{- if .Values.client.tolerations }} @@ -62,139 +62,175 @@ spec: {{- end }} {{- if (or .Values.global.acls.manageSystemACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload)) }} volumes: - {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - - name: snapshot-config - secret: - secretName: {{ .Values.client.snapshotAgent.configSecret.secretName }} - items: - - key: {{ .Values.client.snapshotAgent.configSecret.secretKey }} - path: snapshot-config.json + - name: consul-data + emptyDir: + medium: "Memory" + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + - name: snapshot-config + secret: + secretName: {{ .Values.client.snapshotAgent.configSecret.secretName }} + items: + - key: {{ .Values.client.snapshotAgent.configSecret.secretKey }} + path: snapshot-config.json + {{- end }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled) (not .Values.global.acls.manageSystemACLs)) }} + - name: consul-license + secret: + secretName: {{ .Values.global.enterpriseLicense.secretName }} + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} + - name: consul-ca-cert + secret: + {{- if .Values.global.tls.caCert.secretName }} + secretName: {{ .Values.global.tls.caCert.secretName }} + {{- else }} + secretName: {{ template "consul.fullname" . }}-ca-cert + {{- end }} + items: + - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} + path: tls.crt + {{- end }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + emptyDir: + medium: "Memory" + {{- end }} + {{- end }} + {{- end }} + containers: + - name: consul-snapshot-agent + image: "{{ default .Values.global.image .Values.client.image }}" + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_HTTP_ADDR + value: https://$(HOST_IP):8501 + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- else }} + - name: CONSUL_HTTP_ADDR + value: http://$(HOST_IP):8500 {{- end }} {{- if .Values.global.acls.manageSystemACLs }} - - name: aclconfig - emptyDir: {} + - name: CONSUL_HTTP_TOKEN_FILE + value: /consul/login/acl-token {{- else }} - {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} - - name: consul-license - secret: - secretName: {{ .Values.global.enterpriseLicense.secretName }} + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload) }} + - name: CONSUL_LICENSE_PATH + {{- if .Values.global.secretsBackend.vault.enabled }} + value: /vault/secrets/enterpriselicense.txt + {{- else }} + value: /consul/license/{{ .Values.global.enterpriseLicense.secretKey }} + {{- end }} {{- end }} {{- end }} - {{- if .Values.global.tls.enabled }} - {{- if not (and .Values.externalServers.enabled .Values.externalServers.useSystemRoots) }} - - name: consul-ca-cert - secret: - {{- if .Values.global.tls.caCert.secretName }} - secretName: {{ .Values.global.tls.caCert.secretName }} - {{- else }} - secretName: {{ template "consul.fullname" . }}-ca-cert + command: + - "/bin/sh" + - "-ec" + - | + {{- if .Values.client.snapshotAgent.caCert }} + cat < /etc/ssl/certs/custom-ca.pem + {{- .Values.client.snapshotAgent.caCert | nindent 14 }} + EOF + {{- end }} + exec /bin/consul snapshot agent \ + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + -config-dir=/consul/config \ + {{- end }} + {{- if .Values.global.acls.manageSystemACLs }} + -config-dir=/consul/login \ {{- end }} - items: - - key: {{ default "tls.crt" .Values.global.tls.caCert.secretKey }} - path: tls.crt + {{- if (or .Values.global.acls.manageSystemACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload)) }} + {{- if .Values.global.acls.manageSystemACLs }} + lifecycle: + preStop: + exec: + command: + - "/bin/sh" + - "-ec" + - | + /bin/consul logout {{- end }} - {{- if .Values.global.tls.enableAutoEncrypt }} + volumeMounts: + {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} + - name: snapshot-config + readOnly: true + mountPath: /consul/config + {{- end }} + - mountPath: /consul/login + name: consul-data + readOnly: true + {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled) (not .Values.global.acls.manageSystemACLs))}} + - name: consul-license + mountPath: /consul/license + readOnly: true + {{- end }} + {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt}} - name: consul-auto-encrypt-ca-cert - emptyDir: - medium: "Memory" + {{- else }} + - name: consul-ca-cert {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + {{- end }} + {{- with .Values.client.snapshotAgent.resources }} + resources: + {{- toYaml . | nindent 12 }} {{- end }} - {{- end }} - containers: - - name: consul-snapshot-agent - image: "{{ default .Values.global.image .Values.client.image }}" - env: - - name: HOST_IP - valueFrom: - fieldRef: - fieldPath: status.hostIP - {{- if .Values.global.tls.enabled }} - - name: CONSUL_HTTP_ADDR - value: https://$(HOST_IP):8501 - - name: CONSUL_CACERT - value: /consul/tls/ca/tls.crt - {{- else }} - - name: CONSUL_HTTP_ADDR - value: http://$(HOST_IP):8500 - {{- end }} - {{- if .Values.global.acls.manageSystemACLs }} - - name: CONSUL_HTTP_TOKEN - valueFrom: - secretKeyRef: - name: "{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" - key: "token" - {{- else }} - {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload) }} - - name: CONSUL_LICENSE_PATH - {{- if .Values.global.secretsBackend.vault.enabled }} - value: /vault/secrets/enterpriselicense.txt - {{- else }} - value: /consul/license/{{ .Values.global.enterpriseLicense.secretKey }} - {{- end }} - {{- end }} - {{- end}} - command: - - "/bin/sh" - - "-ec" - - | - {{- if .Values.client.snapshotAgent.caCert }} - cat < /etc/ssl/certs/custom-ca.pem - {{- .Values.client.snapshotAgent.caCert | nindent 14 }} - EOF - {{- end }} - exec /bin/consul snapshot agent \ - {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - -config-dir=/consul/config \ - {{- end }} - {{- if .Values.global.acls.manageSystemACLs }} - -config-dir=/consul/aclconfig \ - {{- end }} - {{- if (or .Values.global.acls.manageSystemACLs .Values.global.tls.enabled (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload)) }} - volumeMounts: - {{- if (and .Values.client.snapshotAgent.configSecret.secretName .Values.client.snapshotAgent.configSecret.secretKey) }} - - name: snapshot-config - readOnly: true - mountPath: /consul/config - {{- end }} - {{- if .Values.global.acls.manageSystemACLs }} - - name: aclconfig - mountPath: /consul/aclconfig - {{- else }} - {{- if (and .Values.global.enterpriseLicense.secretName .Values.global.enterpriseLicense.secretKey .Values.global.enterpriseLicense.enableLicenseAutoload (not .Values.global.secretsBackend.vault.enabled)) }} - - name: consul-license - mountPath: /consul/license - readOnly: true - {{- end }} - {{- end }} - {{- if .Values.global.tls.enabled }} - {{- if .Values.global.tls.enableAutoEncrypt}} - - name: consul-auto-encrypt-ca-cert - {{- else }} - - name: consul-ca-cert - {{- end }} - mountPath: /consul/tls/ca - readOnly: true - {{- end }} - {{- end }} - {{- with .Values.client.snapshotAgent.resources }} - resources: - {{- toYaml . | nindent 12 }} - {{- end }} {{- if (or .Values.global.acls.manageSystemACLs (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt)) }} initContainers: + {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} + {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} + {{- end }} {{- if .Values.global.acls.manageSystemACLs }} - - name: client-snapshot-agent-acl-init + - name: snapshot-agent-acl-init + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.global.tls.enabled }} + - name: CONSUL_CACERT + value: /consul/tls/ca/tls.crt + {{- end }} + - name: CONSUL_HTTP_ADDR + {{- if .Values.global.tls.enabled }} + value: https://$(HOST_IP):8501 + {{- else }} + value: http://$(HOST_IP):8500 + {{- end }} image: {{ .Values.global.imageK8S }} - command: - - "/bin/sh" - - "-ec" - - | - consul-k8s-control-plane acl-init \ - -secret-name="{{ template "consul.fullname" . }}-client-snapshot-agent-acl-token" \ - -k8s-namespace={{ .Release.Namespace }} volumeMounts: - - name: aclconfig - mountPath: /consul/aclconfig + - mountPath: /consul/login + name: consul-data + readOnly: false + {{- if .Values.global.tls.enabled }} + {{- if .Values.global.tls.enableAutoEncrypt }} + - name: consul-auto-encrypt-ca-cert + {{- else }} + - name: consul-ca-cert + {{- end }} + mountPath: /consul/tls/ca + readOnly: true + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + consul-k8s-control-plane acl-init \ + -component-name=snapshot-agent \ + -acl-auth-method={{ template "consul.fullname" . }}-k8s-component-auth-method \ + {{- if .Values.global.adminPartitions.enabled }} + -partition={{ .Values.global.adminPartitions.name }} \ + {{- end }} + -log-level={{ default .Values.global.logLevel .Values.controller.logLevel }} \ + -log-json={{ .Values.global.logJSON }} resources: requests: memory: "25Mi" @@ -203,9 +239,6 @@ spec: memory: "25Mi" cpu: "50m" {{- end }} - {{- if (and .Values.global.tls.enabled .Values.global.tls.enableAutoEncrypt) }} - {{- include "consul.getAutoEncryptClientCA" . | nindent 6 }} - {{- end }} {{- end }} {{- if .Values.client.nodeSelector }} nodeSelector: diff --git a/charts/consul/templates/client-snapshot-agent-role.yaml b/charts/consul/templates/client-snapshot-agent-role.yaml index 6691750487..3077bc96f0 100644 --- a/charts/consul/templates/client-snapshot-agent-role.yaml +++ b/charts/consul/templates/client-snapshot-agent-role.yaml @@ -11,27 +11,16 @@ metadata: heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: client-snapshot-agent -{{- if (or .Values.global.acls.manageSystemACLs .Values.global.enablePodSecurityPolicies) }} -rules: {{- if .Values.global.enablePodSecurityPolicies }} - - apiGroups: ["policy"] - resources: ["podsecuritypolicies"] - resourceNames: - - {{ template "consul.fullname" . }}-snapshot-agent - verbs: - - use -{{- end }} -{{- if .Values.global.acls.manageSystemACLs }} - - apiGroups: [""] - resources: - - secrets - resourceNames: - - {{ template "consul.fullname" . }}-client-snapshot-agent-acl-token - verbs: - - get -{{- end }} +rules: +- apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + resourceNames: + - {{ template "consul.fullname" . }}-snapshot-agent + verbs: + - use {{- else }} -rules: [] +rules: [ ] {{- end }} {{- end }} {{- end }} diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index 84134b878e..f78f2bc632 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -240,7 +240,7 @@ spec: {{- end }} {{- if .Values.client.snapshotAgent.enabled }} - -create-snapshot-agent-token=true \ + -snapshot-agent=true \ {{- end }} {{- if not (or (and (ne (.Values.client.enabled | toString) "-") .Values.client.enabled) (and (eq (.Values.client.enabled | toString) "-") .Values.global.enabled)) }} diff --git a/charts/consul/templates/sync-catalog-deployment.yaml b/charts/consul/templates/sync-catalog-deployment.yaml index 4fd94baf3f..a344ad6f90 100644 --- a/charts/consul/templates/sync-catalog-deployment.yaml +++ b/charts/consul/templates/sync-catalog-deployment.yaml @@ -123,10 +123,10 @@ spec: - name: consul-auto-encrypt-ca-cert {{- else }} - name: consul-ca-cert - {{- end }} {{- end }} mountPath: /consul/tls/ca readOnly: true + {{- end }} command: - "/bin/sh" - "-ec" diff --git a/charts/consul/test/unit/client-snapshot-agent-deployment.bats b/charts/consul/test/unit/client-snapshot-agent-deployment.bats index 8e345189d7..23e323284a 100644 --- a/charts/consul/test/unit/client-snapshot-agent-deployment.bats +++ b/charts/consul/test/unit/client-snapshot-agent-deployment.bats @@ -88,93 +88,189 @@ load _helpers } #-------------------------------------------------------------------- -# global.acls.manageSystemACLs and snapshotAgent.configSecret +# global.acls.manageSystemACLs -@test "client/SnapshotAgentDeployment: no initContainer by default" { +@test "clientSnapshotAgent/Deployment: consul-logout preStop hook is added when ACLs are enabled" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.initContainers' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq '[.spec.template.spec.containers[0].lifecycle.preStop.exec.command[2]] | any(contains("/bin/consul logout"))' | tee /dev/stderr) + [ "${object}" = "true" ] } -@test "client/SnapshotAgentDeployment: populates initContainer when global.acls.manageSystemACLs=true" { +@test "clientSnapshotAgent/Deployment: CONSUL_HTTP_TOKEN_FILE is not set when acls are disabled" { cd `chart_dir` local actual=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.initContainers | length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq '[.spec.template.spec.containers[0].env[1].name] | any(contains("CONSUL_HTTP_TOKEN_FILE"))' | tee /dev/stderr) + [ "${actual}" = "false" ] } -@test "client/SnapshotAgentDeployment: no volumes by default" { +@test "clientSnapshotAgent/Deployment: CONSUL_HTTP_TOKEN_FILE is set when acls are enabled" { cd `chart_dir` local actual=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq '[.spec.template.spec.containers[0].env[2].name] | any(contains("CONSUL_HTTP_TOKEN_FILE"))' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: populates volumes when global.acls.manageSystemACLs=true" { +@test "clientSnapshotAgent/Deployment: init container is created when global.acls.manageSystemACLs=true" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "snapshot-agent-acl-init" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s-control-plane acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[1].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[1].value] | any(contains("http://$(HOST_IP):8500"))' | tee /dev/stderr) + echo $actual [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: populates volumes when client.snapshotAgent.configSecret.secretName and client.snapshotAgent.configSecret secretKey are defined" { +@test "clientSnapshotAgent/Deployment: init container is created when global.acls.manageSystemACLs=true and has correct command and environment with tls enabled" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'client.snapshotAgent.configSecret.secretName=secret' \ - --set 'client.snapshotAgent.configSecret.secretKey=key' \ + --set 'global.tls.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.volumes | length > 0' | tee /dev/stderr) + yq '.spec.template.spec.initContainers[] | select(.name == "snapshot-agent-acl-init")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s-control-plane acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[1].name] | any(contains("CONSUL_CACERT"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].value] | any(contains("https://$(HOST_IP):8501"))' | tee /dev/stderr) + echo $actual + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '.volumeMounts[1] | any(contains("consul-ca-cert"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: no container volumeMounts by default" { +@test "clientSnapshotAgent/Deployment: init container is created when global.acls.manageSystemACLs=true and has correct command with Partitions enabled" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.enableConsulNamespaces=true' \ + --set 'global.adminPartitions.enabled=true' \ + --set 'global.adminPartitions.name=default' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].volumeMounts' | tee /dev/stderr) - [ "${actual}" = "null" ] + yq '.spec.template.spec.initContainers[] | select(.name == "snapshot-agent-acl-init")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s-control-plane acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("-acl-auth-method=RELEASE-NAME-consul-k8s-component-auth-method"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq -r '.command | any(contains("-partition=default"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[1].name] | any(contains("CONSUL_CACERT"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].value] | any(contains("https://$(HOST_IP):8501"))' | tee /dev/stderr) + echo $actual + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '.volumeMounts[1] | any(contains("consul-ca-cert"))' | tee /dev/stderr) + [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: populates container volumeMounts when global.acls.manageSystemACLs=true" { +@test "clientSnapshotAgent/Deployment: init container is created when global.acls.manageSystemACLs=true and has correct command and environment with tls enabled and autoencrypt enabled" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) + yq '.spec.template.spec.initContainers[] | select(.name == "snapshot-agent-acl-init")' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.command | any(contains("consul-k8s-control-plane acl-init"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[1].name] | any(contains("CONSUL_CACERT"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].name] | any(contains("CONSUL_HTTP_ADDR"))' | tee /dev/stderr) + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '[.env[2].value] | any(contains("https://$(HOST_IP):8501"))' | tee /dev/stderr) + echo $actual + [ "${actual}" = "true" ] + + local actual=$(echo $object | + yq '.volumeMounts[1] | any(contains("consul-auto-encrypt-ca-cert"))' | tee /dev/stderr) [ "${actual}" = "true" ] } -@test "client/SnapshotAgentDeployment: populates container volumeMounts when client.snapshotAgent.configSecret.secretName and client.snapshotAgent.configSecret secretKey are defined" { +@test "clientSnapshotAgent/Deployment: auto-encrypt init container is created and is the first init-container when global.acls.manageSystemACLs=true and has correct command and environment with tls enabled and autoencrypt enabled" { cd `chart_dir` - local actual=$(helm template \ + local object=$(helm template \ -s templates/client-snapshot-agent-deployment.yaml \ --set 'client.snapshotAgent.enabled=true' \ - --set 'client.snapshotAgent.configSecret.secretName=secret' \ - --set 'client.snapshotAgent.configSecret.secretKey=key' \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.enableAutoEncrypt=true' \ + --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].volumeMounts | length > 0' | tee /dev/stderr) - [ "${actual}" = "true" ] + yq '.spec.template.spec.initContainers[0]' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.name' | tee /dev/stderr) + [ "${actual}" = "get-auto-encrypt-client-ca" ] } #-------------------------------------------------------------------- @@ -370,15 +466,9 @@ load _helpers --set 'client.snapshotAgent.caCert=-----BEGIN CERTIFICATE----- MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL' \ . | tee /dev/stderr | - yq -r '.spec.template.spec.containers[0].command[2]' | tee /dev/stderr) + yq -r '.spec.template.spec.containers[0].command[2] | contains("MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL")' | tee /dev/stderr) - exp='cat < /etc/ssl/certs/custom-ca.pem ------BEGIN CERTIFICATE----- -MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL -EOF -exec /bin/consul snapshot agent \' - - [ "${actual}" = "${exp}" ] + [ "${actual}" = "true" ] } #-------------------------------------------------------------------- diff --git a/charts/consul/test/unit/client-snapshot-agent-role.bats b/charts/consul/test/unit/client-snapshot-agent-role.bats index 8408010e80..86aaaf3880 100644 --- a/charts/consul/test/unit/client-snapshot-agent-role.bats +++ b/charts/consul/test/unit/client-snapshot-agent-role.bats @@ -53,31 +53,3 @@ load _helpers yq -r '.rules[0].resources[0]' | tee /dev/stderr) [ "${actual}" = "podsecuritypolicies" ] } - -#-------------------------------------------------------------------- -# global.acls.manageSystemACLs - -@test "client/SnapshotAgentRole: allows secret access with global.bootsrapACLs=true" { - cd `chart_dir` - local actual=$(helm template \ - -s templates/client-snapshot-agent-role.yaml \ - --set 'client.snapshotAgent.enabled=true' \ - --set 'client.enabled=true' \ - --set 'global.acls.manageSystemACLs=true' \ - . | tee /dev/stderr | - yq -r '.rules[0].resources[0]' | tee /dev/stderr) - [ "${actual}" = "secrets" ] -} - -@test "client/SnapshotAgentRole: allows secret access with global.bootsrapACLs=true and global.enablePodSecurityPolicies=true" { - cd `chart_dir` - local actual=$(helm template \ - -s templates/client-snapshot-agent-role.yaml \ - --set 'client.enabled=true' \ - --set 'client.snapshotAgent.enabled=true' \ - --set 'global.acls.manageSystemACLs=true' \ - --set 'global.enablePodSecurityPolicies=true' \ - . | tee /dev/stderr | - yq -r '.rules[1].resources[0]' | tee /dev/stderr) - [ "${actual}" = "secrets" ] -} diff --git a/charts/consul/test/unit/server-acl-init-job.bats b/charts/consul/test/unit/server-acl-init-job.bats index fcb997cf16..1582510948 100644 --- a/charts/consul/test/unit/server-acl-init-job.bats +++ b/charts/consul/test/unit/server-acl-init-job.bats @@ -225,7 +225,7 @@ load _helpers -s templates/server-acl-init-job.yaml \ --set 'global.acls.manageSystemACLs=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].command | any(contains("-snapshot-agent"))' | tee /dev/stderr) [ "${actual}" = "false" ] } @@ -236,7 +236,7 @@ load _helpers --set 'global.acls.manageSystemACLs=true' \ --set 'client.snapshotAgent.enabled=true' \ . | tee /dev/stderr | - yq '.spec.template.spec.containers[0].command | any(contains("-create-snapshot-agent-token"))' | tee /dev/stderr) + yq '.spec.template.spec.containers[0].command | any(contains("-snapshot-agent"))' | tee /dev/stderr) [ "${actual}" = "true" ] } diff --git a/control-plane/subcommand/server-acl-init/command.go b/control-plane/subcommand/server-acl-init/command.go index 4fafbebebe..6f19d45905 100644 --- a/control-plane/subcommand/server-acl-init/command.go +++ b/control-plane/subcommand/server-acl-init/command.go @@ -52,7 +52,7 @@ type Command struct { flagCreateEntLicenseToken bool - flagCreateSnapshotAgentToken bool + flagSnapshotAgent bool flagCreateMeshGatewayToken bool flagIngressGatewayNames []string @@ -144,7 +144,7 @@ func (c *Command) init() { c.flags.BoolVar(&c.flagCreateEntLicenseToken, "create-enterprise-license-token", false, "Toggle for creating a token for the enterprise license job.") - c.flags.BoolVar(&c.flagCreateSnapshotAgentToken, "create-snapshot-agent-token", false, + c.flags.BoolVar(&c.flagSnapshotAgent, "snapshot-agent", false, "[Enterprise Only] Toggle for creating a token for the Consul snapshot agent deployment.") c.flags.BoolVar(&c.flagCreateMeshGatewayToken, "create-mesh-gateway-token", false, "Toggle for creating a token for a Connect mesh gateway.") @@ -558,9 +558,9 @@ func (c *Command) Run(args []string) int { } } - if c.flagCreateSnapshotAgentToken { - err := c.createLocalACL("client-snapshot-agent", snapshotAgentRules, consulDC, primary, consulClient) - if err != nil { + if c.flagSnapshotAgent { + serviceAccountName := c.withPrefix("snapshot-agent") + if err := c.createACLPolicyRoleAndBindingRule("snapshot-agent", snapshotAgentRules, consulDC, primaryDC, localPolicy, primary, localComponentAuthMethodName, serviceAccountName, consulClient); err != nil { c.log.Error(err.Error()) return 1 } diff --git a/control-plane/subcommand/server-acl-init/command_ent_test.go b/control-plane/subcommand/server-acl-init/command_ent_test.go index 24f76a61e9..ee3b26ebe6 100644 --- a/control-plane/subcommand/server-acl-init/command_ent_test.go +++ b/control-plane/subcommand/server-acl-init/command_ent_test.go @@ -289,7 +289,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "-create-mesh-gateway-token", "-sync-catalog", "-connect-inject", - "-create-snapshot-agent-token", + "-snapshot-agent", "-create-enterprise-license-token", "-ingress-gateway-name=gw", "-ingress-gateway-name=anothergw", @@ -327,7 +327,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "client-token", "sync-catalog-policy", "mesh-gateway-token", - "client-snapshot-agent-token", + "snapshot-agent-policy", "enterprise-license-token", "gw-ingress-gateway-token", "anothergw-ingress-gateway-token", @@ -379,7 +379,7 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { "sync-catalog-policy", "connect-inject-policy", "mesh-gateway-token", - "client-snapshot-agent-token", + "snapshot-agent-policy", "enterprise-license-token", "cross-namespace-policy", "gw-ingress-gateway-token", @@ -411,11 +411,11 @@ func TestRun_ACLPolicyUpdates(t *testing.T) { require.True(ok, "Did not find policy %s", expected) switch expected { - case "connect-inject-token": + case "connect-inject-policy": // The connect inject token doesn't have namespace config, // but does change to operator:write from an empty string. require.Contains(actRules, "policy = \"write\"") - case "client-snapshot-agent-token", "enterprise-license-token": + case "snapshot-agent-policy", "enterprise-license-token": // The snapshot agent and enterprise license tokens shouldn't change. require.NotContains(actRules, "namespace") require.Contains(actRules, "acl = \"write\"") @@ -682,13 +682,6 @@ func TestRun_TokensWithNamespacesEnabled(t *testing.T) { SecretNames: []string{resourcePrefix + "-enterprise-license-acl-token"}, LocalToken: true, }, - "client-snapshot-agent token": { - TokenFlags: []string{"-create-snapshot-agent-token"}, - PolicyNames: []string{"client-snapshot-agent-token"}, - PolicyDCs: []string{"dc1"}, - SecretNames: []string{resourcePrefix + "-client-snapshot-agent-acl-token"}, - LocalToken: true, - }, "mesh-gateway token": { TokenFlags: []string{"-create-mesh-gateway-token"}, PolicyNames: []string{"mesh-gateway-token"}, diff --git a/control-plane/subcommand/server-acl-init/command_test.go b/control-plane/subcommand/server-acl-init/command_test.go index e010bb9153..a4df1b7d2d 100644 --- a/control-plane/subcommand/server-acl-init/command_test.go +++ b/control-plane/subcommand/server-acl-init/command_test.go @@ -178,14 +178,6 @@ func TestRun_TokensPrimaryDC(t *testing.T) { SecretNames: []string{resourcePrefix + "-enterprise-license-acl-token"}, LocalToken: true, }, - { - TestName: "Snapshot agent token", - TokenFlags: []string{"-create-snapshot-agent-token"}, - PolicyNames: []string{"client-snapshot-agent-token"}, - PolicyDCs: []string{"dc1"}, - SecretNames: []string{resourcePrefix + "-client-snapshot-agent-acl-token"}, - LocalToken: true, - }, { TestName: "Mesh gateway token", TokenFlags: []string{"-create-mesh-gateway-token"}, @@ -388,14 +380,6 @@ func TestRun_TokensReplicatedDC(t *testing.T) { SecretNames: []string{resourcePrefix + "-enterprise-license-acl-token"}, LocalToken: true, }, - { - TestName: "Snapshot agent token", - TokenFlags: []string{"-create-snapshot-agent-token"}, - PolicyNames: []string{"client-snapshot-agent-token-dc2"}, - PolicyDCs: []string{"dc2"}, - SecretNames: []string{resourcePrefix + "-client-snapshot-agent-acl-token"}, - LocalToken: true, - }, { TestName: "Mesh gateway token", TokenFlags: []string{"-create-mesh-gateway-token"}, @@ -508,12 +492,6 @@ func TestRun_TokensWithProvidedBootstrapToken(t *testing.T) { PolicyNames: []string{"enterprise-license-token"}, SecretNames: []string{resourcePrefix + "-enterprise-license-acl-token"}, }, - { - TestName: "Snapshot agent token", - TokenFlags: []string{"-create-snapshot-agent-token"}, - PolicyNames: []string{"client-snapshot-agent-token"}, - SecretNames: []string{resourcePrefix + "-client-snapshot-agent-acl-token"}, - }, { TestName: "Mesh gateway token", TokenFlags: []string{"-create-mesh-gateway-token"}, @@ -2145,6 +2123,12 @@ func TestRun_PoliciesAndBindingRulesForACLLogin_PrimaryDatacenter(t *testing.T) PolicyNames: []string{"api-gateway-controller-policy"}, Roles: []string{resourcePrefix + "-api-gateway-controller-acl-role"}, }, + { + TestName: "Snapshot Agent", + TokenFlags: []string{"-snapshot-agent"}, + PolicyNames: []string{"snapshot-agent-policy"}, + Roles: []string{resourcePrefix + "-snapshot-agent-acl-role"}, + }, } for _, c := range cases { t.Run(c.TestName, func(t *testing.T) { @@ -2263,6 +2247,13 @@ func TestRun_PoliciesAndBindingRulesACLLogin_SecondaryDatacenter(t *testing.T) { Roles: []string{resourcePrefix + "-api-gateway-controller-acl-role-" + secondaryDatacenter}, GlobalAuthMethod: false, }, + { + TestName: "Snapshot Agent", + TokenFlags: []string{"-snapshot-agent"}, + PolicyNames: []string{"snapshot-agent-policy-" + secondaryDatacenter}, + Roles: []string{resourcePrefix + "-snapshot-agent-acl-role-" + secondaryDatacenter}, + GlobalAuthMethod: false, + }, } for _, c := range cases { t.Run(c.TestName, func(t *testing.T) { @@ -2374,6 +2365,11 @@ func TestRun_ValidateLoginToken_PrimaryDatacenter(t *testing.T) { TokenFlags: []string{"-api-gateway-controller"}, Roles: []string{resourcePrefix + "-api-gateway-controller-acl-role"}, }, + { + ComponentName: "snapshot-agent", + TokenFlags: []string{"-snapshot-agent"}, + Roles: []string{resourcePrefix + "-snapshot-agent-acl-role"}, + }, } for _, c := range cases { t.Run(c.ComponentName, func(t *testing.T) { @@ -2474,6 +2470,12 @@ func TestRun_ValidateLoginToken_SecondaryDatacenter(t *testing.T) { Roles: []string{resourcePrefix + "-api-gateway-controller-acl-role-dc2"}, GlobalAuthMethod: false, }, + { + ComponentName: "snapshot-agent", + TokenFlags: []string{"-snapshot-agent"}, + Roles: []string{resourcePrefix + "-snapshot-agent-acl-role-dc2"}, + GlobalAuthMethod: false, + }, } for _, c := range cases { t.Run(c.ComponentName, func(t *testing.T) {