From 36e931572ed7cb0b6817ebe8f9478d33124bd32f Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Wed, 13 Mar 2024 14:07:53 -0700 Subject: [PATCH] Add external k8s bundler (#270) * Complete Server K8S PSAT support Add all the SPIRE Server supported options for the K8S PSAT attestor. This retains the ease of use for configuring local cluster support while adding the ability to configure multiple/external clusters as well. Kubeconfig support is added in its own config block as it will be used/shared with spire-controller-manager support in the future. Signed-off-by: Kevin Fox * Fix merge conflict Signed-off-by: Kevin Fox * Add support for integration tests in the tests/integration dir Signed-off-by: Kevin Fox * Fix split issue and typo Signed-off-by: Kevin Fox * Add basic psat test Signed-off-by: Kevin Fox * Fix linter Signed-off-by: Kevin Fox * Fix up test Signed-off-by: Kevin Fox * Add missing file Signed-off-by: Kevin Fox * Better encode config Signed-off-by: Kevin Fox * Update charts/spire/charts/spire-server/values.yaml Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Update docs Signed-off-by: Kevin Fox * Apply suggestions from code review Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Fix docs Signed-off-by: Kevin Fox * Update charts/spire/charts/spire-server/values.yaml Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Fix docs Signed-off-by: Kevin Fox * Add external k8s bundler Adds support to sync the CA bundle to configmaps in external Kubernetes clusters Signed-off-by: Kevin Fox * Update default Signed-off-by: Kevin Fox * Fix config file layout. Incorperate feedback. Signed-off-by: Kevin Fox * Incorperate feedback Signed-off-by: Kevin Fox * Update based on parent pr feedback Signed-off-by: Kevin Fox * Reformat config file Signed-off-by: Kevin Fox * Fix some things Signed-off-by: Kevin Fox * Reconfigure kind Signed-off-by: Kevin Fox * More debugging Signed-off-by: Kevin Fox * Fix up kind Signed-off-by: Kevin Fox * Incorperate feedback Signed-off-by: Kevin Fox --------- Signed-off-by: Kevin Fox Signed-off-by: kfox1111 Co-authored-by: Faisal Memon --- charts/spire/charts/spire-server/README.md | 6 +++++ .../spire-server/templates/configmap.yaml | 24 +++++++++++++++++++ charts/spire/charts/spire-server/values.yaml | 17 +++++++++++++ tests/integration/psat/run-tests.sh | 4 +++- 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index c04ec19..28105ea 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -223,7 +223,13 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `upstreamAuthority.vault.k8sAuth.k8sAuthRoleName` | Required - Name of the Vault role. The plugin authenticates against the named role | `""` | | `upstreamAuthority.vault.k8sAuth.token.audience` | Intended audience of the PSAT, it must match one of the audiences supported by the Kubernetes API server. If no audience is specified, it defaults to the identifier of API Server. See ['Service Account Documentation'](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection) for more info. | `vault` | | `upstreamAuthority.vault.k8sAuth.token.expiry` | Expiry time in seconds for the token | `7200` | +| `notifier.k8sbundle.enabled` | Enable local k8s bundle uploader | `true` | | `notifier.k8sbundle.namespace` | Namespace to push the bundle into, if blank will default to SPIRE Server namespace | `""` | +| `notifier.externalK8sBundle.enabled` | Enable exernal k8s bundle uploader | `true` | +| `notifier.externalK8sBundle.defaults.namespace` | Namespace to push the bundle into on clusters | `spire-system` | +| `notifier.externalK8sBundle.defaults.configMap` | ConfigMap name to push the bundle into on external clusters | `spire-bundle-upstream` | +| `notifier.externalK8sBundle.defaults.configMapKey` | ConfigMap key to push the bundle into on external clusters | `bundle.crt` | +| `notifier.externalK8sBundle.clusters` | A dictionary of clusters to add with optional overrides. If empty, all clusters defined in kubeConfigs will be used. | `{}` | | `controllerManager.enabled` | Flag to enable controller manager | `false` | | `controllerManager.className` | specify to use an explicit class name. If empty, it will be automatically set to Release.Namespace-Release.Name to not conflict with other installs, enabling parallel installs. | `""` | | `controllerManager.watchClassless` | specify to process custom resources without class name specified. Useful to slowly migrate to class names from classless installs. Do not have two installs on the same k8s cluster both set to true. | `false` | diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index 743657d..8ee8d5e 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -205,11 +205,35 @@ plugins: {{- fail (printf "You have to enable exactly one Key Manager. There are %d enabled." $keyManagerUsed) }} {{- end }} + {{- if or .Values.notifier.k8sbundle.enabled .Values.notifier.externalK8sBundle.enabled }} Notifier: k8sbundle: plugin_data: + {{- if eq (.Values.notifier.k8sbundle.enabled | toString) "true" }} namespace: {{ include "spire-server.bundle-namespace" . | quote }} config_map: {{ include "spire-lib.bundle-configmap" . | quote }} + {{- end }} + {{- $clusters := default .Values.kubeConfigs .Values.notifier.externalK8sBundle.clusters }} + {{- if and (eq (.Values.notifier.externalK8sBundle.enabled | toString) "true") (ne (len $clusters) 0) }} + clusters: + - "": + {{- $clusterDefaults := .Values.notifier.externalK8sBundle.defaults }} + {{- range $name, $_ := $clusters }} + {{- $clusterSettings := dict }} + {{- if hasKey $root.Values.notifier.externalK8sBundle.clusters $name }} + {{- $clusterSettings = index $root.Values.notifier.externalK8sBundle.clusters $name }} + {{- end }} + {{- if hasKey $clusterSettings "kubeConfigName" }} + - kube_config_file_path: /kubeconfigs/{{ $clusterSettings.kubeConfigName }} + {{- else }} + - kube_config_file_path: /kubeconfigs/{{ $name }} + {{- end }} + namespace: {{ if hasKey $clusterSettings "namespace" }}{{ $clusterSettings.namespace }}{{ else }}{{ $clusterDefaults.namespace }}{{ end }} + config_map: {{ if hasKey $clusterSettings "configMap" }}{{ $clusterSettings.configMap }}{{ else }}{{ $clusterDefaults.configMap }}{{ end }} + config_map_key: {{ if hasKey $clusterSettings "configMapKey" }}{{ $clusterSettings.configMapKey }}{{ else }}{{ $clusterDefaults.configMapKey }}{{ end }} + {{- end }} + {{- end }} + {{- end }} {{- with .Values.upstreamAuthority.disk }} {{- if eq (.enabled | toString) "true" }} diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index c3fffe8..12ca6ed 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -423,8 +423,25 @@ upstreamAuthority: notifier: k8sbundle: + ## @param notifier.k8sbundle.enabled Enable local k8s bundle uploader + enabled: true ## @param notifier.k8sbundle.namespace Namespace to push the bundle into, if blank will default to SPIRE Server namespace namespace: "" + externalK8sBundle: + ## @param notifier.externalK8sBundle.enabled Enable exernal k8s bundle uploader + enabled: true + defaults: + ## @param notifier.externalK8sBundle.defaults.namespace Namespace to push the bundle into on clusters + namespace: "spire-system" + ## @param notifier.externalK8sBundle.defaults.configMap ConfigMap name to push the bundle into on external clusters + configMap: "spire-bundle-upstream" + ## @param notifier.externalK8sBundle.defaults.configMapKey ConfigMap key to push the bundle into on external clusters + configMapKey: "bundle.crt" + ## @param notifier.externalK8sBundle.clusters [object] A dictionary of clusters to add with optional overrides. If empty, all clusters defined in kubeConfigs will be used. + clusters: {} + # clustera: + # namespace: foo + # clusterb: {} controllerManager: ## @param controllerManager.enabled Flag to enable controller manager diff --git a/tests/integration/psat/run-tests.sh b/tests/integration/psat/run-tests.sh index bbcc22d..6b7785a 100755 --- a/tests/integration/psat/run-tests.sh +++ b/tests/integration/psat/run-tests.sh @@ -59,8 +59,10 @@ kind create cluster --name other --kubeconfig "${SCRIPTPATH}/kubeconfig" --confi md5sum "${SCRIPTPATH}/kubeconfig" wc -l "${SCRIPTPATH}/kubeconfig" KCB64="$(base64 < "${SCRIPTPATH}/kubeconfig" | tr '\n' ' ' | sed 's/ //g')" +kubectl --kubeconfig "${SCRIPTPATH}/kubeconfig" create namespace spire-system +kubectl --kubeconfig "${SCRIPTPATH}/kubeconfig" create configmap -n spire-system spire-bundle-upstream helm upgrade --install --create-namespace --namespace spire-server --values "${SCRIPTPATH}/values.yaml" \ --wait spire charts/spire --set "spire-server.kubeConfigs.other.kubeConfigBase64=$KCB64" helm test --namespace spire-server spire - +kubectl --kubeconfig "${SCRIPTPATH}/kubeconfig" get configmap -n spire-system spire-bundle-upstream