From 020bde8561d69a20c3a64b8dee60ffb9d6dc9bab Mon Sep 17 00:00:00 2001 From: Drew Wells Date: Fri, 16 Jun 2023 16:04:11 -0500 Subject: [PATCH] Add support to create a issuer and CA via cert-manager (#342) Co-authored-by: Kevin Fox --- .../cert-manager-ca.yaml | 31 ----------- .../pre-install.sh | 2 - .../values.yaml | 3 +- charts/spire/README.md | 18 ++++-- charts/spire/charts/spire-server/README.md | 18 ++++-- .../spire-server/templates/configmap.yaml | 2 +- .../charts/spire-server/templates/issuer.yaml | 55 +++++++++++++++++++ .../templates/post-install-hook.yaml | 2 +- .../templates/post-upgrade-hook.yaml | 2 +- .../templates/pre-upgrade-hook.yaml | 2 +- .../charts/spire-server/templates/roles.yaml | 1 + .../spire-server/templates/statefulset.yaml | 17 +++++- charts/spire/charts/spire-server/values.yaml | 41 +++++++++----- 13 files changed, 130 insertions(+), 64 deletions(-) delete mode 100644 .github/tests/upstream-authority-cert-manager/cert-manager-ca.yaml create mode 100644 charts/spire/charts/spire-server/templates/issuer.yaml diff --git a/.github/tests/upstream-authority-cert-manager/cert-manager-ca.yaml b/.github/tests/upstream-authority-cert-manager/cert-manager-ca.yaml deleted file mode 100644 index dbbe201..0000000 --- a/.github/tests/upstream-authority-cert-manager/cert-manager-ca.yaml +++ /dev/null @@ -1,31 +0,0 @@ ---- -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: selfsigned-issuer -spec: - selfSigned: {} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: demo-selfsigned-ca -spec: - isCA: true - commonName: demo-selfsigned-ca - secretName: root-secret - privateKey: - algorithm: ECDSA - size: 256 - issuerRef: - name: selfsigned-issuer - kind: Issuer - group: cert-manager.io ---- -apiVersion: cert-manager.io/v1 -kind: Issuer -metadata: - name: demo-ca -spec: - ca: - secretName: root-secret diff --git a/.github/tests/upstream-authority-cert-manager/pre-install.sh b/.github/tests/upstream-authority-cert-manager/pre-install.sh index 9508f5d..69f25fd 100755 --- a/.github/tests/upstream-authority-cert-manager/pre-install.sh +++ b/.github/tests/upstream-authority-cert-manager/pre-install.sh @@ -5,5 +5,3 @@ SCRIPTPATH="$(dirname "${SCRIPT}")" scenario="${scenario:-$(basename "${SCRIPTPATH}")}" helm install cert-manager cert-manager --namespace cert-manager --create-namespace --version "$VERSION_CERT_MANAGER" --set installCRDs=true --repo "$HELM_REPO_CERT_MANAGER" --wait -SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -kubectl apply -f "${SCRIPT_DIR}/cert-manager-ca.yaml" -n "$scenario" diff --git a/.github/tests/upstream-authority-cert-manager/values.yaml b/.github/tests/upstream-authority-cert-manager/values.yaml index 08fbec7..ddb0a5a 100644 --- a/.github/tests/upstream-authority-cert-manager/values.yaml +++ b/.github/tests/upstream-authority-cert-manager/values.yaml @@ -2,4 +2,5 @@ spire-server: upstreamAuthority: certManager: enabled: true - issuer_name: "demo-ca" + ca: + create: true diff --git a/charts/spire/README.md b/charts/spire/README.md index 54298da..010941d 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -306,11 +306,6 @@ Now you can interact with the Spire agent socket from your own application. The | spire-server.controllerManager.service.port | int | `443` | | | spire-server.controllerManager.service.type | string | `"ClusterIP"` | | | spire-server.controllerManager.validatingWebhookConfiguration.failurePolicy | string | `"Fail"` | | -| spire-server.controllerManager.validatingWebhookConfiguration.upgradeHook.image.pullPolicy | string | `"IfNotPresent"` | The image pull policy | -| spire-server.controllerManager.validatingWebhookConfiguration.upgradeHook.image.registry | string | `"docker.io"` | The OCI registry to pull the image from | -| spire-server.controllerManager.validatingWebhookConfiguration.upgradeHook.image.repository | string | `"rancher/kubectl"` | The repository within the registry | -| spire-server.controllerManager.validatingWebhookConfiguration.upgradeHook.image.tag | string | `""` | Overrides the image tag | -| spire-server.controllerManager.validatingWebhookConfiguration.upgradeHook.image.version | string | `""` | This value is deprecated in favor of tag. (Will be removed in a future release) | | spire-server.dataStore.sql.databaseName | string | `"spire"` | Only used by "postgres" or "mysql" | | spire-server.dataStore.sql.databaseType | string | `"sqlite3"` | Other supported databases are "postgres" and "mysql" | | spire-server.dataStore.sql.host | string | `""` | Only used by "postgres" or "mysql" | @@ -382,6 +377,11 @@ Now you can interact with the Spire agent socket from your own application. The | spire-server.telemetry.prometheus.podMonitor.labels | object | `{}` | | | spire-server.telemetry.prometheus.podMonitor.namespace | string | `""` | Override where to install the podMonitor, if not set will use the same namespace as the spire-server | | spire-server.tolerations | list | `[]` | | +| spire-server.tools.kubectl.image.pullPolicy | string | `"IfNotPresent"` | The image pull policy | +| spire-server.tools.kubectl.image.registry | string | `"docker.io"` | The OCI registry to pull the image from | +| spire-server.tools.kubectl.image.repository | string | `"rancher/kubectl"` | The repository within the registry | +| spire-server.tools.kubectl.image.tag | string | `""` | Overrides the image tag | +| spire-server.tools.kubectl.image.version | string | `""` | This value is deprecated in favor of tag. (Will be removed in a future release) | | spire-server.topologySpreadConstraints | list | `[]` | | | spire-server.tornjak.config.dataStore | object | `{"driver":"sqlite3","file":"/run/spire/data/tornjak.sqlite3"}` | persistent DB for storing Tornjak specific information | | spire-server.tornjak.enabled | bool | `false` | Deploys Tornjak API (backend) (Not for production) | @@ -400,10 +400,16 @@ Now you can interact with the Spire agent socket from your own application. The | spire-server.tornjak.startupProbe.successThreshold | int | `1` | | | spire-server.tornjak.startupProbe.timeoutSeconds | int | `5` | | | spire-server.trustDomain | string | `"example.org"` | Set the trust domain to be used for the SPIFFE identifiers | +| spire-server.upstreamAuthority.certManager.ca.create | bool | `false` | Creates a Cert-Manager CA | +| spire-server.upstreamAuthority.certManager.ca.duration | string | `"87600h"` | Duration of the CA. Defaults to 10 years. | +| spire-server.upstreamAuthority.certManager.ca.privateKey.algorithm | string | `"ECDSA"` | | +| spire-server.upstreamAuthority.certManager.ca.privateKey.rotationPolicy | string | `""` | | +| spire-server.upstreamAuthority.certManager.ca.privateKey.size | int | `256` | | +| spire-server.upstreamAuthority.certManager.ca.renewBefore | string | `""` | How long to wait before renewing the CA | | spire-server.upstreamAuthority.certManager.enabled | bool | `false` | | | spire-server.upstreamAuthority.certManager.issuer_group | string | `"cert-manager.io"` | | | spire-server.upstreamAuthority.certManager.issuer_kind | string | `"Issuer"` | | -| spire-server.upstreamAuthority.certManager.issuer_name | string | `"spire-ca"` | | +| spire-server.upstreamAuthority.certManager.issuer_name | string | `""` | Defaults to the release name, override if CA is provided outside of the chart | | spire-server.upstreamAuthority.certManager.kube_config_file | string | `""` | | | spire-server.upstreamAuthority.certManager.namespace | string | `""` | Specify to use a namespace other then the one the chart is installed into | | spire-server.upstreamAuthority.certManager.rbac.create | bool | `true` | | diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index fc2e78a..36bcbe4 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -67,11 +67,6 @@ A Helm chart to install the SPIRE server. | controllerManager.service.port | int | `443` | | | controllerManager.service.type | string | `"ClusterIP"` | | | controllerManager.validatingWebhookConfiguration.failurePolicy | string | `"Fail"` | | -| controllerManager.validatingWebhookConfiguration.upgradeHook.image.pullPolicy | string | `"IfNotPresent"` | The image pull policy | -| controllerManager.validatingWebhookConfiguration.upgradeHook.image.registry | string | `"docker.io"` | The OCI registry to pull the image from | -| controllerManager.validatingWebhookConfiguration.upgradeHook.image.repository | string | `"rancher/kubectl"` | The repository within the registry | -| controllerManager.validatingWebhookConfiguration.upgradeHook.image.tag | string | `""` | Overrides the image tag | -| controllerManager.validatingWebhookConfiguration.upgradeHook.image.version | string | `""` | This value is deprecated in favor of tag. (Will be removed in a future release) | | dataStore.sql.databaseName | string | `"spire"` | Only used by "postgres" or "mysql" | | dataStore.sql.databaseType | string | `"sqlite3"` | Other supported databases are "postgres" and "mysql" | | dataStore.sql.host | string | `""` | Only used by "postgres" or "mysql" | @@ -143,6 +138,11 @@ A Helm chart to install the SPIRE server. | telemetry.prometheus.podMonitor.labels | object | `{}` | | | telemetry.prometheus.podMonitor.namespace | string | `""` | Override where to install the podMonitor, if not set will use the same namespace as the spire-server | | tolerations | list | `[]` | | +| tools.kubectl.image.pullPolicy | string | `"IfNotPresent"` | The image pull policy | +| tools.kubectl.image.registry | string | `"docker.io"` | The OCI registry to pull the image from | +| tools.kubectl.image.repository | string | `"rancher/kubectl"` | The repository within the registry | +| tools.kubectl.image.tag | string | `""` | Overrides the image tag | +| tools.kubectl.image.version | string | `""` | This value is deprecated in favor of tag. (Will be removed in a future release) | | topologySpreadConstraints | list | `[]` | | | tornjak.config.dataStore | object | `{"driver":"sqlite3","file":"/run/spire/data/tornjak.sqlite3"}` | persistent DB for storing Tornjak specific information | | tornjak.enabled | bool | `false` | Deploys Tornjak API (backend) (Not for production) | @@ -161,10 +161,16 @@ A Helm chart to install the SPIRE server. | tornjak.startupProbe.successThreshold | int | `1` | | | tornjak.startupProbe.timeoutSeconds | int | `5` | | | trustDomain | string | `"example.org"` | Set the trust domain to be used for the SPIFFE identifiers | +| upstreamAuthority.certManager.ca.create | bool | `false` | Creates a Cert-Manager CA | +| upstreamAuthority.certManager.ca.duration | string | `"87600h"` | Duration of the CA. Defaults to 10 years. | +| upstreamAuthority.certManager.ca.privateKey.algorithm | string | `"ECDSA"` | | +| upstreamAuthority.certManager.ca.privateKey.rotationPolicy | string | `""` | | +| upstreamAuthority.certManager.ca.privateKey.size | int | `256` | | +| upstreamAuthority.certManager.ca.renewBefore | string | `""` | How long to wait before renewing the CA | | upstreamAuthority.certManager.enabled | bool | `false` | | | upstreamAuthority.certManager.issuer_group | string | `"cert-manager.io"` | | | upstreamAuthority.certManager.issuer_kind | string | `"Issuer"` | | -| upstreamAuthority.certManager.issuer_name | string | `"spire-ca"` | | +| upstreamAuthority.certManager.issuer_name | string | `""` | Defaults to the release name, override if CA is provided outside of the chart | | upstreamAuthority.certManager.kube_config_file | string | `""` | | | upstreamAuthority.certManager.namespace | string | `""` | Specify to use a namespace other then the one the chart is installed into | | upstreamAuthority.certManager.rbac.create | bool | `true` | | diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index ad22824..cf53d48 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -78,7 +78,7 @@ plugins: UpstreamAuthority: - cert-manager: plugin_data: - issuer_name: {{ .issuer_name | quote }} + issuer_name: {{ default .issuer_name (include "spire-server.fullname" $root) }} issuer_kind: {{ .issuer_kind | quote }} issuer_group: {{ .issuer_group | quote }} namespace: {{ default $root.Release.Namespace .namespace | quote }} diff --git a/charts/spire/charts/spire-server/templates/issuer.yaml b/charts/spire/charts/spire-server/templates/issuer.yaml new file mode 100644 index 0000000..4ce6c25 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/issuer.yaml @@ -0,0 +1,55 @@ +{{- with .Values.upstreamAuthority.certManager }} +{{ if and .enabled .ca.create }} +{{/* +Configuring CA Issuer: https://cert-manager.io/docs/configuration/ca/ +*/}} +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "spire-server.fullname" $ }}-selfsigned + namespace: {{ include "spire-server.namespace" $ }} + labels: + {{- include "spire-server.labels" $ | nindent 4}} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "spire-server.fullname" $ }} + namespace: {{ include "spire-server.namespace" $ }} +spec: + isCA: true + commonName: {{ $.Values.ca_subject.common_name }} + secretName: {{ include "spire-server.fullname" $ }}-ca-keys + duration: {{ $.Values.upstreamAuthority.certManager.ca.duration }} + subject: + countries: + - {{ $.Values.ca_subject.country }} + organizations: + - {{ $.Values.ca_subject.organization }} + privateKey: + algorithm: {{ $.Values.upstreamAuthority.certManager.ca.privateKey.algorithm }} + size: {{ $.Values.upstreamAuthority.certManager.ca.privateKey.size }} + {{- with $.Values.upstreamAuthority.certManager.ca.privateKey.rotationPolicy }} + rotationPolicy: {{ . }} + {{- end }} + {{- with $.Values.upstreamAuthority.certManager.ca.renewBefore }} + renewBefore: {{ . }} + {{- end }} + issuerRef: + name: {{ include "spire-server.fullname" $ }}-selfsigned + kind: Issuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "spire-server.fullname" $ }} + namespace: {{ include "spire-server.namespace" $ }} +spec: + ca: + secretName: {{ include "spire-server.fullname" $ }}-ca-keys +--- +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/post-install-hook.yaml b/charts/spire/charts/spire-server/templates/post-install-hook.yaml index 39607e2..98d6ac9 100644 --- a/charts/spire/charts/spire-server/templates/post-install-hook.yaml +++ b/charts/spire/charts/spire-server/templates/post-install-hook.yaml @@ -63,7 +63,7 @@ spec: - name: post-install-job securityContext: {{- toYaml .Values.securityContext | nindent 10 }} - image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} + image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.kubectl.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} args: - patch - validatingwebhookconfiguration diff --git a/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml b/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml index d518116..b179be4 100644 --- a/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml +++ b/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml @@ -63,7 +63,7 @@ spec: - name: post-upgrade-job securityContext: {{- toYaml .Values.securityContext | nindent 10 }} - image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} + image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.kubectl.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} args: - patch - validatingwebhookconfiguration diff --git a/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml b/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml index 47f8ab1..54f9ae0 100644 --- a/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml +++ b/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml @@ -63,7 +63,7 @@ spec: - name: post-install-job securityContext: {{- toYaml .Values.securityContext | nindent 10 }} - image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} + image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.kubectl.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} args: - patch - validatingwebhookconfiguration diff --git a/charts/spire/charts/spire-server/templates/roles.yaml b/charts/spire/charts/spire-server/templates/roles.yaml index fc08e6a..6c667e7 100644 --- a/charts/spire/charts/spire-server/templates/roles.yaml +++ b/charts/spire/charts/spire-server/templates/roles.yaml @@ -24,6 +24,7 @@ rules: - apiGroups: ["cert-manager.io"] resources: - certificaterequests + - issuers verbs: - list - get diff --git a/charts/spire/charts/spire-server/templates/statefulset.yaml b/charts/spire/charts/spire-server/templates/statefulset.yaml index 883bbcb..1540dd0 100644 --- a/charts/spire/charts/spire-server/templates/statefulset.yaml +++ b/charts/spire/charts/spire-server/templates/statefulset.yaml @@ -42,8 +42,23 @@ spec: shareProcessNamespace: true securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} - {{- if gt (len .Values.initContainers) 0 }} initContainers: + {{- if and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.createCA }} + - name: wait + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ template "spire-server.kubectl-image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image "global" .Values.global "KubeVersion" .Capabilities.KubeVersion.Version) }} + args: + - wait + - --namespace + - {{ .Release.Namespace }} + - --timeout=3m + - --for=condition=ready + - issuer + - {{ include "spire-server.fullname" $ }} + imagePullPolicy: {{ .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image.pullPolicy }} + {{- end }} + {{- if gt (len .Values.initContainers) 0 }} {{- toYaml .Values.initContainers | nindent 8 }} {{- end }} containers: diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 564d4f5..17095b0 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -188,12 +188,25 @@ upstreamAuthority: enabled: false rbac: create: true - issuer_name: "spire-ca" + # -- Defaults to the release name, override if CA is provided outside of the chart + issuer_name: "" issuer_kind: "Issuer" issuer_group: "cert-manager.io" # -- Specify to use a namespace other then the one the chart is installed into namespace: "" kube_config_file: "" + + ca: + # -- Creates a Cert-Manager CA + create: false + # -- Duration of the CA. Defaults to 10 years. + duration: 87600h + privateKey: + algorithm: ECDSA + size: 256 + rotationPolicy: "" + # -- How long to wait before renewing the CA + renewBefore: "" spire: enabled: false server: @@ -269,18 +282,20 @@ controllerManager: validatingWebhookConfiguration: failurePolicy: Fail - upgradeHook: - image: - # -- The OCI registry to pull the image from - registry: docker.io - # -- The repository within the registry - repository: rancher/kubectl - # -- The image pull policy - pullPolicy: IfNotPresent - # -- This value is deprecated in favor of tag. (Will be removed in a future release) - version: "" - # -- Overrides the image tag - tag: "" + +tools: + kubectl: + image: + # -- The OCI registry to pull the image from + registry: docker.io + # -- The repository within the registry + repository: rancher/kubectl + # -- The image pull policy + pullPolicy: IfNotPresent + # -- This value is deprecated in favor of tag. (Will be removed in a future release) + version: "" + # -- Overrides the image tag + tag: "" telemetry: prometheus: