diff --git a/.github/tests/extras/values.yaml b/.github/tests/extras/values.yaml index 274bc39..41a416e 100644 --- a/.github/tests/extras/values.yaml +++ b/.github/tests/extras/values.yaml @@ -1,7 +1,7 @@ spire-agent: initContainers: - name: extra-init - image: busybox + image: cgr.dev/chainguard/busybox:latest-glibc command: - sh - -xec @@ -12,7 +12,7 @@ spire-agent: mountPath: /extra extraContainers: - name: extra - image: busybox + image: cgr.dev/chainguard/busybox:latest-glibc command: - sh - -xec @@ -32,7 +32,7 @@ spire-agent: spire-server: initContainers: - name: extra-init - image: busybox + image: cgr.dev/chainguard/busybox:latest-glibc command: - sh - -xec @@ -43,7 +43,7 @@ spire-server: mountPath: /extra extraContainers: - name: extra - image: busybox + image: cgr.dev/chainguard/busybox:latest-glibc command: - sh - -xec diff --git a/.github/tests/federation-bundle-endpoint/values.yaml b/.github/tests/federation-bundle-endpoint/values.yaml new file mode 100644 index 0000000..6b7d104 --- /dev/null +++ b/.github/tests/federation-bundle-endpoint/values.yaml @@ -0,0 +1,3 @@ +spire-server: + federation: + enabled: true diff --git a/.github/tests/lockdown/.env b/.github/tests/lockdown/.env deleted file mode 100644 index 7b6e741..0000000 --- a/.github/tests/lockdown/.env +++ /dev/null @@ -1 +0,0 @@ -export EXTRA_HELM_ARGS="--values=examples/production/values.yaml" diff --git a/.github/tests/lockdown/pre-install.sh b/.github/tests/lockdown/pre-install.sh deleted file mode 100755 index 8336be0..0000000 --- a/.github/tests/lockdown/pre-install.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -kubectl create namespace "spire-system" -kubectl label namespace "spire-system" pod-security.kubernetes.io/enforce=privileged -kubectl create namespace "spire-server" -kubectl label namespace "spire-server" pod-security.kubernetes.io/enforce=restricted diff --git a/.github/tests/lockdown/values.yaml b/.github/tests/lockdown/values.yaml deleted file mode 100644 index 3260fb5..0000000 --- a/.github/tests/lockdown/values.yaml +++ /dev/null @@ -1,5 +0,0 @@ -spiffe-oidc-discovery-provider: - namespaceOverride: spire-server - -spire-server: - namespaceOverride: spire-server diff --git a/.github/tests/lockdown/post-install.sh b/.github/tests/namespace-override/post-install.sh similarity index 76% rename from .github/tests/lockdown/post-install.sh rename to .github/tests/namespace-override/post-install.sh index d93ebd9..c565da6 100755 --- a/.github/tests/lockdown/post-install.sh +++ b/.github/tests/namespace-override/post-install.sh @@ -5,17 +5,29 @@ set -x SCRIPT=$(readlink -f "$0") SCRIPTPATH=$(dirname "$SCRIPT") -k_wait=(kubectl wait --for condition=available --timeout 30s --namespace) -k_rollout_status=(kubectl rollout status --watch --timeout 30s --namespace) +k_wait () { + kubectl wait --for condition=available --timeout 30s --namespace "$1" "$2" "$3" | tail -n 1 +} + +k_rollout_status () { + kubectl rollout status --watch --timeout 30s --namespace "$1" "$2" "$3" | tail -n 1 +} + +RELEASE=$(helm ls --no-headers -n "${scenario}" | awk '{print $1}' | grep 'spire-[^-]*$') cat <>"$GITHUB_STEP_SUMMARY" +### release +| release | +| ------- | +| $RELEASE | + ### spire | workload | Status | | -------- | ------ | -| spire-server | $("${k_rollout_status[@]}" spire-server statefulset spire-server) | -| spire-spiffe-csi-driver | $("${k_rollout_status[@]}" spire-system daemonset spire-spiffe-csi-driver) | -| spire-agent | $("${k_rollout_status[@]}" spire-system daemonset spire-agent) | -| spire-spiffe-oidc-discovery-provider | $("${k_wait[@]}" spire-server deployments.apps spire-spiffe-oidc-discovery-provider) | +| spire-server |
$(k_rollout_status spire-server statefulset "${RELEASE}-server")
| +| spire-spiffe-csi-driver |
$(k_rollout_status spire-system daemonset "${RELEASE}-spiffe-csi-driver")
| +| spire-agent |
$(k_rollout_status spire-system daemonset "${RELEASE}-agent")
| +| spire-spiffe-oidc-discovery-provider |
$(k_wait spire-server deployments.apps "${RELEASE}-spiffe-oidc-discovery-provider")
| EOF if [ $1 -ne 0 ]; then diff --git a/.github/tests/namespace-override/pre-install.sh b/.github/tests/namespace-override/pre-install.sh new file mode 100755 index 0000000..91bd6f0 --- /dev/null +++ b/.github/tests/namespace-override/pre-install.sh @@ -0,0 +1,3 @@ +#!/bin/bash +kubectl create namespace "spire-system" +kubectl create namespace "spire-server" diff --git a/.github/tests/namespace-override/values.yaml b/.github/tests/namespace-override/values.yaml new file mode 100644 index 0000000..36a4336 --- /dev/null +++ b/.github/tests/namespace-override/values.yaml @@ -0,0 +1,26 @@ +spiffe-oidc-discovery-provider: + enabled: true + namespaceOverride: spire-server + insecureScheme: + enabled: true + +spire-server: + namespaceOverride: spire-server + nodeAttestor: + k8sPsat: + serviceAccountAllowList: ["spire-system:spire-agent"] + notifier: + k8sbundle: + namespace: spire-system + +spiffe-csi-driver: + enabled: true + namespaceOverride: spire-system + +spire-agent: + enabled: true + namespaceOverride: spire-system + serviceAccount: + name: spire-agent + server: + namespaceOverride: spire-server diff --git a/.github/tests/production-example/install.sh b/.github/tests/production-example/install.sh new file mode 100755 index 0000000..442a97b --- /dev/null +++ b/.github/tests/production-example/install.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -xe + +SCRIPT=$(readlink -f "$0") +SCRIPTPATH=$(dirname "$SCRIPT") + +helm install \ + --namespace spire-server \ + --values "${SCRIPTPATH}/../../../examples/production/values.yaml" \ + spire charts/spire --wait + +helm test spire --namespace spire-server diff --git a/.github/tests/production-example/post-install.sh b/.github/tests/production-example/post-install.sh new file mode 100755 index 0000000..ee0963e --- /dev/null +++ b/.github/tests/production-example/post-install.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +set -x + +SCRIPT=$(readlink -f "$0") +SCRIPTPATH=$(dirname "$SCRIPT") + +k_wait=(kubectl wait --for condition=available --timeout 30s --namespace) +k_rollout_status=(kubectl rollout status --watch --timeout 30s --namespace) + +function get_namespace_details { +cat <>"$GITHUB_STEP_SUMMARY" +### Namespace $1 + +#### Events + +\`\`\`shell +$(kubectl --request-timeout=30s get events --output wide --namespace "$1") +\`\`\` + +#### Pods + +\`\`\`shell +$(kubectl --request-timeout=30s describe pods --namespace "$1") +\`\`\` + +#### Logs + +\`\`\`shell +$(kubectl get pods -o name -n "$1" | while read -r line; do echo logs for "${line}"; kubectl logs -n "$1" "${line}" --all-containers=true --ignore-errors=true; done) +\`\`\` + +EOF +} + +cat <>"$GITHUB_STEP_SUMMARY" +### spire + +| workload | Status | +| ------------------------------------ | ------ | +| spire-server | "$("${k_rollout_status[@]}" spire-server statefulset spire-server)" | +| spire-controller-manager | "$("${k_rollout_status[@]}" spire-server statefulset spire-controller-manager)" | +| spire-spiffe-oidc-discovery-provider | "$("${k_wait[@]}" spire-server deployments.apps spire-spiffe-oidc-discovery-provider)" | +| spire-spiffe-csi-driver | "$("${k_rollout_status[@]}" spire-system daemonset spire-spiffe-csi-driver)" | +| spire-agent | "$("${k_rollout_status[@]}" spire-system daemonset spire-agent)" | +EOF + +if [ $1 -ne 0 ]; then + get_namespace_details spire-server + get_namespace_details spire-systen +fi diff --git a/.github/tests/production-example/pre-install.sh b/.github/tests/production-example/pre-install.sh new file mode 100755 index 0000000..b33d1ed --- /dev/null +++ b/.github/tests/production-example/pre-install.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +kubectl create namespace spire-system +kubectl label namespace spire-system pod-security.kubernetes.io/enforce=privileged +kubectl create namespace spire-server +kubectl label namespace spire-server pod-security.kubernetes.io/enforce=restricted diff --git a/.github/tests/prometheus/pre-install.sh b/.github/tests/prometheus/pre-install.sh new file mode 100755 index 0000000..5959a16 --- /dev/null +++ b/.github/tests/prometheus/pre-install.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +helm install kube-prometheus-stack kube-prometheus-stack --version 45.7.1 --repo https://prometheus-community.github.io/helm-charts -n "$scenario" --wait diff --git a/.github/tests/prometheus/values.yaml b/.github/tests/prometheus/values.yaml index b66af8d..a0886e4 100644 --- a/.github/tests/prometheus/values.yaml +++ b/.github/tests/prometheus/values.yaml @@ -2,3 +2,12 @@ global: telemetry: prometheus: enabled: true + podMonitor: + enabled: true + labels: + release: kube-prometheus-stack + +spiffe-oidc-discovery-provider: + enabled: true + insecureScheme: + enabled: true diff --git a/.github/workflows/helm-chart-ci.yaml b/.github/workflows/helm-chart-ci.yaml index 7cee295..c6755c8 100644 --- a/.github/workflows/helm-chart-ci.yaml +++ b/.github/workflows/helm-chart-ci.yaml @@ -10,6 +10,7 @@ on: - '.github/kind/conf/kind-config.yaml' - '.github/tests/**/*.yaml' - '.github/tests/**/*.sh' + - 'examples/**/*.yaml' - 'helm-docs.sh' concurrency: @@ -19,25 +20,60 @@ concurrency: env: HELM_VERSION: v3.11.1 PYTHON_VERSION: 3.11.2 - CHART_TESTING_VERSION: v3.7.1 + CHART_TESTING_VERSION: v3.8.0 jobs: - check-docs: + checks: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 - name: Verify Docs updated run: ./helm-docs.sh + - name: Verify Spire appVersion + run: | + set +e + BASEVER=$(yq e .appVersion Chart.yaml) + for FILE in spiffe-oidc-discovery-provider spire-agent spire-server; do + VER=$(yq .appVersion charts/$FILE/Chart.yaml) + if [ "$VER" != "$BASEVER" ]; then + { + echo "## Version mismatch" + echo + echo "There is a mismatch between the chart version ($BASEVER) and subchart version ($VER). The issue may be in file $FILE. Please fix." + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + done + + - name: Check objects for images without overrides + run: | + set +e + set -o pipefail + # Look for image: definitions that are not templated. If we find none, exit is not 0 and we invert the error code to get the + # test to pass. Ignore tests for now... + grep "image:" charts/spire/charts/*/templates/*.* | grep -v 'image: {{ template "' > /tmp/findings + res=$? + if [ $res -eq 0 ]; then + { + echo "## Hardcoded images" + echo + echo ":x: These templates were found to be using statically defined images and not overridable ones. Please fix." + echo + cat /tmp/findings + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + lint-chart: runs-on: ubuntu-22.04 steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 with: fetch-depth: 0 @@ -52,7 +88,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Setup chart-testing - uses: helm/chart-testing-action@v2.3.1 + uses: helm/chart-testing-action@v2.4.0 with: version: ${{ env.CHART_TESTING_VERSION }} @@ -82,7 +118,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 - id: set-matrix name: Collect all tests @@ -122,7 +158,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 with: fetch-depth: 0 @@ -137,7 +173,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Setup chart-testing - uses: helm/chart-testing-action@v2.3.1 + uses: helm/chart-testing-action@v2.4.0 with: version: ${{ env.CHART_TESTING_VERSION }} @@ -152,23 +188,28 @@ jobs: - name: Run chart-testing (install) run: | - export scenario="$(basename "${TEST_DIR}")" - export EXTRA_HELM_ARGS="" - [ "${scenario}" != "default" ] && kubectl create namespace "${scenario}" post-install() { [ -x "${TEST_DIR}/post-install.sh" ] && "${TEST_DIR}/post-install.sh" $1 exit $1 } + trap 'post-install $? $LINENO' EXIT + + export scenario="$(basename "${TEST_DIR}")" + export EXTRA_HELM_ARGS="" + + [ "${scenario}" != "default" ] && kubectl create namespace "${scenario}" [ -x "${TEST_DIR}/pre-install.sh" ] && "${TEST_DIR}/pre-install.sh" [ -f "${TEST_DIR}/.env" ] && source "${TEST_DIR}/.env" - if [ -x {${TEST_DIR}/install.sh ]; then - ./${TEST_DIR}/install.sh + + if [ -x "${TEST_DIR}/install.sh" ]; then + "${TEST_DIR}/install.sh" else ct install --debug \ --namespace "${scenario}" \ --target-branch ${{ github.base_ref }} \ --exclude-deprecated \ + --skip-clean-up \ ${{ (matrix.values != 'default' && '--helm-extra-set-args "--values=${TEST_DIR}/values.yaml ${EXTRA_HELM_ARGS}"') || '' }} fi env: diff --git a/.github/workflows/helm-release.yaml b/.github/workflows/helm-release.yaml index f85d48d..ec04daf 100644 --- a/.github/workflows/helm-release.yaml +++ b/.github/workflows/helm-release.yaml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3.4.0 + uses: actions/checkout@v3.5.0 with: fetch-depth: 0 diff --git a/CODEOWNERS b/CODEOWNERS index 0a45229..97468c2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,6 +2,6 @@ # the repo. Unless a later match takes precedence, # they will be requested for review when someone opens a # pull request. -* @marcofranssen @Kfox1111 @developer-guy @dennisgove @dfeldman @faisal-memon @mrsabath +* @marcofranssen @Kfox1111 @developer-guy @dfeldman @faisal-memon @mrsabath # See CODEOWNERS syntax here: https://help.github.com/articles/about-codeowners/#codeowners-syntax diff --git a/README.md b/README.md index d450fab..d5e947b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ # SPIFFE Helm Charts -[![Apache 2.0 License](https://img.shields.io/github/license/spiffe/helm-charts?style=for-the-badge)](https://opensource.org/licenses/Apache-2.0) +[![Apache 2.0 License](https://img.shields.io/github/license/spiffe/helm-charts)](https://opensource.org/licenses/Apache-2.0) +[![Development Phase](https://github.com/spiffe/spiffe/blob/main/.img/maturity/dev.svg)](https://github.com/spiffe/spiffe/blob/main/MATURITY.md#development) +[![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/spiffe)](https://artifacthub.io/packages/search?repo=spiffe) A suite of [Helm Charts](https://helm.sh/docs) for standardized installations of SPIRE components in Kubernetes environments. @@ -21,8 +23,9 @@ Unless otherwise noted in an application chart README, the following dependencie |:-----------|:-------------------| | SPIRE | `1.5.3`+, `1.6.x` | | Helm | `3.x` | +| Kubernetes | `1.21+` | -For Kubernetes we will officially try to support the last 3 versions as described in [k8s versioning](https://kubernetes.io/releases/version-skew-policy/#supported-versions). +> **Note**: For Kubernetes, we will officially support the last 3 versions as described in [k8s versioning](https://kubernetes.io/releases/version-skew-policy/#supported-versions). Any version before the last 3 we will try to support as long it doesn't bring security issues or any big maintenance burden. *The first version we tested this chart with is `1.21`.* ## Contributing diff --git a/charts/spire/Chart.yaml b/charts/spire/Chart.yaml index 33585ad..8519d5c 100644 --- a/charts/spire/Chart.yaml +++ b/charts/spire/Chart.yaml @@ -3,7 +3,7 @@ name: spire description: > A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager. type: application -version: 0.5.1 +version: 0.6.0 appVersion: "1.6.1" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts/tree/main/charts/spire diff --git a/charts/spire/README.md b/charts/spire/README.md index 20b945f..4b083eb 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -2,7 +2,7 @@ -![Version: 0.5.1](https://img.shields.io/badge/Version-0.5.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.6.1](https://img.shields.io/badge/AppVersion-1.6.1-informational?style=flat-square) +![Version: 0.6.0](https://img.shields.io/badge/Version-0.6.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.6.1](https://img.shields.io/badge/AppVersion-1.6.1-informational?style=flat-square) [![Development Phase](https://github.com/spiffe/spiffe/blob/main/.img/maturity/dev.svg)](https://github.com/spiffe/spiffe/blob/main/MATURITY.md#development) A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager. @@ -19,6 +19,9 @@ A Helm chart for deploying the complete Spire stack including: spire-server, spi |:-----------|:-------------------| | SPIRE | `1.5.3+`, `1.6.x` | | Helm | `3.x` | +| Kubernetes | `1.21+` | + +> **Note**: For Kubernetes, we will officially support the last 3 versions as described in [k8s versioning](https://kubernetes.io/releases/version-skew-policy/#supported-versions). Any version before the last 3 we will try to support as long it doesn't bring security issues or any big maintenance burden. *The first version we tested this chart with is `1.21`.* ## Prerequisites @@ -105,20 +108,17 @@ Kubernetes: `>=1.21.0-0` | Key | Type | Default | Description | |-----|------|---------|-------------| | fullnameOverride | string | `""` | | +| global.k8s.clusterDomain | string | `"cluster.local"` | | +| global.spire.bundleConfigMap | string | `""` | Override all instances of bundleConfigMap | +| global.spire.clusterName | string | `"example-cluster"` | Set the name of the Kubernetes cluster | +| global.spire.trustDomain | string | `"example.org"` | Set the trust domain to use for the spiffe identifiers | | nameOverride | string | `""` | | | spiffe-csi-driver.enabled | bool | `true` | | | spiffe-oidc-discovery-provider.enabled | bool | `false` | | -| spiffe-oidc-discovery-provider.trustDomain | string | `"example.org"` | | -| spire-agent.bundleConfigMap | string | `"spire-bundle"` | | -| spire-agent.clusterName | string | `"example-cluster"` | | | spire-agent.enabled | bool | `true` | | | spire-agent.nameOverride | string | `"agent"` | | -| spire-agent.trustDomain | string | `"example.org"` | | -| spire-server.bundleConfigMap | string | `"spire-bundle"` | | -| spire-server.clusterName | string | `"example-cluster"` | | | spire-server.controllerManager.enabled | bool | `true` | | | spire-server.enabled | bool | `true` | | | spire-server.nameOverride | string | `"server"` | | -| spire-server.trustDomain | string | `"example.org"` | | ---------------------------------------------- diff --git a/charts/spire/README.md.gotmpl b/charts/spire/README.md.gotmpl index a5fdd06..70823d0 100644 --- a/charts/spire/README.md.gotmpl +++ b/charts/spire/README.md.gotmpl @@ -21,6 +21,9 @@ |:-----------|:-------------------| | SPIRE | `1.5.3+`, `1.6.x` | | Helm | `3.x` | +| Kubernetes | `1.21+` | + +> **Note**: For Kubernetes, we will officially support the last 3 versions as described in [k8s versioning](https://kubernetes.io/releases/version-skew-policy/#supported-versions). Any version before the last 3 we will try to support as long it doesn't bring security issues or any big maintenance burden. *The first version we tested this chart with is `1.21`.* ## Prerequisites diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md index b5dd649..3504e7f 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md @@ -21,6 +21,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | autoscaling.minReplicas | int | `1` | | | autoscaling.targetCPUUtilizationPercentage | int | `80` | | | autoscaling.targetMemoryUtilizationPercentage | int | `80` | | +| clusterDomain | string | `"cluster.local"` | | | config.acme.cacheDir | string | `"/run/spire"` | | | config.acme.directoryUrl | string | `"https://acme-v02.api.letsencrypt.org/directory"` | | | config.acme.emailAddress | string | `"letsencrypt@example.org"` | | @@ -67,6 +68,9 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | telemetry.prometheus.nginxExporter.image.repository | string | `"nginx/nginx-prometheus-exporter"` | | | telemetry.prometheus.nginxExporter.image.version | string | `"0.11.0"` | | | telemetry.prometheus.nginxExporter.resources | object | `{}` | | +| telemetry.prometheus.podMonitor.enabled | bool | `false` | | +| 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 spiffe-oidc-discovery-provider | | telemetry.prometheus.port | int | `9988` | | | tolerations | list | `[]` | | | trustDomain | string | `"example.org"` | | diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/_helpers.tpl b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/_helpers.tpl index 6ff4768..139e151 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/_helpers.tpl +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/_helpers.tpl @@ -34,6 +34,16 @@ Allow the release namespace to be overridden for multi-namespace deployments in {{- end -}} {{- end -}} +{{- define "spiffe-oidc-discovery-provider.podMonitor.namespace" -}} + {{- if ne (len .Values.telemetry.prometheus.podMonitor.namespace) 0 }} + {{- .Values.telemetry.prometheus.podMonitor.namespace }} + {{- else if ne (len (dig "telemetry" "prometheus" "podMonitor" "namespace" "" .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.namespace }} + {{- else }} + {{- include "spiffe-oidc-discovery-provider.namespace" . }} + {{- end }} +{{- end -}} + {{/* Create chart name and version as used by the chart label. */}} @@ -87,3 +97,27 @@ Create the name of the service account to use {{- define "spiffe-oidc-discovery-provider.workload-api-socket-path" -}} {{- printf "/spiffe-workload-api/%s" .Values.agentSocketName }} {{- end }} + +{{- define "spiffe-oidc-discovery-provider.cluster-name" }} +{{- if ne (len (dig "spire" "clusterName" "" .Values.global)) 0 }} +{{- .Values.global.spire.clusterName }} +{{- else }} +{{- .Values.clusterName }} +{{- end }} +{{- end }} + +{{- define "spiffe-oidc-discovery-provider.trust-domain" }} +{{- if ne (len (dig "spire" "trustDomain" "" .Values.global)) 0 }} +{{- .Values.global.spire.trustDomain }} +{{- else }} +{{- .Values.trustDomain }} +{{- end }} +{{- end }} + +{{- define "spiffe-oidc-discovery-provider.cluster-domain" }} +{{- if ne (len (dig "k8s" "clusterDomain" "" .Values.global)) 0 }} +{{- .Values.global.k8s.clusterDomain }} +{{- else }} +{{- .Values.clusterDomain }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml index 70308ad..a0ec2bf 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/configmap.yaml @@ -11,7 +11,7 @@ data: domains = [ "{{ include "spiffe-oidc-discovery-provider.fullname" . }}", "{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}", - "{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}.svc.cluster.local", + "{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}.svc.{{ include "spiffe-oidc-discovery-provider.cluster-domain" . }}", {{- if gt (len .Values.config.domains) 0 }} "{{- join "\",\n \"" .Values.config.domains }}" {{- end }} diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/podmonitor.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/podmonitor.yaml new file mode 100644 index 0000000..dec060f --- /dev/null +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/podmonitor.yaml @@ -0,0 +1,29 @@ +{{- if .Values.insecureScheme.enabled }} +{{- if (dig "telemetry" "prometheus" "podMonitor" "enabled" .Values.telemetry.prometheus.podMonitor.enabled .Values.global) }} +{{- $namespace := include "spiffe-oidc-discovery-provider.podMonitor.namespace" . }} +{{- $podNamespace := ( include "spiffe-oidc-discovery-provider.namespace" . ) }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "spire-agent.fullname" . }} + namespace: {{ $namespace }} + labels: + {{- include "spire-agent.labels" . | nindent 4 }} + {{- if ne (len (dig "telemetry" "prometheus" "podMonitor" "labels" (dict) .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.telemetry.prometheus.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "spire-agent.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: prom + {{- if ne $namespace $podNamespace }} + namespaceSelector: + kubernetes.io/metadata.name: {{ $podNamespace }} + {{- end }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/tests/test-connection.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/tests/test-connection.yaml index 70ab843..e687868 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/tests/test-connection.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/tests/test-connection.yaml @@ -11,29 +11,29 @@ spec: securityContext: {{- toYaml .Values.podSecurityContext | nindent 4 }} containers: - - name: wget-service-name - image: busybox - command: ['wget'] - args: ['-O', '/dev/null', '{{ include "spiffe-oidc-discovery-provider.fullname" . }}:{{ .Values.service.port }}/.well-known/openid-configuration'] + - name: curl-service-name + image: cgr.dev/chainguard/bash:latest + command: ['curl'] + args: ['-s', '-f', 'http://{{ include "spiffe-oidc-discovery-provider.fullname" . }}:{{ .Values.service.port }}/.well-known/openid-configuration'] securityContext: {{- toYaml .Values.securityContext | nindent 8 }} - - name: wget-service-name-namespace - image: busybox - command: ['wget'] - args: ['-O', '/dev/null', '{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}:{{ .Values.service.port }}/.well-known/openid-configuration'] + - name: curl-service-name-namespace + image: cgr.dev/chainguard/bash:latest + command: ['curl'] + args: ['-s', '-f', 'http://{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}:{{ .Values.service.port }}/.well-known/openid-configuration'] securityContext: {{- toYaml .Values.securityContext | nindent 8 }} - - name: wget-service-name-namespace-svc-cluster-local - image: busybox - command: ['wget'] - args: ['-O', '/dev/null', '{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/.well-known/openid-configuration'] + - name: curl-service-name-namespace-svc-cluster-local + image: cgr.dev/chainguard/bash:latest + command: ['curl'] + args: ['-s', '-f', 'http://{{ include "spiffe-oidc-discovery-provider.fullname" . }}.{{ include "spiffe-oidc-discovery-provider.namespace" . }}.svc.{{ include "spiffe-oidc-discovery-provider.cluster-domain" . }}:{{ .Values.service.port }}/.well-known/openid-configuration'] securityContext: {{- toYaml .Values.securityContext | nindent 8 }} {{- if .Values.ingress.enabled }} - - name: wget-ingress - image: busybox - command: ['wget'] - args: ['-O', '/dev/null', '{{ index .Values.config.domains 0 }}/.well-known/openid-configuration'] + - name: curl-ingress + image: cgr.dev/chainguard/bash:latest + command: ['curl'] + args: ['-s', '-f', 'http://{{ index .Values.config.domains 0 }}/.well-known/openid-configuration'] securityContext: {{- toYaml .Values.securityContext | nindent 8 }} {{- end }} diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml index 88f53b0..1424301 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml @@ -113,11 +113,18 @@ tolerations: [] affinity: {} trustDomain: example.org +# -- This is the value of your clusters `kubeadm init --service-dns-domain` flag +clusterDomain: cluster.local telemetry: prometheus: enabled: false port: 9988 + podMonitor: + enabled: false + # -- Override where to install the podMonitor, if not set will use the same namespace as the spiffe-oidc-discovery-provider + namespace: "" + labels: {} nginxExporter: image: diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index e8a9665..035c857 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -44,6 +44,9 @@ A Helm chart to install the SPIRE agent. | serviceAccount.name | string | `""` | | | socketPath | string | `"/run/spire/agent-sockets/spire-agent.sock"` | | | telemetry.prometheus.enabled | bool | `false` | | +| telemetry.prometheus.podMonitor.enabled | bool | `false` | | +| 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-agent | | telemetry.prometheus.port | int | `9988` | | | trustDomain | string | `"example.org"` | | | waitForIt.image.pullPolicy | string | `"IfNotPresent"` | | diff --git a/charts/spire/charts/spire-agent/templates/_helpers.tpl b/charts/spire/charts/spire-agent/templates/_helpers.tpl index f3704fc..ff43724 100644 --- a/charts/spire/charts/spire-agent/templates/_helpers.tpl +++ b/charts/spire/charts/spire-agent/templates/_helpers.tpl @@ -42,6 +42,16 @@ Allow the release namespace to be overridden for multi-namespace deployments in {{- end -}} {{- end -}} +{{- define "spire-agent.podMonitor.namespace" -}} + {{- if ne (len .Values.telemetry.prometheus.podMonitor.namespace) 0 }} + {{- .Values.telemetry.prometheus.podMonitor.namespace }} + {{- else if ne (len (dig "telemetry" "prometheus" "podMonitor" "namespace" "" .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.namespace }} + {{- else }} + {{- include "spire-agent.namespace" . }} + {{- end }} +{{- end -}} + {{/* Create chart name and version as used by the chart label. */}} @@ -103,3 +113,27 @@ Create the name of the service account to use {{- define "spire-agent.socket-path" -}} {{- print .Values.socketPath }} {{- end }} + +{{- define "spire-agent.cluster-name" }} +{{- if ne (len (dig "spire" "clusterName" "" .Values.global)) 0 }} +{{- .Values.global.spire.clusterName }} +{{- else }} +{{- .Values.clusterName }} +{{- end }} +{{- end }} + +{{- define "spire-agent.trust-domain" }} +{{- if ne (len (dig "spire" "trustDomain" "" .Values.global)) 0 }} +{{- .Values.global.spire.trustDomain }} +{{- else }} +{{- .Values.trustDomain }} +{{- end }} +{{- end }} + +{{- define "spire-agent.bundle-configmap" }} +{{- if ne (len (dig "spire" "bundleConfigMap" "" .Values.global)) 0 }} +{{- .Values.global.spire.bundleConfigMap }} +{{- else }} +{{- .Values.bundleConfigMap }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-agent/templates/configmap.yaml b/charts/spire/charts/spire-agent/templates/configmap.yaml index 9d368e8..900f526 100644 --- a/charts/spire/charts/spire-agent/templates/configmap.yaml +++ b/charts/spire/charts/spire-agent/templates/configmap.yaml @@ -12,13 +12,13 @@ data: server_port = {{ .Values.server.port | quote }} socket_path = {{ include "spire-agent.socket-path" . | quote }} trust_bundle_path = "/run/spire/bundle/bundle.crt" - trust_domain = {{ .Values.trustDomain | quote }} + trust_domain = {{ include "spire-agent.trust-domain" . | quote }} } plugins { NodeAttestor "k8s_psat" { plugin_data { - cluster = {{ .Values.clusterName | quote }} + cluster = {{ include "spire-agent.cluster-name" . | quote }} } } diff --git a/charts/spire/charts/spire-agent/templates/daemonset.yaml b/charts/spire/charts/spire-agent/templates/daemonset.yaml index 503c171..10c2603 100644 --- a/charts/spire/charts/spire-agent/templates/daemonset.yaml +++ b/charts/spire/charts/spire-agent/templates/daemonset.yaml @@ -100,7 +100,7 @@ spec: name: {{ include "spire-agent.fullname" . }} - name: spire-bundle configMap: - name: {{ .Values.bundleConfigMap }} + name: {{ include "spire-agent.bundle-configmap" . }} - name: spire-token projected: sources: diff --git a/charts/spire/charts/spire-agent/templates/podmonitor.yaml b/charts/spire/charts/spire-agent/templates/podmonitor.yaml new file mode 100644 index 0000000..92fd0e3 --- /dev/null +++ b/charts/spire/charts/spire-agent/templates/podmonitor.yaml @@ -0,0 +1,27 @@ +{{- if (dig "telemetry" "prometheus" "podMonitor" "enabled" .Values.telemetry.prometheus.podMonitor.enabled .Values.global) }} +{{- $namespace := include "spiffe-oidc-discovery-provider.podMonitor.namespace" . }} +{{- $podNamespace := ( include "spiffe-oidc-discovery-provider.namespace" . ) }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "spiffe-oidc-discovery-provider.fullname" . }} + namespace: {{ $namespace }} + labels: + {{- include "spiffe-oidc-discovery-provider.labels" . | nindent 4 }} + {{- if ne (len (dig "telemetry" "prometheus" "podMonitor" "labels" (dict) .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.telemetry.prometheus.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "spiffe-oidc-discovery-provider.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: prom + {{- if ne $namespace $podNamespace }} + namespaceSelector: + kubernetes.io/metadata.name: {{ $podNamespace }} + {{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-agent/values.yaml b/charts/spire/charts/spire-agent/values.yaml index a2b47db..e5bca41 100644 --- a/charts/spire/charts/spire-agent/values.yaml +++ b/charts/spire/charts/spire-agent/values.yaml @@ -86,6 +86,11 @@ telemetry: prometheus: enabled: false port: 9988 + podMonitor: + enabled: false + # -- Override where to install the podMonitor, if not set will use the same namespace as the spire-agent + namespace: "" + labels: {} socketPath: /run/spire/agent-sockets/spire-agent.sock diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 4f085d5..8a6abd7 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -22,12 +22,13 @@ A Helm chart to install the SPIRE server. | autoscaling.maxReplicas | int | `100` | | | autoscaling.minReplicas | int | `1` | | | autoscaling.targetCPUUtilizationPercentage | int | `80` | | -| bundleConfigMap | string | `"spire-server"` | | +| bundleConfigMap | string | `"spire-bundle"` | | | caKeyType | string | `"rsa-2048"` | The CA key type to use, possible values are rsa-2048, rsa-4096, ec-p256, ec-p384 (AWS requires the use of RSA. EC cryptography is not supported) | | caTTL | string | `"24h"` | | | ca_subject.common_name | string | `"example.org"` | | | ca_subject.country | string | `"NL"` | | | ca_subject.organization | string | `"Example"` | | +| clusterDomain | string | `"cluster.local"` | | | clusterName | string | `"example-cluster"` | | | controllerManager.enabled | bool | `false` | | | controllerManager.identities.dnsNameTemplates | list | `[]` | | @@ -48,6 +49,10 @@ 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"` | | +| controllerManager.validatingWebhookConfiguration.upgradeHook.image.registry | string | `"cgr.dev"` | | +| controllerManager.validatingWebhookConfiguration.upgradeHook.image.repository | string | `"chainguard/kubectl"` | | +| controllerManager.validatingWebhookConfiguration.upgradeHook.image.version | string | `"latest"` | | | dataStorage.accessMode | string | `"ReadWriteOnce"` | | | dataStorage.enabled | bool | `true` | | | dataStorage.size | string | `"1Gi"` | | @@ -57,6 +62,9 @@ A Helm chart to install the SPIRE server. | extraContainers | list | `[]` | | | extraVolumeMounts | list | `[]` | | | extraVolumes | list | `[]` | | +| federation.bundleEndpoint.address | string | `"0.0.0.0"` | | +| federation.bundleEndpoint.port | int | `8443` | | +| federation.enabled | bool | `false` | | | fullnameOverride | string | `""` | | | image.pullPolicy | string | `"IfNotPresent"` | | | image.registry | string | `"ghcr.io"` | | @@ -84,6 +92,9 @@ A Helm chart to install the SPIRE server. | serviceAccount.create | bool | `true` | | | serviceAccount.name | string | `""` | | | telemetry.prometheus.enabled | bool | `false` | | +| telemetry.prometheus.podMonitor.enabled | bool | `false` | | +| 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 | `[]` | | | topologySpreadConstraints | list | `[]` | | | trustDomain | string | `"example.org"` | | diff --git a/charts/spire/charts/spire-server/templates/_helpers.tpl b/charts/spire/charts/spire-server/templates/_helpers.tpl index 7e7c45c..809aeb3 100644 --- a/charts/spire/charts/spire-server/templates/_helpers.tpl +++ b/charts/spire/charts/spire-server/templates/_helpers.tpl @@ -34,6 +34,16 @@ Allow the release namespace to be overridden for multi-namespace deployments in {{- end -}} {{- end -}} +{{- define "spire-server.podMonitor.namespace" -}} + {{- if ne (len .Values.telemetry.prometheus.podMonitor.namespace) 0 }} + {{- .Values.telemetry.prometheus.podMonitor.namespace }} + {{- else if ne (len (dig "telemetry" "prometheus" "podMonitor" "namespace" "" .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.namespace }} + {{- else }} + {{- include "spire-server.namespace" . }} + {{- end }} +{{- end -}} + {{/* Create chart name and version as used by the chart label. */}} @@ -84,7 +94,6 @@ Create the name of the service account to use {{- end -}} {{- end }} - {{- define "spire-server.upstream-ca-secret" -}} {{- $root := . }} {{- with .Values.upstreamAuthority.disk -}} @@ -100,10 +109,6 @@ Create the name of the service account to use {{ include "spire-server.fullname" . | trimSuffix "-server" }}-controller-manager {{- end }} -{{- define "spire-k8s-workload-registrar.fullname" -}} -{{ include "spire-server.fullname" . | trimSuffix "-server" }}-k8s-workload-registrar -{{- end }} - {{- define "spire-server.serviceAccountAllowedList" }} {{- if ne (len .Values.nodeAttestor.k8sPsat.serviceAccountAllowList) 0 }} {{- .Values.nodeAttestor.k8sPsat.serviceAccountAllowList | toJson }} @@ -111,3 +116,35 @@ Create the name of the service account to use [{{ printf "%s:%s-agent" .Release.Namespace .Release.Name | quote }}] {{- end }} {{- end }} + +{{- define "spire-server.cluster-name" }} +{{- if ne (len (dig "spire" "clusterName" "" .Values.global)) 0 }} +{{- .Values.global.spire.clusterName }} +{{- else }} +{{- .Values.clusterName }} +{{- end }} +{{- end }} + +{{- define "spire-server.trust-domain" }} +{{- if ne (len (dig "spire" "trustDomain" "" .Values.global)) 0 }} +{{- .Values.global.spire.trustDomain }} +{{- else }} +{{- .Values.trustDomain }} +{{- end }} +{{- end }} + +{{- define "spire-server.bundle-configmap" }} +{{- if ne (len (dig "spire" "bundleConfigMap" "" .Values.global)) 0 }} +{{- .Values.global.spire.bundleConfigMap }} +{{- else }} +{{- .Values.bundleConfigMap }} +{{- end }} +{{- end }} + +{{- define "spire-server.cluster-domain" -}} +{{- if ne (len (dig "k8s" "clusterDomain" "" .Values.global)) 0 }} +{{- .Values.global.k8s.clusterDomain }} +{{- else }} +{{- .Values.clusterDomain }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/bundle-configmap.yaml b/charts/spire/charts/spire-server/templates/bundle-configmap.yaml index 948c120..bbc2fb5 100644 --- a/charts/spire/charts/spire-server/templates/bundle-configmap.yaml +++ b/charts/spire/charts/spire-server/templates/bundle-configmap.yaml @@ -2,5 +2,5 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ .Values.bundleConfigMap }} + name: {{ include "spire-server.bundle-configmap" . }} namespace: {{ .Values.notifier.k8sbundle.namespace | default $namespace }} diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index 03f148a..d1143f5 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -10,7 +10,7 @@ data: server { bind_address = "0.0.0.0" bind_port = "8081" - trust_domain = {{ .Values.trustDomain | quote }} + trust_domain = {{ include "spire-server.trust-domain" . | quote }} data_dir = "/run/spire/data" log_level = {{ .Values.logLevel | quote }} @@ -29,6 +29,17 @@ data: common_name = {{ .common_name | quote }}, {{- end }} } + + {{- with .Values.federation }} + {{- if eq (.enabled | toString) "true" }} + federation { + bundle_endpoint { + address = "{{ .bundleEndpoint.address }}" + port = {{ .bundleEndpoint.port }} + } + } + {{- end }} + {{- end }} } plugins { @@ -44,7 +55,7 @@ data: NodeAttestor "k8s_psat" { plugin_data { clusters = { - {{ $root.Values.clusterName | quote }} = { + {{ include "spire-server.cluster-name" $root | quote }} = { service_account_allow_list = {{ include "spire-server.serviceAccountAllowedList" $root | trim }} } } @@ -62,7 +73,7 @@ data: Notifier "k8sbundle" { plugin_data { namespace = {{ .Values.notifier.k8sbundle.namespace | default $namespace | quote }} - config_map = {{ .Values.bundleConfigMap | quote }} + config_map = {{ include "spire-server.bundle-configmap" . | quote }} } } diff --git a/charts/spire/charts/spire-server/templates/controller-manager-configmap.yaml b/charts/spire/charts/spire-server/templates/controller-manager-configmap.yaml index ebf9ee8..0509a56 100644 --- a/charts/spire/charts/spire-server/templates/controller-manager-configmap.yaml +++ b/charts/spire/charts/spire-server/templates/controller-manager-configmap.yaml @@ -22,8 +22,8 @@ data: resourceName: {{ .Release.Name | sha256sum | trunc 8 }}.spiffe.io resourceNamespace: {{ include "spire-server.namespace" . }} validatingWebhookConfigurationName: {{ include "spire-controller-manager.fullname" . }}-webhook - clusterName: {{ .Values.clusterName }} - trustDomain: {{ .Values.trustDomain }} + clusterName: {{ include "spire-server.cluster-name" . }} + trustDomain: {{ include "spire-server.trust-domain" . }} ignoreNamespaces: {{- with .Values.controllerManager.ignoreNamespaces }} {{- toYaml . | nindent 6 }} diff --git a/charts/spire/charts/spire-server/templates/controller-manager-webhook.yaml b/charts/spire/charts/spire-server/templates/controller-manager-webhook.yaml index 1e55403..4216396 100644 --- a/charts/spire/charts/spire-server/templates/controller-manager-webhook.yaml +++ b/charts/spire/charts/spire-server/templates/controller-manager-webhook.yaml @@ -10,7 +10,7 @@ webhooks: name: {{ include "spire-controller-manager.fullname" . }}-webhook namespace: {{ include "spire-server.namespace" . }} path: /validate-spire-spiffe-io-v1alpha1-clusterfederatedtrustdomain - failurePolicy: {{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }} + failurePolicy: Ignore # Actual value to be set by post install/upgrade hooks name: vclusterfederatedtrustdomain.kb.io rules: - apiGroups: ["spire.spiffe.io"] @@ -24,7 +24,7 @@ webhooks: name: {{ include "spire-controller-manager.fullname" . }}-webhook namespace: {{ include "spire-server.namespace" . }} path: /validate-spire-spiffe-io-v1alpha1-clusterspiffeid - failurePolicy: {{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }} + failurePolicy: Ignore # Actual value to be set by post install/upgrade hooks name: vclusterspiffeid.kb.io rules: - apiGroups: ["spire.spiffe.io"] diff --git a/charts/spire/charts/spire-server/templates/podmonitor.yaml b/charts/spire/charts/spire-server/templates/podmonitor.yaml new file mode 100644 index 0000000..878a4ba --- /dev/null +++ b/charts/spire/charts/spire-server/templates/podmonitor.yaml @@ -0,0 +1,27 @@ +{{- if (dig "telemetry" "prometheus" "podMonitor" "enabled" .Values.telemetry.prometheus.podMonitor.enabled .Values.global) }} +{{- $namespace := include "spire-server.podMonitor.namespace" . }} +{{- $podNamespace := ( include "spire-server.namespace" . ) }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "spire-server.fullname" . }} + namespace: {{ $namespace }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + {{- if ne (len (dig "telemetry" "prometheus" "podMonitor" "labels" (dict) .Values.global)) 0 }} + {{- .Values.global.telemetry.prometheus.podMonitor.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.telemetry.prometheus.podMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "spire-server.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: prom + {{- if ne $namespace $podNamespace }} + namespaceSelector: + kubernetes.io/metadata.name: {{ $podNamespace }} + {{- 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 new file mode 100644 index 0000000..d30893d --- /dev/null +++ b/charts/spire/charts/spire-server/templates/post-install-hook.yaml @@ -0,0 +1,85 @@ +{{- if eq (.Values.controllerManager.enabled | toString) "true" }} +{{- if eq .Values.controllerManager.validatingWebhookConfiguration.failurePolicy "Fail" }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "spire-server.serviceAccountName" . }}-post-install + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "spire-server.fullname" . }}-post-install + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +rules: + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations"] + resourceNames: [{{ printf "%s-webhook" (include "spire-controller-manager.fullname" .) | quote }}] + verbs: ["get", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "spire-server.fullname" . }}-post-install + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +subjects: + - kind: ServiceAccount + name: {{ include "spire-server.serviceAccountName" . }}-post-install + namespace: {{ include "spire-server.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "spire-server.fullname" . }}-post-install + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "spire-server.fullname" . }}-post-install + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ include "spire-server.fullname" . }}-post-install + spec: + restartPolicy: Never + serviceAccountName: {{ include "spire-server.serviceAccountName" . }}-post-install + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: post-install-job + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + image: {{ template "spire-server.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image) }} + command: + - /bin/sh + - -c + - |- + kubectl patch validatingwebhookconfiguration {{ include "spire-controller-manager.fullname" . }}-webhook --type='strategic' -p ' + { + "webhooks":[ + { + "name":"vclusterspiffeid.kb.io", + "failurePolicy":"{{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }}" + }, + { + "name":"vclusterfederatedtrustdomain.kb.io", + "failurePolicy":"{{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }}" + } + ] + }' +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml b/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml new file mode 100644 index 0000000..a6fd319 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/post-upgrade-hook.yaml @@ -0,0 +1,85 @@ +{{- if eq (.Values.controllerManager.enabled | toString) "true" }} +{{- if eq .Values.controllerManager.validatingWebhookConfiguration.failurePolicy "Fail" }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "spire-server.serviceAccountName" . }}-post-upgrade + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "spire-server.fullname" . }}-post-upgrade + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +rules: + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations"] + resourceNames: [{{ printf "%s-webhook" (include "spire-controller-manager.fullname" .) | quote }}] + verbs: ["get", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "spire-server.fullname" . }}-post-upgrade + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +subjects: + - kind: ServiceAccount + name: {{ include "spire-server.serviceAccountName" . }}-post-upgrade + namespace: {{ include "spire-server.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "spire-server.fullname" . }}-post-upgrade + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "spire-server.fullname" . }}-post-upgrade + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ include "spire-server.fullname" . }}-post-upgrade + spec: + restartPolicy: Never + serviceAccountName: {{ include "spire-server.serviceAccountName" . }}-post-upgrade + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: post-upgrade-job + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + image: {{ template "spire-server.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image) }} + command: + - /bin/sh + - -c + - |- + kubectl patch validatingwebhookconfiguration {{ include "spire-controller-manager.fullname" . }}-webhook --type='strategic' -p ' + { + "webhooks":[ + { + "name":"vclusterspiffeid.kb.io", + "failurePolicy":"{{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }}" + }, + { + "name":"vclusterfederatedtrustdomain.kb.io", + "failurePolicy":"{{ .Values.controllerManager.validatingWebhookConfiguration.failurePolicy }}" + } + ] + }' +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml b/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml new file mode 100644 index 0000000..bf4fa74 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/pre-upgrade-hook.yaml @@ -0,0 +1,85 @@ +{{- if eq (.Values.controllerManager.enabled | toString) "true" }} +{{- if eq .Values.controllerManager.validatingWebhookConfiguration.failurePolicy "Fail" }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "spire-server.serviceAccountName" . }}-pre-upgrade + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "spire-server.fullname" . }}-pre-upgrade + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +rules: + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations"] + resourceNames: [{{ printf "%s-webhook" (include "spire-controller-manager.fullname" .) | quote }}] + verbs: ["get", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "spire-server.fullname" . }}-pre-upgrade + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +subjects: + - kind: ServiceAccount + name: {{ include "spire-server.serviceAccountName" . }}-pre-upgrade + namespace: {{ include "spire-server.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "spire-server.fullname" . }}-pre-upgrade + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "spire-server.fullname" . }}-pre-upgrade + namespace: {{ include "spire-server.namespace" . }} + labels: + {{- include "spire-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-upgrade + "helm.sh/hook-delete-policy": hook-succeeded, hook-failed +spec: + template: + metadata: + name: {{ include "spire-server.fullname" . }}-pre-upgrade + spec: + restartPolicy: Never + serviceAccountName: {{ include "spire-server.serviceAccountName" . }}-pre-upgrade + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: post-install-job + securityContext: + {{- toYaml .Values.securityContext | nindent 10 }} + image: {{ template "spire-server.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.controllerManager.validatingWebhookConfiguration.upgradeHook.image) }} + command: + - /bin/sh + - -c + - |- + kubectl patch validatingwebhookconfiguration {{ include "spire-controller-manager.fullname" . }}-webhook --type='strategic' -p ' + { + "webhooks":[ + { + "name":"vclusterspiffeid.kb.io", + "failurePolicy":"Ignore" + }, + { + "name":"vclusterfederatedtrustdomain.kb.io", + "failurePolicy":"Ignore" + } + ] + }' +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/roles.yaml b/charts/spire/charts/spire-server/templates/roles.yaml index 3382d67..7bd8b1c 100644 --- a/charts/spire/charts/spire-server/templates/roles.yaml +++ b/charts/spire/charts/spire-server/templates/roles.yaml @@ -8,7 +8,7 @@ metadata: rules: - apiGroups: [""] resources: [configmaps] - resourceNames: [{{ .Values.bundleConfigMap }}] + resourceNames: [{{ include "spire-server.bundle-configmap" . }}] verbs: - get - patch diff --git a/charts/spire/charts/spire-server/templates/service.yaml b/charts/spire/charts/spire-server/templates/service.yaml index a0cb1c2..5cdaf50 100644 --- a/charts/spire/charts/spire-server/templates/service.yaml +++ b/charts/spire/charts/spire-server/templates/service.yaml @@ -16,5 +16,13 @@ spec: port: {{ .Values.service.port }} targetPort: grpc protocol: TCP + {{- with .Values.federation }} + {{- if eq (.enabled | toString) "true" }} + - name: federation + port: {{ .bundleEndpoint.port }} + targetPort: federation + protocol: TCP + {{- end }} + {{- end }} selector: {{- include "spire-server.selectorLabels" . | nindent 4 }} diff --git a/charts/spire/charts/spire-server/templates/statefulset.yaml b/charts/spire/charts/spire-server/templates/statefulset.yaml index cd18025..2773bf6 100644 --- a/charts/spire/charts/spire-server/templates/statefulset.yaml +++ b/charts/spire/charts/spire-server/templates/statefulset.yaml @@ -57,6 +57,13 @@ spec: protocol: TCP - containerPort: 8080 name: healthz + {{- with .Values.federation }} + {{- if eq (.enabled | toString) "true" }} + - name: federation + containerPort: {{ .bundleEndpoint.port }} + protocol: TCP + {{- end }} + {{- end }} {{- if (dig "telemetry" "prometheus" "enabled" .Values.telemetry.prometheus.enabled .Values.global) }} - containerPort: 9988 name: prom diff --git a/charts/spire/charts/spire-server/templates/tests/test-connection.yaml b/charts/spire/charts/spire-server/templates/tests/test-connection.yaml index 432a583..ce49605 100644 --- a/charts/spire/charts/spire-server/templates/tests/test-connection.yaml +++ b/charts/spire/charts/spire-server/templates/tests/test-connection.yaml @@ -11,10 +11,30 @@ spec: securityContext: {{- toYaml .Values.podSecurityContext | nindent 4 }} containers: - - name: wget - image: busybox - command: ['nc'] - args: ['-zvw3', '{{ include "spire-server.fullname" . }}', '{{ .Values.service.port }}'] + - name: curl + image: cgr.dev/chainguard/bash:latest + command: ['bash'] + args: + - -c + - | + curl -f -s 'https://{{ include "spire-server.fullname" . }}:{{ .Values.service.port }}' + NOCA=$? + curl -k -f -s 'https://{{ include "spire-server.fullname" . }}:{{ .Values.service.port }}' + IGNORECA=$? + echo $NOCA $IGNORECA + if [ $NOCA -eq 60 -a $IGNORECA -eq 22 ]; then + # We were able to connect to the server but didn't recognize the ca (60) and the page not found (22) because we're not using grpc + exit 0 + fi + exit 1 securityContext: {{- toYaml .Values.securityContext | nindent 8 }} + {{- if eq (.Values.federation.enabled | toString) "true" }} + - name: curl-federation-bundle-endpoint + image: cgr.dev/chainguard/bash:latest + command: ['curl'] + args: ['-k', '-s', '-f', 'https://{{ include "spire-server.fullname" . }}.{{ include "spire-server.namespace" . }}.svc.{{ include "spire-server.cluster-domain" . }}:{{ .Values.federation.bundleEndpoint.port }}'] + securityContext: + {{- toYaml .Values.securityContext | nindent 8 }} + {{- end }} restartPolicy: Never diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 5768c0b..4206c66 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -85,7 +85,16 @@ jwtIssuer: oidc-discovery.example.org clusterName: example-cluster trustDomain: example.org -bundleConfigMap: spire-server +bundleConfigMap: spire-bundle + +# -- This is the value of your clusters `kubeadm init --service-dns-domain` flag +clusterDomain: cluster.local + +federation: + enabled: false + bundleEndpoint: + port: 8443 + address: "0.0.0.0" ca_subject: country: NL @@ -176,10 +185,21 @@ controllerManager: validatingWebhookConfiguration: failurePolicy: Fail + upgradeHook: + image: + registry: cgr.dev + repository: chainguard/kubectl + pullPolicy: IfNotPresent + version: latest telemetry: prometheus: enabled: false + podMonitor: + enabled: false + # -- Override where to install the podMonitor, if not set will use the same namespace as the spire-server + namespace: "" + labels: {} extraVolumes: [] extraVolumeMounts: [] diff --git a/charts/spire/values.yaml b/charts/spire/values.yaml index 76e0e1b..72e07e1 100644 --- a/charts/spire/values.yaml +++ b/charts/spire/values.yaml @@ -1,8 +1,24 @@ -# You can enable features that affect all services here. -# global: -# telemetry: -# prometheus: -# enabled: true +# You can enable config/features that affect all services here. +global: + k8s: + # -- This is the value of your clusters `kubeadm init --service-dns-domain` flag + clusterDomain: "cluster.local" + spire: + # -- Set the name of the Kubernetes cluster + clusterName: "example-cluster" + # -- Set the trust domain to use for the spiffe identifiers + trustDomain: "example.org" + # -- Override all instances of bundleConfigMap + bundleConfigMap: "" + +# telemetry: +# prometheus: +# enabled: true +# podMonitor: +# enabled: true +# # -- Allows to install the PodMonitor in another namespace then the spire components are installed into. +# namespace: "kube-prometheus-system" +# labels: {} nameOverride: "" fullnameOverride: "" @@ -11,10 +27,6 @@ fullnameOverride: "" spire-server: enabled: true nameOverride: server - bundleConfigMap: &bundleConfigMap spire-bundle - - clusterName: &clusterName "example-cluster" - trustDomain: &trustDomain "example.org" controllerManager: enabled: true @@ -22,14 +34,9 @@ spire-server: spire-agent: enabled: true nameOverride: agent - bundleConfigMap: *bundleConfigMap - - clusterName: *clusterName - trustDomain: *trustDomain spiffe-csi-driver: enabled: true spiffe-oidc-discovery-provider: enabled: false - trustDomain: *trustDomain diff --git a/examples/production/README.md b/examples/production/README.md index 77f3b78..4cf892c 100644 --- a/examples/production/README.md +++ b/examples/production/README.md @@ -1,8 +1,14 @@ -Install with something similar to: +# Recommended production setup +Too install Spire with the least privileges possible we deploy spire accross 2 namespaces. + +```shell kubectl create namespace "spire-system" kubectl label namespace "spire-system" pod-security.kubernetes.io/enforce=privileged kubectl create namespace "spire-server" kubectl label namespace "spire-server" pod-security.kubernetes.io/enforce=restricted helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml +``` + +See [values.yaml](./values.yaml) for more details on the chart configurations to achieve this setup. diff --git a/examples/production/values.yaml b/examples/production/values.yaml index 7658760..d81d285 100644 --- a/examples/production/values.yaml +++ b/examples/production/values.yaml @@ -3,22 +3,6 @@ global: prometheus: enabled: true -spiffe-oidc-discovery-provider: - enabled: true - insecureScheme: - enabled: true - podSecurityContext: - runAsUser: 1000 - runAsGroup: 1000 - securityContext: - allowPrivilegeEscalation: false - runAsNonRoot: true - readOnlyRootFilesystem: true - capabilities: - drop: [ALL] - seccompProfile: - type: RuntimeDefault - spire-server: nodeAttestor: k8sPsat: @@ -29,6 +13,8 @@ spire-server: podSecurityContext: runAsUser: 1000 runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch securityContext: allowPrivilegeEscalation: false runAsNonRoot: true @@ -37,6 +23,12 @@ spire-server: drop: [ALL] seccompProfile: type: RuntimeDefault + + dataStorage: + enabled: true + + logLevel: info + controllerManager: securityContext: allowPrivilegeEscalation: false @@ -47,6 +39,11 @@ spire-server: seccompProfile: type: RuntimeDefault + ignoreNamespaces: + - kube-system + - kube-public + - local-path-storage + spiffe-csi-driver: enabled: true namespaceOverride: spire-system @@ -60,3 +57,23 @@ spire-agent: server: namespaceOverride: spire-server priorityClassName: system-node-critical + + logLevel: info + +spiffe-oidc-discovery-provider: + enabled: true + insecureScheme: + enabled: true + podSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: OnRootMismatch + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault