From cb0f08e53a57328f1dc3c7a9e78b2b4bcdf2ebe6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 03:52:40 +0000 Subject: [PATCH 01/12] Bump regclient/actions/regctl-installer Bumps [regclient/actions/regctl-installer](https://github.com/regclient/actions) from 78eb729dbdb4ef6480e85ff697b4410e22112583 to f9ceff9bbbc63cd1008e60cec2b27627eedc7322. - [Release notes](https://github.com/regclient/actions/releases) - [Changelog](https://github.com/regclient/actions/blob/main/RELEASE.md) - [Commits](https://github.com/regclient/actions/compare/78eb729dbdb4ef6480e85ff697b4410e22112583...f9ceff9bbbc63cd1008e60cec2b27627eedc7322) --- updated-dependencies: - dependency-name: regclient/actions/regctl-installer dependency-version: f9ceff9bbbc63cd1008e60cec2b27627eedc7322 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .github/workflows/update-devcontainer-image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-devcontainer-image.yaml b/.github/workflows/update-devcontainer-image.yaml index e9dfca4..dae60a1 100644 --- a/.github/workflows/update-devcontainer-image.yaml +++ b/.github/workflows/update-devcontainer-image.yaml @@ -29,7 +29,7 @@ jobs: with: cosign-release: v2.2.3 - name: Install regctl - uses: regclient/actions/regctl-installer@78eb729dbdb4ef6480e85ff697b4410e22112583 # main + uses: regclient/actions/regctl-installer@f9ceff9bbbc63cd1008e60cec2b27627eedc7322 # main - name: Log in to GHCR uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: From 85ab0fa5abaf9db759d4a54f427e4f8da8c37176 Mon Sep 17 00:00:00 2001 From: sabsari Date: Mon, 31 Aug 2026 00:44:56 +0900 Subject: [PATCH 02/12] Fix spire-server PodMonitor controller-manager port names (#932) The PodMonitor targeted the port name prom-cm, but controller-manager containers expose pm-cm (and auto-suffixed/overridable names for external managers), so their metrics were never scraped. Resolve port names through a shared helper and enumerate every controller-manager in the PodMonitor. Signed-off-by: sabsari Co-authored-by: Claude Opus 4.8 --- .../_controller-manager-container.tpl | 97 +++++++++++++----- .../spire-server/templates/podmonitor.yaml | 6 +- tests/unit/spire_test.go | 98 +++++++++++++++++++ 3 files changed, 174 insertions(+), 27 deletions(-) diff --git a/charts/spire/charts/spire-server/templates/_controller-manager-container.tpl b/charts/spire/charts/spire-server/templates/_controller-manager-container.tpl index 14cc911..64d28fb 100644 --- a/charts/spire/charts/spire-server/templates/_controller-manager-container.tpl +++ b/charts/spire/charts/spire-server/templates/_controller-manager-container.tpl @@ -1,3 +1,72 @@ +{{/* 15-char-safe port-name suffix for a controller-manager cluster name ("" -> ""). Shared by container ports and the PodMonitor so they cannot drift. */}} +{{- define "spire-controller-manager.portSuffix" -}} +{{- $name := . -}} +{{- $portSuffix := "" -}} +{{- if ne $name "" -}} +{{- $portSuffix = printf "-%s" $name -}} +{{- if gt (len $name) 9 -}} +{{- $numberMatch := regexFind "[-]?[0-9]{1,2}$" $name -}} +{{- if $numberMatch -}} +{{- $numLen := len $numberMatch -}} +{{- $baseLen := sub (len $name) $numLen | int -}} +{{- $baseName := substr 0 $baseLen $name -}} +{{- if not (hasPrefix "-" $numberMatch) -}} +{{- $numberMatch = printf "-%s" $numberMatch -}} +{{- end -}} +{{- $maxBase := sub 9 (len $numberMatch) | int -}} +{{- $baseName = $baseName | trunc $maxBase | trimSuffix "-" -}} +{{- $portSuffix = printf "-%s%s" $baseName $numberMatch -}} +{{- else -}} +{{- $hash := sha256sum $name | trunc 3 -}} +{{- $portSuffix = printf "-%s-%s" ($name | trunc 5 | trimSuffix "-") $hash -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- $portSuffix -}} +{{- end -}} + +{{/* Resolve a port name: override wins, else prefix+suffix. dict: prefix, portSuffix, override */}} +{{- define "spire-controller-manager.portName" -}} +{{- if and (hasKey . "override") (ne (.override | toString) "") -}} +{{- .override -}} +{{- else -}} +{{- printf "%s%s" .prefix .portSuffix -}} +{{- end -}} +{{- end -}} + +{{/* Prometheus port name for one controller-manager. dict: name (""=main), settings (may hold prometheusPortName) */}} +{{- define "spire-controller-manager.promPortName" -}} +{{- $override := "" -}} +{{- if hasKey .settings "prometheusPortName" -}} +{{- $override = .settings.prometheusPortName -}} +{{- end -}} +{{- include "spire-controller-manager.portName" (dict "prefix" "pm-cm" "portSuffix" (include "spire-controller-manager.portSuffix" .name) "override" $override) -}} +{{- end -}} + +{{/* List of prometheus port names for every controller-manager that renders one. Consumed by the PodMonitor. */}} +{{- define "spire-controller-manager.prometheusPortNames" -}} +{{- $root := . -}} +{{- $names := list -}} +{{- if eq (.Values.controllerManager.enabled | toString) "true" -}} +{{- $names = append $names (include "spire-controller-manager.promPortName" (dict "name" "" "settings" .Values.controllerManager)) -}} +{{- end -}} +{{- if .Values.externalControllerManagers.enabled -}} +{{- $clusters := default .Values.kubeConfigs .Values.externalControllerManagers.clusters -}} +{{- range $name, $_ := $clusters -}} +{{- $clusterSettings := dict -}} +{{- if hasKey $root.Values.externalControllerManagers.clusters $name -}} +{{- $clusterSettings = index $root.Values.externalControllerManagers.clusters $name -}} +{{- end -}} +{{- $pmName := include "spire-controller-manager.promPortName" (dict "name" $name "settings" $clusterSettings) -}} +{{- if has $pmName $names -}} +{{- fail (printf "controller-manager prometheus port name %q collides for cluster %q; set a distinct prometheusPortName override" $pmName $name) -}} +{{- end -}} +{{- $names = append $names $pmName -}} +{{- end -}} +{{- end -}} +{{- $names | toYaml -}} +{{- end -}} + {{- define "spire-controller-manager.containers" }} {{- $root := . }} {{- $settings := dict }} @@ -41,23 +110,7 @@ Auto-generation preserves trailing numbers from cluster names or uses hash for u {{- $prometheusPortName = $clusterSettings.prometheusPortName }} {{- end }} {{- if or (eq $healthPortName "") (eq $prometheusPortName "") }} -{{- if gt (len $name) 9 }} -{{- $numberMatch := regexFind "[-]?[0-9]{1,2}$" $name }} -{{- if $numberMatch }} -{{- $numLen := len $numberMatch }} -{{- $baseLen := sub (len $name) $numLen | int }} -{{- $baseName := substr 0 $baseLen $name }} -{{- if not (hasPrefix "-" $numberMatch) }} -{{- $numberMatch = printf "-%s" $numberMatch }} -{{- end }} -{{- $maxBase := sub 9 (len $numberMatch) | int }} -{{- $baseName = $baseName | trunc $maxBase | trimSuffix "-" }} -{{- $portSuffix = printf "-%s%s" $baseName $numberMatch }} -{{- else }} -{{- $hash := sha256sum $name | trunc 3 }} -{{- $portSuffix = printf "-%s-%s" ($name | trunc 5 | trimSuffix "-") $hash }} -{{- end }} -{{- end }} +{{- $portSuffix = include "spire-controller-manager.portSuffix" $name }} {{- end }} {{- $startPort = add $startPort 2 }} @@ -127,17 +180,11 @@ Auto-generation preserves trailing numbers from cluster names or uses hash for u containerPort: 9443 protocol: TCP {{- end }} - {{- $hpName := .healthPortName }} - {{- if eq $hpName "" }} - {{- $hpName = printf "hp-cm%s" .portSuffix }} - {{- end }} + {{- $hpName := include "spire-controller-manager.portName" (dict "prefix" "hp-cm" "portSuffix" .portSuffix "override" .healthPortName) }} - containerPort: {{ $healthPort }} name: {{ $hpName }} {{- if or (dig "telemetry" "prometheus" "enabled" .Values.telemetry.prometheus.enabled .Values.global) (and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "prometheus" true .Values.global)) }} - {{- $pmName := .prometheusPortName }} - {{- if eq $pmName "" }} - {{- $pmName = printf "pm-cm%s" .portSuffix }} - {{- end }} + {{- $pmName := include "spire-controller-manager.portName" (dict "prefix" "pm-cm" "portSuffix" .portSuffix "override" .prometheusPortName) }} - containerPort: {{ $promPort }} name: {{ $pmName }} {{- end }} diff --git a/charts/spire/charts/spire-server/templates/podmonitor.yaml b/charts/spire/charts/spire-server/templates/podmonitor.yaml index d73034c..f17e180 100644 --- a/charts/spire/charts/spire-server/templates/podmonitor.yaml +++ b/charts/spire/charts/spire-server/templates/podmonitor.yaml @@ -21,10 +21,12 @@ spec: {{- include "spire-server.selectorLabels" . | nindent 6 }} podMetricsEndpoints: - port: prom - - port: prom-cm + {{- range (include "spire-controller-manager.prometheusPortNames" . | fromYamlArray) }} + - port: {{ . }} + {{- end }} {{- if ne $namespace $podNamespace }} namespaceSelector: kubernetes.io/metadata.name: {{ $podNamespace }} - {{- end }} + {{- end }} {{- end }} {{- end }} diff --git a/tests/unit/spire_test.go b/tests/unit/spire_test.go index 4f11873..c2819bb 100644 --- a/tests/unit/spire_test.go +++ b/tests/unit/spire_test.go @@ -810,6 +810,104 @@ spire-server: } }) }) + Describe("spire-server.telemetry.podMonitor controller-manager ports", func() { + podMonitorTmpl := "spire/charts/spire-server/templates/podmonitor.yaml" + serverTmpl := "spire/charts/spire-server/templates/server-resource.yaml" + + It("targets the real main controller-manager port name, not the legacy prom-cm", func() { + objs, err := ValueStringRender(chart, ` +spire-server: + controllerManager: + enabled: true + telemetry: + prometheus: + enabled: true + podMonitor: + enabled: true +`) + Expect(err).Should(Succeed()) + podMonitor := objs[podMonitorTmpl] + Expect(podMonitor).Should(ContainSubstring("- port: prom")) + Expect(podMonitor).Should(ContainSubstring("- port: pm-cm")) + // Regression: the PodMonitor used to hardcode a port name the container never renders. + Expect(podMonitor).ShouldNot(ContainSubstring("prom-cm")) + // The endpoint must match the actual container port. + Expect(objs[serverTmpl]).Should(ContainSubstring("name: pm-cm")) + }) + + It("enumerates external controller-managers, honouring auto-suffix and prometheusPortName override", func() { + objs, err := ValueStringRender(chart, ` +spire-server: + controllerManager: + enabled: true + telemetry: + prometheus: + enabled: true + podMonitor: + enabled: true + kubeConfigs: + child01: + kubeConfig: | + apiVersion: v1 + kind: Config + verylongclustername: + kubeConfig: | + apiVersion: v1 + kind: Config + externalControllerManagers: + enabled: true + clusters: + child01: + kubeConfigName: child01 + verylongclustername: + kubeConfigName: verylongclustername + prometheusPortName: prom-ext2 +`) + Expect(err).Should(Succeed()) + podMonitor := objs[podMonitorTmpl] + server := objs[serverTmpl] + // Auto-suffixed external CM and the overridden one must both be scraped, + // and each endpoint must match a real container port name. + for _, port := range []string{"pm-cm", "pm-cm-child01", "prom-ext2"} { + Expect(podMonitor).Should(ContainSubstring("- port: " + port)) + Expect(server).Should(ContainSubstring("name: " + port)) + } + }) + + It("derives external controller-managers from kubeConfigs when clusters is the default {}", func() { + objs, err := ValueStringRender(chart, ` +spire-server: + controllerManager: + enabled: true + telemetry: + prometheus: + enabled: true + podMonitor: + enabled: true + kubeConfigs: + child01: + kubeConfig: | + apiVersion: v1 + kind: Config + child02: + kubeConfig: | + apiVersion: v1 + kind: Config + externalControllerManagers: + enabled: true + clusters: {} +`) + Expect(err).Should(Succeed()) + podMonitor := objs[podMonitorTmpl] + server := objs[serverTmpl] + // clusters={} (the chart default) falls back to kubeConfigs, so each + // kubeConfig-derived controller-manager must be scraped and match its port. + for _, port := range []string{"pm-cm", "pm-cm-child01", "pm-cm-child02"} { + Expect(podMonitor).Should(ContainSubstring("- port: " + port)) + Expect(server).Should(ContainSubstring("name: " + port)) + } + }) + }) Describe("spire-server.dataStore.sql.postgres passwordless", func() { It("omits password and the -dbpw Secret for cert auth with an empty password", func() { objs, err := ValueStringRender(chart, ` From d86f08ff9619b75cd9b5182a8a688a5b64543618 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 03:53:40 +0000 Subject: [PATCH 03/12] Bump github.com/onsi/gomega from 1.42.1 to 1.43.0 in /tests Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.42.1 to 1.43.0. - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/gomega/compare/v1.42.1...v1.43.0) --- updated-dependencies: - dependency-name: github.com/onsi/gomega dependency-version: 1.43.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/go.mod | 4 ++-- tests/go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index c665a2e..d424d74 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -4,8 +4,9 @@ go 1.26.0 require ( github.com/onsi/ginkgo/v2 v2.32.1 - github.com/onsi/gomega v1.42.1 + github.com/onsi/gomega v1.43.0 helm.sh/helm/v3 v3.21.4 + k8s.io/apimachinery v0.36.2 ) require ( @@ -59,7 +60,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.36.2 // indirect k8s.io/apiextensions-apiserver v0.36.2 // indirect - k8s.io/apimachinery v0.36.2 // indirect k8s.io/client-go v0.36.2 // indirect k8s.io/klog/v2 v2.140.0 // indirect k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect diff --git a/tests/go.sum b/tests/go.sum index 51ec3d7..7584b3c 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -91,8 +91,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/onsi/ginkgo/v2 v2.32.1 h1:6tlvcDm/3sE8lGJbZ4+d4mO3RLy24/tQWOFzVSQNIfw= github.com/onsi/ginkgo/v2 v2.32.1/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= -github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I= -github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg= +github.com/onsi/gomega v1.43.0 h1:VlG/1FxqNxhSO+lq/OHBNaaqwiBK/mO8JbVkX9Y+FeU= +github.com/onsi/gomega v1.43.0/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= From c63812199728bdcbcd48800f3c26a44474bd5f02 Mon Sep 17 00:00:00 2001 From: sabsari Date: Tue, 1 Sep 2026 21:41:12 +0900 Subject: [PATCH 04/12] feat(gateway): expose gatewayAPI.gateway.infrastructure passthrough (#939) Render Gateway spec.infrastructure (labels/annotations) so Gateway API controllers propagate the metadata onto the provisioned Service/Deployment, e.g. AWS internal NLB annotations. Purely additive: guarded by `with`, so the default {} renders no change. - spire-lib: toYaml passthrough in the shared Gateway helper - spire, spire-nested: add the values param; regenerate READMEs - tests/unit: cover the positive passthrough case Signed-off-by: sabsari Co-authored-by: Claude Opus 4.8 --- charts/spire-lib/templates/_helpers.tpl | 4 ++++ charts/spire-nested/README.md | 1 + charts/spire-nested/values.yaml | 2 ++ charts/spire/README.md | 1 + charts/spire/values.yaml | 2 ++ tests/unit/spire_test.go | 17 +++++++++++++++++ 6 files changed, 27 insertions(+) diff --git a/charts/spire-lib/templates/_helpers.tpl b/charts/spire-lib/templates/_helpers.tpl index 6110827..a5e598e 100644 --- a/charts/spire-lib/templates/_helpers.tpl +++ b/charts/spire-lib/templates/_helpers.tpl @@ -589,6 +589,10 @@ metadata: {{- end }} spec: gatewayClassName: {{ required "gatewayAPI.gateway.className is required to render the shared Gateway" $obj.className | quote }} + {{- with $obj.infrastructure }} + infrastructure: + {{- toYaml . | nindent 4 }} + {{- end }} allowedListeners: namespaces: from: {{ default "All" $obj.allowedListenersNamespaces }} diff --git a/charts/spire-nested/README.md b/charts/spire-nested/README.md index 2a7db72..e49319d 100644 --- a/charts/spire-nested/README.md +++ b/charts/spire-nested/README.md @@ -243,6 +243,7 @@ Now you can interact with the Spire agent socket from your own application. The | `gatewayAPI.gateway.enabled` | Render the shared Gateway object | `false` | | `gatewayAPI.gateway.className` | gatewayClassName for the shared Gateway (e.g. "eg"). Required when enabled. | `""` | | `gatewayAPI.gateway.annotations` | Annotations for the Gateway object | `{}` | +| `gatewayAPI.gateway.infrastructure` | Metadata (labels/annotations) propagated to the provisioned Gateway Service/Deployment. Use for cloud LB annotations, e.g. internal NLB. | `{}` | | `gatewayAPI.gateway.allowedListenersNamespaces` | From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector. | `All` | | `gatewayAPI.gateway.allowedRoutesNamespaces` | From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector. | `All` | | `gatewayAPI.gateway.extraListeners` | Additional listeners to add to the Gateway | `[]` | diff --git a/charts/spire-nested/values.yaml b/charts/spire-nested/values.yaml index c5406d9..66b6d28 100644 --- a/charts/spire-nested/values.yaml +++ b/charts/spire-nested/values.yaml @@ -138,6 +138,8 @@ gatewayAPI: className: "" ## @param gatewayAPI.gateway.annotations [object] Annotations for the Gateway object annotations: {} + ## @param gatewayAPI.gateway.infrastructure [object] Metadata (labels/annotations) propagated to the provisioned Gateway Service/Deployment. Use for cloud LB annotations, e.g. internal NLB. + infrastructure: {} ## @param gatewayAPI.gateway.allowedListenersNamespaces From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector. allowedListenersNamespaces: All ## @param gatewayAPI.gateway.allowedRoutesNamespaces From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector. diff --git a/charts/spire/README.md b/charts/spire/README.md index b6f1423..531abf0 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -328,6 +328,7 @@ Now you can interact with the Spire agent socket from your own application. The | `gatewayAPI.gateway.enabled` | Render the shared Gateway object | `false` | | `gatewayAPI.gateway.className` | gatewayClassName for the shared Gateway (e.g. "eg"). Required when enabled. | `""` | | `gatewayAPI.gateway.annotations` | Annotations for the Gateway object | `{}` | +| `gatewayAPI.gateway.infrastructure` | Metadata (labels/annotations) propagated to the provisioned Gateway Service/Deployment. Use for cloud LB annotations, e.g. internal NLB. | `{}` | | `gatewayAPI.gateway.allowedListenersNamespaces` | From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector. | `All` | | `gatewayAPI.gateway.allowedRoutesNamespaces` | From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector. | `All` | | `gatewayAPI.gateway.extraListeners` | Additional listeners to add to the Gateway | `[]` | diff --git a/charts/spire/values.yaml b/charts/spire/values.yaml index 0932ec8..5629295 100644 --- a/charts/spire/values.yaml +++ b/charts/spire/values.yaml @@ -159,6 +159,8 @@ gatewayAPI: className: "" ## @param gatewayAPI.gateway.annotations [object] Annotations for the Gateway object annotations: {} + ## @param gatewayAPI.gateway.infrastructure [object] Metadata (labels/annotations) propagated to the provisioned Gateway Service/Deployment. Use for cloud LB annotations, e.g. internal NLB. + infrastructure: {} ## @param gatewayAPI.gateway.allowedListenersNamespaces From which namespaces ListenerSets may attach to the Gateway. One of All, Same, Selector. allowedListenersNamespaces: All ## @param gatewayAPI.gateway.allowedRoutesNamespaces From which namespaces routes may attach directly to the base listener (used when ListenerSet management is off). One of All, Same, Selector. diff --git a/tests/unit/spire_test.go b/tests/unit/spire_test.go index c2819bb..6126912 100644 --- a/tests/unit/spire_test.go +++ b/tests/unit/spire_test.go @@ -985,4 +985,21 @@ spire-server: Expect(serverResource).Should(ContainSubstring("name: my-ro-db-secret")) }) }) + Describe("gatewayAPI.gateway.infrastructure", func() { + It("passes infrastructure through to the shared Gateway spec when set", func() { + objs, err := ValueStringRender(chart, ` +gatewayAPI: + gateway: + enabled: true + className: istio + infrastructure: + annotations: + service.beta.kubernetes.io/aws-load-balancer-scheme: internal +`) + Expect(err).Should(Succeed()) + gateway := objs["spire/templates/gateway.yaml"] + Expect(gateway).Should(ContainSubstring("infrastructure:")) + Expect(gateway).Should(ContainSubstring("service.beta.kubernetes.io/aws-load-balancer-scheme: internal")) + }) + }) }) From ece47796f0b6f89083be36c2a510a661d64ed264 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 05:06:01 -0700 Subject: [PATCH 05/12] Bump regclient/actions/regctl-installer (#942) Bumps [regclient/actions/regctl-installer](https://github.com/regclient/actions) from f9ceff9bbbc63cd1008e60cec2b27627eedc7322 to ba687069a65d03e9214808f16f3f0b3933c2048b. - [Release notes](https://github.com/regclient/actions/releases) - [Changelog](https://github.com/regclient/actions/blob/main/RELEASE.md) - [Commits](https://github.com/regclient/actions/compare/f9ceff9bbbc63cd1008e60cec2b27627eedc7322...ba687069a65d03e9214808f16f3f0b3933c2048b) --- updated-dependencies: - dependency-name: regclient/actions/regctl-installer dependency-version: ba687069a65d03e9214808f16f3f0b3933c2048b dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/update-devcontainer-image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-devcontainer-image.yaml b/.github/workflows/update-devcontainer-image.yaml index dae60a1..2913867 100644 --- a/.github/workflows/update-devcontainer-image.yaml +++ b/.github/workflows/update-devcontainer-image.yaml @@ -29,7 +29,7 @@ jobs: with: cosign-release: v2.2.3 - name: Install regctl - uses: regclient/actions/regctl-installer@f9ceff9bbbc63cd1008e60cec2b27627eedc7322 # main + uses: regclient/actions/regctl-installer@ba687069a65d03e9214808f16f3f0b3933c2048b # main - name: Log in to GHCR uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: From c90e639623774bd6e91ab5bd21c5be52625849c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Sep 2026 03:52:42 +0000 Subject: [PATCH 06/12] Bump helm/kind-action from 1.14.0 to 1.15.0 Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.14.0 to 1.15.0. - [Release notes](https://github.com/helm/kind-action/releases) - [Commits](https://github.com/helm/kind-action/compare/v1.14.0...v1.15.0) --- updated-dependencies: - dependency-name: helm/kind-action dependency-version: 1.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/helm-chart-ci.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/helm-chart-ci.yaml b/.github/workflows/helm-chart-ci.yaml index ec7b9b3..6f16c92 100644 --- a/.github/workflows/helm-chart-ci.yaml +++ b/.github/workflows/helm-chart-ci.yaml @@ -186,7 +186,7 @@ jobs: version: ${{ env.CHART_TESTING_VERSION }} - name: Create kind ${{ matrix.k8s }} cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@v1.15.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -272,7 +272,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@v1.15.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -327,7 +327,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@v1.15.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -373,7 +373,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.14.0 + uses: helm/kind-action@v1.15.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} From cb18cc3e14b624b7a322127f801313647e97f82e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 03:52:56 +0000 Subject: [PATCH 07/12] Bump k8s.io/apimachinery from 0.36.2 to 0.37.0 in /tests Bumps [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) from 0.36.2 to 0.37.0. - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.36.2...v0.37.0) --- updated-dependencies: - dependency-name: k8s.io/apimachinery dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- tests/go.mod | 34 +++++++++++++-------- tests/go.sum | 84 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 69 insertions(+), 49 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index d424d74..4fd63b4 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -6,7 +6,7 @@ require ( github.com/onsi/ginkgo/v2 v2.32.1 github.com/onsi/gomega v1.43.0 helm.sh/helm/v3 v3.21.4 - k8s.io/apimachinery v0.36.2 + k8s.io/apimachinery v0.37.0 ) require ( @@ -18,11 +18,22 @@ require ( github.com/cyphar/filepath-securejoin v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.1 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/jsonpointer v1.0.0 // indirect + github.com/go-openapi/jsonreference v1.0.0 // indirect + github.com/go-openapi/swag v0.27.1 // indirect + github.com/go-openapi/swag/cmdutils v0.27.1 // indirect + github.com/go-openapi/swag/conv v0.27.1 // indirect + github.com/go-openapi/swag/fileutils v0.27.1 // indirect + github.com/go-openapi/swag/jsonutils v0.27.1 // indirect + github.com/go-openapi/swag/loading v0.27.1 // indirect + github.com/go-openapi/swag/mangling v0.27.1 // indirect + github.com/go-openapi/swag/netutils v0.27.1 // indirect + github.com/go-openapi/swag/pools v0.27.1 // indirect + github.com/go-openapi/swag/stringutils v0.27.1 // indirect + github.com/go-openapi/swag/typeutils v0.27.1 // indirect + github.com/go-openapi/swag/yamlutils v0.27.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect @@ -30,9 +41,7 @@ require ( github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -47,25 +56,24 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.54.0 // indirect golang.org/x/mod v0.37.0 // indirect - golang.org/x/net v0.56.0 // indirect + golang.org/x/net v0.57.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.22.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.40.0 // indirect - golang.org/x/time v0.14.0 // indirect + golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.47.0 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.36.2 // indirect k8s.io/apiextensions-apiserver v0.36.2 // indirect k8s.io/client-go v0.36.2 // indirect k8s.io/klog/v2 v2.140.0 // indirect - k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect - k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect + k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect + k8s.io/utils v0.0.0-20260626114624-be93311217bd // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/tests/go.sum b/tests/go.sum index 7584b3c..e5a1eda 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -10,7 +10,6 @@ github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAw github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.7.0 h1:s0Y3ITPy6sQn5xt54DuYvTF8hu134ooYLUb58DX/HjE= github.com/cyphar/filepath-securejoin v0.7.0/go.mod h1:ymLGms/u3BYaviIiuKFnUx8EkQEZeK6cInNoAPJA3o4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -23,8 +22,8 @@ github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bF github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= +github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -33,14 +32,40 @@ github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01 github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= +github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= +github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= +github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= +github.com/go-openapi/swag v0.27.1 h1:VotvOLWW8q/EAxB0YdsBBGC8XYyeL1YwBj2ungAGPNg= +github.com/go-openapi/swag v0.27.1/go.mod h1:GTkJPwHfhJp6MWr4/rCh64HVI3Ofu+tcsbfjfHmTxpE= +github.com/go-openapi/swag/cmdutils v0.27.1 h1:I7sYqaWVl5mq0NEmNQkAmFDyNin9ufvMX/p2zwtQaOE= +github.com/go-openapi/swag/cmdutils v0.27.1/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.27.1 h1:8wi9ZG+olmY1wXphl93EWniPtbSPkXM/feH7FgjsvrU= +github.com/go-openapi/swag/conv v0.27.1/go.mod h1:QbqMivkpKhC3g1B1GGGOJ6ANewI3S62dbzYu3Duowqs= +github.com/go-openapi/swag/fileutils v0.27.1 h1:QQqBSoi5mW4XpU85nS0mLcA+zAE6vLzrb0QkmLKf9oM= +github.com/go-openapi/swag/fileutils v0.27.1/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= +github.com/go-openapi/swag/jsonutils v0.27.1 h1:SVgK3i4USzCU5mibOOS/l4ea2h9UQXy7J7RNLTjuXjU= +github.com/go-openapi/swag/jsonutils v0.27.1/go.mod h1:tdlEpZqdcQ17uj6J4YdK9vd8It5qWMwjWXOs0tjpRlk= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1 h1:mJu3COL9WEaZVp/Kf2PRMi7tPszPEJfSr/OO75ynCs8= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= +github.com/go-openapi/swag/loading v0.27.1 h1:/DxUgDXKbBX4bcn7r9uEXfJyzN5XpiJmZplzQTjrRCY= +github.com/go-openapi/swag/loading v0.27.1/go.mod h1:jvGh3iA2+zyUUycB5fgJWzeHnhrpvGnJJM0RVE9ZShE= +github.com/go-openapi/swag/mangling v0.27.1 h1:yC9D0HyUE8gbP+BfmGx9+AA89ikwZTMjESK3OnnoaqA= +github.com/go-openapi/swag/mangling v0.27.1/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.27.1 h1:mICMFoS82F5TZ4Zy3cqmcQk+BFeCp3Uyq3Np7GI0/qU= +github.com/go-openapi/swag/netutils v0.27.1/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/pools v0.27.1 h1:9LeadcMyb2GJCbXX5hVQDbZ2Lq9TL4dCs/nx1j5DO0E= +github.com/go-openapi/swag/pools v0.27.1/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= +github.com/go-openapi/swag/stringutils v0.27.1 h1:ZXePZ0r2p1qSjo8tD3Un4vFj8+FqlCkczxDrJIhYUp8= +github.com/go-openapi/swag/stringutils v0.27.1/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.27.1 h1:KSTdFlfnse4r6dP9IrEnwMldjE+zs71UeEB3//PtVXc= +github.com/go-openapi/swag/typeutils v0.27.1/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= +github.com/go-openapi/swag/yamlutils v0.27.1 h1:ftxv6xvXb1E3zohUc+okZ9nSqNb9StQX/FXnKZ98sQA= +github.com/go-openapi/swag/yamlutils v0.27.1/go.mod h1:bnxFIB1qewGRiZHypXGZ3fNgf13/0HfRgnS/iZBDrOo= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= +github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= +github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -58,21 +83,14 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= @@ -109,14 +127,9 @@ github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -137,8 +150,8 @@ golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= -golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= -golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= +golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= @@ -149,8 +162,8 @@ golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= @@ -162,7 +175,6 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= helm.sh/helm/v3 v3.21.4 h1:T/GcIEXU/gNjJnkITlIZ3e9xqkZjhFTmISuStTZ6+Qg= @@ -171,21 +183,21 @@ k8s.io/api v0.36.2 h1:TF6YDLIzKfccK7cq9YpTcGX8TJmEkHVRv78DM51fRYY= k8s.io/api v0.36.2/go.mod h1:F4LbMO4brjZYh7yFkXWhynSvtB7YauxV4c+HHkNRGNg= k8s.io/apiextensions-apiserver v0.36.2 h1:3O5gqOj/dt2XWWbpMe+TXWpE9yU6pjM/tXxtHHJT/K4= k8s.io/apiextensions-apiserver v0.36.2/go.mod h1:cL1tBWe8XSaP1H30iWKGo7hf6iAUUUJPEU70dskmAnA= -k8s.io/apimachinery v0.36.2 h1:0PE/W/WNy1UX61NLbXY5TMbJ6UwLL6E6lAPkYrKFxbQ= -k8s.io/apimachinery v0.36.2/go.mod h1:fvf/HOLXq9RId0rnDIbN1OEBvHXdQbLMM8nu0LcBUf4= +k8s.io/apimachinery v0.37.0 h1:Np2AbDtf8x6RDHiD8T9LbKJ9gaegeVNa8yNm5FuGKm0= +k8s.io/apimachinery v0.37.0/go.mod h1:RN3nhprFSCxOi5Selxd7oMTXOe/c+ZbcE7Im+TS2zkE= k8s.io/client-go v0.36.2 h1:bfgxmFKc9CgqsgX4xKLAAdmTQlWee7Ob/HlDOrJ5TBI= k8s.io/client-go v0.36.2/go.mod h1:1vgO4OAlfPnoLcb+Rze2GF5rAr14w8qjrYMoyXJzQj0= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= -k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A= +k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I= +k8s.io/utils v0.0.0-20260626114624-be93311217bd h1:Ea7fgQ5we8Y9T0OX5o0dAHzQOBRI07D/dEYRaB9ZZEs= +k8s.io/utils v0.0.0-20260626114624-be93311217bd/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= -sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= From 5121622ead9e24bccfba36d7d9dc934df16a783d Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Fri, 4 Sep 2026 10:46:12 -0700 Subject: [PATCH 08/12] Revert "Bump k8s.io/apimachinery from 0.36.2 to 0.37.0 in /tests" (#945) This reverts commit cb18cc3e14b624b7a322127f801313647e97f82e. Signed-off-by: Kevin Fox --- tests/go.mod | 34 ++++++++------------- tests/go.sum | 84 ++++++++++++++++++++++------------------------------ 2 files changed, 49 insertions(+), 69 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index 4fd63b4..d424d74 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -6,7 +6,7 @@ require ( github.com/onsi/ginkgo/v2 v2.32.1 github.com/onsi/gomega v1.43.0 helm.sh/helm/v3 v3.21.4 - k8s.io/apimachinery v0.37.0 + k8s.io/apimachinery v0.36.2 ) require ( @@ -18,22 +18,11 @@ require ( github.com/cyphar/filepath-securejoin v0.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect - github.com/fxamacker/cbor/v2 v2.9.1 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v1.0.0 // indirect - github.com/go-openapi/jsonreference v1.0.0 // indirect - github.com/go-openapi/swag v0.27.1 // indirect - github.com/go-openapi/swag/cmdutils v0.27.1 // indirect - github.com/go-openapi/swag/conv v0.27.1 // indirect - github.com/go-openapi/swag/fileutils v0.27.1 // indirect - github.com/go-openapi/swag/jsonutils v0.27.1 // indirect - github.com/go-openapi/swag/loading v0.27.1 // indirect - github.com/go-openapi/swag/mangling v0.27.1 // indirect - github.com/go-openapi/swag/netutils v0.27.1 // indirect - github.com/go-openapi/swag/pools v0.27.1 // indirect - github.com/go-openapi/swag/stringutils v0.27.1 // indirect - github.com/go-openapi/swag/typeutils v0.27.1 // indirect - github.com/go-openapi/swag/yamlutils v0.27.1 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect @@ -41,7 +30,9 @@ require ( github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect github.com/google/uuid v1.6.0 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -56,24 +47,25 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.54.0 // indirect golang.org/x/mod v0.37.0 // indirect - golang.org/x/net v0.57.0 // indirect + golang.org/x/net v0.56.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.22.0 // indirect golang.org/x/sys v0.47.0 // indirect golang.org/x/term v0.45.0 // indirect golang.org/x/text v0.40.0 // indirect - golang.org/x/time v0.15.0 // indirect + golang.org/x/time v0.14.0 // indirect golang.org/x/tools v0.47.0 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.36.2 // indirect k8s.io/apiextensions-apiserver v0.36.2 // indirect k8s.io/client-go v0.36.2 // indirect k8s.io/klog/v2 v2.140.0 // indirect - k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect - k8s.io/utils v0.0.0-20260626114624-be93311217bd // indirect + k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect + k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/tests/go.sum b/tests/go.sum index e5a1eda..7584b3c 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -10,6 +10,7 @@ github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAw github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.7.0 h1:s0Y3ITPy6sQn5xt54DuYvTF8hu134ooYLUb58DX/HjE= github.com/cyphar/filepath-securejoin v0.7.0/go.mod h1:ymLGms/u3BYaviIiuKFnUx8EkQEZeK6cInNoAPJA3o4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -22,8 +23,8 @@ github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bF github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= -github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -32,40 +33,14 @@ github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01 github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= -github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= -github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= -github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= -github.com/go-openapi/swag v0.27.1 h1:VotvOLWW8q/EAxB0YdsBBGC8XYyeL1YwBj2ungAGPNg= -github.com/go-openapi/swag v0.27.1/go.mod h1:GTkJPwHfhJp6MWr4/rCh64HVI3Ofu+tcsbfjfHmTxpE= -github.com/go-openapi/swag/cmdutils v0.27.1 h1:I7sYqaWVl5mq0NEmNQkAmFDyNin9ufvMX/p2zwtQaOE= -github.com/go-openapi/swag/cmdutils v0.27.1/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= -github.com/go-openapi/swag/conv v0.27.1 h1:8wi9ZG+olmY1wXphl93EWniPtbSPkXM/feH7FgjsvrU= -github.com/go-openapi/swag/conv v0.27.1/go.mod h1:QbqMivkpKhC3g1B1GGGOJ6ANewI3S62dbzYu3Duowqs= -github.com/go-openapi/swag/fileutils v0.27.1 h1:QQqBSoi5mW4XpU85nS0mLcA+zAE6vLzrb0QkmLKf9oM= -github.com/go-openapi/swag/fileutils v0.27.1/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= -github.com/go-openapi/swag/jsonutils v0.27.1 h1:SVgK3i4USzCU5mibOOS/l4ea2h9UQXy7J7RNLTjuXjU= -github.com/go-openapi/swag/jsonutils v0.27.1/go.mod h1:tdlEpZqdcQ17uj6J4YdK9vd8It5qWMwjWXOs0tjpRlk= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1 h1:mJu3COL9WEaZVp/Kf2PRMi7tPszPEJfSr/OO75ynCs8= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= -github.com/go-openapi/swag/loading v0.27.1 h1:/DxUgDXKbBX4bcn7r9uEXfJyzN5XpiJmZplzQTjrRCY= -github.com/go-openapi/swag/loading v0.27.1/go.mod h1:jvGh3iA2+zyUUycB5fgJWzeHnhrpvGnJJM0RVE9ZShE= -github.com/go-openapi/swag/mangling v0.27.1 h1:yC9D0HyUE8gbP+BfmGx9+AA89ikwZTMjESK3OnnoaqA= -github.com/go-openapi/swag/mangling v0.27.1/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= -github.com/go-openapi/swag/netutils v0.27.1 h1:mICMFoS82F5TZ4Zy3cqmcQk+BFeCp3Uyq3Np7GI0/qU= -github.com/go-openapi/swag/netutils v0.27.1/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= -github.com/go-openapi/swag/pools v0.27.1 h1:9LeadcMyb2GJCbXX5hVQDbZ2Lq9TL4dCs/nx1j5DO0E= -github.com/go-openapi/swag/pools v0.27.1/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= -github.com/go-openapi/swag/stringutils v0.27.1 h1:ZXePZ0r2p1qSjo8tD3Un4vFj8+FqlCkczxDrJIhYUp8= -github.com/go-openapi/swag/stringutils v0.27.1/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= -github.com/go-openapi/swag/typeutils v0.27.1 h1:KSTdFlfnse4r6dP9IrEnwMldjE+zs71UeEB3//PtVXc= -github.com/go-openapi/swag/typeutils v0.27.1/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= -github.com/go-openapi/swag/yamlutils v0.27.1 h1:ftxv6xvXb1E3zohUc+okZ9nSqNb9StQX/FXnKZ98sQA= -github.com/go-openapi/swag/yamlutils v0.27.1/go.mod h1:bnxFIB1qewGRiZHypXGZ3fNgf13/0HfRgnS/iZBDrOo= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= -github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= -github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= -github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= @@ -83,14 +58,21 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= @@ -127,9 +109,14 @@ github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -150,8 +137,8 @@ golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= -golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= -golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= @@ -162,8 +149,8 @@ golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= -golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= -golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= @@ -175,6 +162,7 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= helm.sh/helm/v3 v3.21.4 h1:T/GcIEXU/gNjJnkITlIZ3e9xqkZjhFTmISuStTZ6+Qg= @@ -183,21 +171,21 @@ k8s.io/api v0.36.2 h1:TF6YDLIzKfccK7cq9YpTcGX8TJmEkHVRv78DM51fRYY= k8s.io/api v0.36.2/go.mod h1:F4LbMO4brjZYh7yFkXWhynSvtB7YauxV4c+HHkNRGNg= k8s.io/apiextensions-apiserver v0.36.2 h1:3O5gqOj/dt2XWWbpMe+TXWpE9yU6pjM/tXxtHHJT/K4= k8s.io/apiextensions-apiserver v0.36.2/go.mod h1:cL1tBWe8XSaP1H30iWKGo7hf6iAUUUJPEU70dskmAnA= -k8s.io/apimachinery v0.37.0 h1:Np2AbDtf8x6RDHiD8T9LbKJ9gaegeVNa8yNm5FuGKm0= -k8s.io/apimachinery v0.37.0/go.mod h1:RN3nhprFSCxOi5Selxd7oMTXOe/c+ZbcE7Im+TS2zkE= +k8s.io/apimachinery v0.36.2 h1:0PE/W/WNy1UX61NLbXY5TMbJ6UwLL6E6lAPkYrKFxbQ= +k8s.io/apimachinery v0.36.2/go.mod h1:fvf/HOLXq9RId0rnDIbN1OEBvHXdQbLMM8nu0LcBUf4= k8s.io/client-go v0.36.2 h1:bfgxmFKc9CgqsgX4xKLAAdmTQlWee7Ob/HlDOrJ5TBI= k8s.io/client-go v0.36.2/go.mod h1:1vgO4OAlfPnoLcb+Rze2GF5rAr14w8qjrYMoyXJzQj0= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A= -k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I= -k8s.io/utils v0.0.0-20260626114624-be93311217bd h1:Ea7fgQ5we8Y9T0OX5o0dAHzQOBRI07D/dEYRaB9ZZEs= -k8s.io/utils v0.0.0-20260626114624-be93311217bd/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= +k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU= +k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= -sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= From bb4c73febf40375956624c07371b1156ae727102 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Fri, 4 Sep 2026 11:03:40 -0700 Subject: [PATCH 09/12] Revert "Bump helm/kind-action from 1.14.0 to 1.15.0" (#944) This reverts commit c90e639623774bd6e91ab5bd21c5be52625849c0. Signed-off-by: Kevin Fox --- .github/workflows/helm-chart-ci.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/helm-chart-ci.yaml b/.github/workflows/helm-chart-ci.yaml index 6f16c92..ec7b9b3 100644 --- a/.github/workflows/helm-chart-ci.yaml +++ b/.github/workflows/helm-chart-ci.yaml @@ -186,7 +186,7 @@ jobs: version: ${{ env.CHART_TESTING_VERSION }} - name: Create kind ${{ matrix.k8s }} cluster - uses: helm/kind-action@v1.15.0 + uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -272,7 +272,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.15.0 + uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -327,7 +327,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.15.0 + uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} @@ -373,7 +373,7 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - name: Create kind cluster - uses: helm/kind-action@v1.15.0 + uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. with: version: ${{ env.KIND_VERSION }} From 2a8c1b63c45588f7d978bbd06d5ec2305f5e2a15 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Fri, 4 Sep 2026 12:50:34 -0700 Subject: [PATCH 10/12] Bottom turtle ha registry tests (#929) * Bottom turtle ha registry tests Signed-off-by: Kevin Fox * Fix test because of spire-ha-agent Signed-off-by: Kevin Fox * Fix config options Signed-off-by: Kevin Fox * Fix yq issue and log better Signed-off-by: Kevin Fox * Fix some things Signed-off-by: Kevin Fox * Change timeout and fix image Signed-off-by: Kevin Fox * Bump up zot version. Signed-off-by: Kevin Fox * More debugging stuff Signed-off-by: Kevin Fox * More debugging stuff Signed-off-by: Kevin Fox * More fixes Signed-off-by: Kevin Fox * More logging Signed-off-by: Kevin Fox * More logging Signed-off-by: Kevin Fox * More logging Signed-off-by: Kevin Fox * More logging Signed-off-by: Kevin Fox * More logging Signed-off-by: Kevin Fox * Fix test Signed-off-by: Kevin Fox * Log less Signed-off-by: Kevin Fox * Cleanup Signed-off-by: Kevin Fox * Make test less different then real deployment Signed-off-by: Kevin Fox --------- Signed-off-by: Kevin Fox Signed-off-by: kfox1111 --- .../kind/conf/credential-provider-config.yaml | 25 ++ .github/kind/conf/kind-config.yaml | 99 +++++++ .../scripts/install-image-cred-provider.sh | 37 +++ .github/tests/charts.json | 5 + .github/workflows/helm-chart-ci-ignore.yaml | 24 +- .github/workflows/helm-chart-ci.yaml | 38 ++- .gitignore | 1 + charts/spire-ha-agent/Chart.yaml | 2 +- charts/spire-ha-agent/README.md | 2 +- examples/bottom-turtle-ha/README.md | 75 +++++ .../node1-spire-ha-agent.yaml | 11 + .../example-manifests/node2-image-pull.yaml | 10 + .../example-manifests/node2-kubelet.yaml | 10 + .../example-manifests/node3-image-pull.yaml | 10 + .../example-manifests/node3-kubelet.yaml | 10 + .../example-manifests/node4-image-pull.yaml | 10 + .../example-manifests/node4-kubelet.yaml | 10 + examples/bottom-turtle-ha/image-pull-job.yaml | 34 +++ .../image-push-denied-job.yaml | 122 +++++++++ examples/bottom-turtle-ha/image-push-job.yaml | 121 +++++++++ examples/bottom-turtle-ha/run-tests.sh | 257 +++++++++++++++++- .../spire-identity-exchange-values.yaml | 43 +++ examples/bottom-turtle-ha/zot-values.yaml | 154 +++++++++++ 23 files changed, 1082 insertions(+), 28 deletions(-) create mode 100644 .github/kind/conf/credential-provider-config.yaml create mode 100755 .github/scripts/install-image-cred-provider.sh create mode 100644 examples/bottom-turtle-ha/example-manifests/node1-spire-ha-agent.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node2-image-pull.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node2-kubelet.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node3-image-pull.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node3-kubelet.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node4-image-pull.yaml create mode 100644 examples/bottom-turtle-ha/example-manifests/node4-kubelet.yaml create mode 100644 examples/bottom-turtle-ha/image-pull-job.yaml create mode 100644 examples/bottom-turtle-ha/image-push-denied-job.yaml create mode 100644 examples/bottom-turtle-ha/image-push-job.yaml create mode 100644 examples/bottom-turtle-ha/zot-values.yaml diff --git a/.github/kind/conf/credential-provider-config.yaml b/.github/kind/conf/credential-provider-config.yaml new file mode 100644 index 0000000..40d1e5b --- /dev/null +++ b/.github/kind/conf/credential-provider-config.yaml @@ -0,0 +1,25 @@ +apiVersion: kubelet.config.k8s.io/v1 +kind: CredentialProviderConfig +providers: + - name: k8s-image-cred-spire-identity-exchange + matchImages: + - "zot.production.other" + defaultCacheDuration: "0s" + apiVersion: credentialprovider.kubelet.k8s.io/v1 + args: + - "--username=zot" + - "--mode=spire-identity-exchange" + - "--url=https://spire-identity-exchange-rest-spiffe.production.other" + - "--stack=image_pull" + - "--registry-audience=zot" + - "--spiffe-audience=spire-identity-exchange" + - "--spiffe-hint=image-pull" + - "--spiffe-id=spiffe://production.other/service/spire-identity-exchange" + - "--timeout=10s" + env: + - name: SPIFFE_ENDPOINT_SOCKET + value: unix:///var/run/spire/agent/sockets/main/public/api.sock + tokenAttributes: + serviceAccountTokenAudience: "spire-identity-exchange" + cacheType: "Token" + requireServiceAccount: true diff --git a/.github/kind/conf/kind-config.yaml b/.github/kind/conf/kind-config.yaml index d98b5c6..e0a289f 100644 --- a/.github/kind/conf/kind-config.yaml +++ b/.github/kind/conf/kind-config.yaml @@ -30,6 +30,39 @@ nodes: containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-a/public - hostPath: /var/run/spiffe/socat/unix/k8s-spire-agent-2-b/public containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-b/public + # One spire-ha-agent on the host is shared by all three virtual nodes, with a + # spiffe-socat-unix bridge per node in front of it. Mount that bridge where a + # package installed spire-ha-agent@main listens, so kubelet's configuration in + # the node is the same one a real bare metal node would use. + - hostPath: /var/run/spiffe/socat/unix/k8s-kubelet-2/public + containerPath: /var/run/spire/agent/sockets/main/public + - hostPath: ./.github/kind/conf/credential-providers + containerPath: /credential-plugins + - hostPath: ./.github/kind/conf/credential-provider-config.yaml + containerPath: /etc/kubernetes/credential-provider-config.yaml + kubeadmConfigPatches: + - | + apiVersion: kubeadm.k8s.io/v1beta3 + kind: JoinConfiguration + nodeRegistration: + kubeletExtraArgs: + image-credential-provider-config: /etc/kubernetes/credential-provider-config.yaml + image-credential-provider-bin-dir: /credential-plugins + kubeadmConfigPatchesJSON6902: + - group: kubeadm.k8s.io + version: v1beta4 + kind: JoinConfiguration + patch: | + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-config + value: /etc/kubernetes/credential-provider-config.yaml + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-bin-dir + value: /credential-plugins - role: worker extraMounts: - hostPath: /var/run/spiffe/socat/unix/k8s-spire-server-a/public @@ -40,6 +73,39 @@ nodes: containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-a/public - hostPath: /var/run/spiffe/socat/unix/k8s-spire-agent-3-b/public containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-b/public + # One spire-ha-agent on the host is shared by all three virtual nodes, with a + # spiffe-socat-unix bridge per node in front of it. Mount that bridge where a + # package installed spire-ha-agent@main listens, so kubelet's configuration in + # the node is the same one a real bare metal node would use. + - hostPath: /var/run/spiffe/socat/unix/k8s-kubelet-3/public + containerPath: /var/run/spire/agent/sockets/main/public + - hostPath: ./.github/kind/conf/credential-providers + containerPath: /credential-plugins + - hostPath: ./.github/kind/conf/credential-provider-config.yaml + containerPath: /etc/kubernetes/credential-provider-config.yaml + kubeadmConfigPatches: + - | + apiVersion: kubeadm.k8s.io/v1beta3 + kind: JoinConfiguration + nodeRegistration: + kubeletExtraArgs: + image-credential-provider-config: /etc/kubernetes/credential-provider-config.yaml + image-credential-provider-bin-dir: /credential-plugins + kubeadmConfigPatchesJSON6902: + - group: kubeadm.k8s.io + version: v1beta4 + kind: JoinConfiguration + patch: | + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-config + value: /etc/kubernetes/credential-provider-config.yaml + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-bin-dir + value: /credential-plugins - role: worker extraMounts: - hostPath: /var/run/spiffe/socat/unix/k8s-spire-server-a/public @@ -50,3 +116,36 @@ nodes: containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-a/public - hostPath: /var/run/spiffe/socat/unix/k8s-spire-agent-4-b/public containerPath: /var/run/spiffe/socat/unix/k8s-spire-agent-b/public + # One spire-ha-agent on the host is shared by all three virtual nodes, with a + # spiffe-socat-unix bridge per node in front of it. Mount that bridge where a + # package installed spire-ha-agent@main listens, so kubelet's configuration in + # the node is the same one a real bare metal node would use. + - hostPath: /var/run/spiffe/socat/unix/k8s-kubelet-4/public + containerPath: /var/run/spire/agent/sockets/main/public + - hostPath: ./.github/kind/conf/credential-providers + containerPath: /credential-plugins + - hostPath: ./.github/kind/conf/credential-provider-config.yaml + containerPath: /etc/kubernetes/credential-provider-config.yaml + kubeadmConfigPatches: + - | + apiVersion: kubeadm.k8s.io/v1beta3 + kind: JoinConfiguration + nodeRegistration: + kubeletExtraArgs: + image-credential-provider-config: /etc/kubernetes/credential-provider-config.yaml + image-credential-provider-bin-dir: /credential-plugins + kubeadmConfigPatchesJSON6902: + - group: kubeadm.k8s.io + version: v1beta4 + kind: JoinConfiguration + patch: | + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-config + value: /etc/kubernetes/credential-provider-config.yaml + - op: add + path: /nodeRegistration/kubeletExtraArgs/- + value: + name: image-credential-provider-bin-dir + value: /credential-plugins diff --git a/.github/scripts/install-image-cred-provider.sh b/.github/scripts/install-image-cred-provider.sh new file mode 100755 index 0000000..29e0768 --- /dev/null +++ b/.github/scripts/install-image-cred-provider.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -euo pipefail + +VERSION="${IMAGE_CRED_PROVIDER_VERSION:-v0.5.0}" +BIN_NAME="k8s-image-cred-spire-identity-exchange" + +SCRIPTPATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BIN_DIR="${SCRIPTPATH}/../kind/conf/credential-providers" + +case "$(uname -m)" in + x86_64|amd64) ARCH="x86_64" ;; + aarch64|arm64) ARCH="arm64" ;; + *) echo "unsupported architecture: $(uname -m)" >&2; exit 1 ;; +esac + +if [ -x "${BIN_DIR}/${BIN_NAME}" ]; then + echo "${BIN_NAME} already staged in ${BIN_DIR}" + exit 0 +fi + +BASE_URL="https://github.com/spiffe/spire-identity-exchange/releases/download/${VERSION}" +ARCHIVE="${BIN_NAME}_Linux_${ARCH}.tar.gz" +CHECKSUMS="spire-identity-exchange_${VERSION#v}_checksums.txt" + +WORKDIR="$(mktemp -d)" +trap 'rm -rf "${WORKDIR}"' EXIT + +curl -fsSL --retry 5 --retry-all-errors -o "${WORKDIR}/${ARCHIVE}" "${BASE_URL}/${ARCHIVE}" +curl -fsSL --retry 5 --retry-all-errors -o "${WORKDIR}/${CHECKSUMS}" "${BASE_URL}/${CHECKSUMS}" +(cd "${WORKDIR}" && grep " ${ARCHIVE}\$" "${CHECKSUMS}" | sha256sum -c -) + +tar -xzf "${WORKDIR}/${ARCHIVE}" -C "${WORKDIR}" "${BIN_NAME}" +mkdir -p "${BIN_DIR}" +install -m 0755 "${WORKDIR}/${BIN_NAME}" "${BIN_DIR}/${BIN_NAME}" + +echo "Staged ${BIN_NAME} ${VERSION} in ${BIN_DIR}" diff --git a/.github/tests/charts.json b/.github/tests/charts.json index 19e8692..4c5666d 100644 --- a/.github/tests/charts.json +++ b/.github/tests/charts.json @@ -13,5 +13,10 @@ "name": "ingress-nginx", "repo": "https://kubernetes.github.io/ingress-nginx", "version": "4.15.1" + }, + { + "name": "zot", + "repo": "https://zotregistry.dev/helm-charts", + "version": "0.1.122" } ] diff --git a/.github/workflows/helm-chart-ci-ignore.yaml b/.github/workflows/helm-chart-ci-ignore.yaml index 0bf2124..5bde7e2 100644 --- a/.github/workflows/helm-chart-ci-ignore.yaml +++ b/.github/workflows/helm-chart-ci-ignore.yaml @@ -31,9 +31,9 @@ jobs: strategy: matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 steps: - run: 'echo "Skipping tests"' @@ -75,9 +75,9 @@ jobs: strategy: matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 example: - ${{ fromJson(needs.build-matrix.outputs.examples) }} @@ -93,9 +93,9 @@ jobs: strategy: matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 example: - ${{ fromJson(needs.build-matrix.outputs.integrationtests) }} @@ -111,9 +111,9 @@ jobs: strategy: matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 steps: - run: 'echo "Skipping upgrade-test"' diff --git a/.github/workflows/helm-chart-ci.yaml b/.github/workflows/helm-chart-ci.yaml index ec7b9b3..4867fb8 100644 --- a/.github/workflows/helm-chart-ci.yaml +++ b/.github/workflows/helm-chart-ci.yaml @@ -17,6 +17,7 @@ on: - '.github/tests/**/*.sh' - '.github/tests/**/*.json' - '.github/scripts/check-readme-versions.sh' + - '.github/scripts/install-image-cred-provider.sh' - 'examples/**/*.yaml' - 'examples/**/*.sh' - 'tests/**/*' @@ -31,6 +32,7 @@ env: PYTHON_VERSION: 3.11.3 KIND_VERSION: v0.32.0 CHART_TESTING_VERSION: v3.8.0 + IMAGE_CRED_PROVIDER_VERSION: v0.5.0 jobs: checks: @@ -160,9 +162,9 @@ jobs: # Kubernetes, but can go back farther as long as we don't need heroics # to pull it off (i.e. kubectl version juggling). k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 steps: - name: Checkout @@ -185,6 +187,9 @@ jobs: with: version: ${{ env.CHART_TESTING_VERSION }} + - name: Install image credential provider + run: ./.github/scripts/install-image-cred-provider.sh + - name: Create kind ${{ matrix.k8s }} cluster uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. @@ -251,9 +256,9 @@ jobs: fail-fast: false matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 example: - ${{ fromJson(needs.build-matrix.outputs.examples) }} @@ -271,6 +276,9 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} + - name: Install image credential provider + run: ./.github/scripts/install-image-cred-provider.sh + - name: Create kind cluster uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. @@ -306,9 +314,9 @@ jobs: fail-fast: false matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 integrationtest: - ${{ fromJson(needs.build-matrix.outputs.integrationtests) }} @@ -326,6 +334,9 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} + - name: Install image credential provider + run: ./.github/scripts/install-image-cred-provider.sh + - name: Create kind cluster uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. @@ -354,9 +365,9 @@ jobs: fail-fast: false matrix: k8s: - - v1.33.7 - - v1.34.3 - - v1.35.1 + - v1.34.8 + - v1.35.5 + - v1.36.1 steps: - name: Checkout @@ -372,6 +383,9 @@ jobs: with: python-version: ${{ env.PYTHON_VERSION }} + - name: Install image credential provider + run: ./.github/scripts/install-image-cred-provider.sh + - name: Create kind cluster uses: helm/kind-action@v1.14.0 # Only build a kind cluster if there are chart changes to test. diff --git a/.gitignore b/.gitignore index beb5ec8..3f4ab01 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ bin/ *.swp charts/**/*.tgz .DS_Store +.github/kind/conf/credential-providers/ diff --git a/charts/spire-ha-agent/Chart.yaml b/charts/spire-ha-agent/Chart.yaml index b0b9b1e..b576192 100644 --- a/charts/spire-ha-agent/Chart.yaml +++ b/charts/spire-ha-agent/Chart.yaml @@ -3,7 +3,7 @@ name: spire-ha-agent description: A Helm chart to install the SPIRE HA agent. type: application version: 0.3.1 -appVersion: "0.3.0" +appVersion: "0.4.0" keywords: ["spiffe", "spire-ha-agent"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire-ha-agent sources: diff --git a/charts/spire-ha-agent/README.md b/charts/spire-ha-agent/README.md index 915fdf6..a665cc8 100644 --- a/charts/spire-ha-agent/README.md +++ b/charts/spire-ha-agent/README.md @@ -1,6 +1,6 @@ # spire-ha-agent -![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.3.0](https://img.shields.io/badge/AppVersion-0.3.0-informational?style=flat-square) +![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.4.0](https://img.shields.io/badge/AppVersion-0.4.0-informational?style=flat-square) A Helm chart to install the SPIRE HA agent. diff --git a/examples/bottom-turtle-ha/README.md b/examples/bottom-turtle-ha/README.md index 396edb3..57796dd 100644 --- a/examples/bottom-turtle-ha/README.md +++ b/examples/bottom-turtle-ha/README.md @@ -136,3 +136,78 @@ helm upgrade --install --namespace spire-mgmt --values "spire-values.yaml" \ --set tags.bottomTurtleHAB=true \ --set "global.spire.ingressControllerType=ingress-nginx" ``` + +## Host services on the bottom turtle + +The diagrams above show a `spire-ha-agent` on each host, fed by `spire-agent@a` and +`spire-agent@b`, serving host services such as sshd and kubelet. That is what makes a host +service's identity survive one root server going away: the ha-agent merges both sides into +a single Workload API and answers from whichever side is up. + +It attests every caller by pid, so one ha-agent can serve many callers with different +identities. Register the caller against the root servers and it gets its own SVID: + +``` +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node1-spire-ha-agent +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/spire-ha-agent + selectors: + - systemd:id:spire-ha-agent@main.service + federatesWith: + - spire-ha +``` + +The packaged `spire-agent` config already names `spiffe://${SPIFFE_TRUST_DOMAIN}/spire-ha-agent` +in its `authorized_delegates`, so no agent configuration is needed, only the entry. + +## Registry image pull + +Kubelet can use that host identity to pull images, without any pull secret. On seeing an +image from the registry, kubelet runs an image credential provider on the node, which +presents two credentials to the spire-identity-exchange: the pod's projected service +account token and the node's own JWT-SVID from the ha-agent. The exchange mints a registry +token, and the registry authorizes by SPIFFE ID. + +The registry in this example is zot, deployed with the upstream chart. Its serving +certificate is a SPIRE SVID delivered by `spiffe-helper` as an init container plus a +sidecar, so nothing carries a long lived key. The identity needs an explicit DNS name, +because an X509-SVID has only a URI SAN by default and containerd validates the registry +by hostname: + +``` +zot: + spiffeIDTemplate: spiffe://{{ .TrustDomain }}/zot + podSelector: + matchLabels: + app.kubernetes.io/name: zot + dnsNameTemplates: + - zot.{{ .TrustDomain }} +``` + +Push and pull share one exchange stack. They are kept apart by their registration entries, +whose selectors are disjoint, and by the registry's own access control, which grants the +push identity write and the pull identity read only. + +### How the test deviates from the diagrams + +The test runs a single VM behind several virtual Kubernetes nodes, so a few things differ +from what you would deploy. Worth knowing if you are using this as a reference: + +* One `spire-ha-agent` is shared by every virtual node, with a `spiffe-socat-unix` bridge + per node in front of it. On a real host kubelet talks to its local ha-agent directly. + Each bridge is mounted into its node at `/var/run/spire/agent/sockets/main/public`, which + is where a package installed ha-agent listens, so kubelet's own configuration is not a + deviation: what you see here is what you would deploy. +* The registration entries do deviate. Because the caller the ha-agent attests by pid is the + bridge, they select on the socat unit rather than on kubelet's own unit. On a real host + that selector is the only line that changes. +* One ha-agent behind every node means the test covers a root server failing, which is the + part that matters here, but not a single node's ha-agent failing. +* The credential provider binary and its configuration are staged into every kind cluster + by `.github/scripts/install-image-cred-provider.sh` before the cluster is created. + Kubelet refuses to start when a provider named in its configuration is missing, so this + cannot be deferred to the test itself. diff --git a/examples/bottom-turtle-ha/example-manifests/node1-spire-ha-agent.yaml b/examples/bottom-turtle-ha/example-manifests/node1-spire-ha-agent.yaml new file mode 100644 index 0000000..670abd3 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node1-spire-ha-agent.yaml @@ -0,0 +1,11 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node1-spire-ha-agent +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/spire-ha-agent + selectors: + - systemd:id:spire-ha-agent@main.service + federatesWith: + - spire-ha diff --git a/examples/bottom-turtle-ha/example-manifests/node2-image-pull.yaml b/examples/bottom-turtle-ha/example-manifests/node2-image-pull.yaml new file mode 100644 index 0000000..7dcb0da --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node2-image-pull.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node2-image-pull +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet + hint: image-pull + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-2.service diff --git a/examples/bottom-turtle-ha/example-manifests/node2-kubelet.yaml b/examples/bottom-turtle-ha/example-manifests/node2-kubelet.yaml new file mode 100644 index 0000000..1960025 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node2-kubelet.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node2-kubelet +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet/node2.${SPIFFE_TRUST_DOMAIN} + hint: kubelet + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-2.service diff --git a/examples/bottom-turtle-ha/example-manifests/node3-image-pull.yaml b/examples/bottom-turtle-ha/example-manifests/node3-image-pull.yaml new file mode 100644 index 0000000..7538762 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node3-image-pull.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node3-image-pull +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet + hint: image-pull + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-3.service diff --git a/examples/bottom-turtle-ha/example-manifests/node3-kubelet.yaml b/examples/bottom-turtle-ha/example-manifests/node3-kubelet.yaml new file mode 100644 index 0000000..5a345e4 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node3-kubelet.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node3-kubelet +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet/node3.${SPIFFE_TRUST_DOMAIN} + hint: kubelet + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-3.service diff --git a/examples/bottom-turtle-ha/example-manifests/node4-image-pull.yaml b/examples/bottom-turtle-ha/example-manifests/node4-image-pull.yaml new file mode 100644 index 0000000..89cbe13 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node4-image-pull.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node4-image-pull +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet + hint: image-pull + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-4.service diff --git a/examples/bottom-turtle-ha/example-manifests/node4-kubelet.yaml b/examples/bottom-turtle-ha/example-manifests/node4-kubelet.yaml new file mode 100644 index 0000000..f665027 --- /dev/null +++ b/examples/bottom-turtle-ha/example-manifests/node4-kubelet.yaml @@ -0,0 +1,10 @@ +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: node4-kubelet +spec: + parentID: spiffe://${SPIFFE_TRUST_DOMAIN}/agent/node1 + spiffeID: spiffe://${SPIFFE_TRUST_DOMAIN}/kubelet/node4.${SPIFFE_TRUST_DOMAIN} + hint: kubelet + selectors: + - systemd:id:spiffe-socat-unix@k8s-kubelet-4.service diff --git a/examples/bottom-turtle-ha/image-pull-job.yaml b/examples/bottom-turtle-ha/image-pull-job.yaml new file mode 100644 index 0000000..fe6b397 --- /dev/null +++ b/examples/bottom-turtle-ha/image-pull-job.yaml @@ -0,0 +1,34 @@ +# Pulls the image zot only serves to an exchange-minted identity. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: zot-pull +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: image-pull +spec: + backoffLimit: 0 + template: + metadata: + labels: + app: image-pull + spec: + serviceAccountName: zot-pull + restartPolicy: Never + containers: + - name: main + image: zot.production.other/test/busybox:latest + imagePullPolicy: Always + command: ["sh", "-c", "echo IMAGE-PULL-OK"] + # The node authorizer only lets kubelet mint a service account token for an audience + # that appears in the pod spec. This must be here to work, even if it looks unused. + volumes: + - name: spire-token-gate + projected: + sources: + - serviceAccountToken: + path: token + audience: spire-identity-exchange + expirationSeconds: 3600 diff --git a/examples/bottom-turtle-ha/image-push-denied-job.yaml b/examples/bottom-turtle-ha/image-push-denied-job.yaml new file mode 100644 index 0000000..068711b --- /dev/null +++ b/examples/bottom-turtle-ha/image-push-denied-job.yaml @@ -0,0 +1,122 @@ +# Negative control: the pull identity must not be able to write. Identical to image-push-job.yaml except the service account +apiVersion: batch/v1 +kind: Job +metadata: + name: image-push-denied +spec: + backoffLimit: 0 + template: + metadata: + labels: + app: image-push-denied + spec: + serviceAccountName: zot-pull + restartPolicy: Never + initContainers: + - name: static-busybox + # Replaced by run-tests.sh with the image from the spiffe-oidc-discovery-provider chart + image: IMAGE_BUSYBOX + command: ["sh", "-c", "cp /bin/busybox /data/busybox && chmod +x /data/busybox"] + volumeMounts: + - name: data-volume + mountPath: /data + - name: fetch-svid + # Replaced by run-tests.sh with the image from the spire-agent chart + image: IMAGE_SPIRE_AGENT + command: + - /data/busybox + - sh + - -xec + - | + SOCK=/spire-agent/spire-agent.sock + i=0 + while [ "$i" -lt 30 ]; do + if /opt/spire/bin/spire-agent api fetch x509 -socketPath "$SOCK" -write /data -timeout 5s && + /opt/spire/bin/spire-agent api fetch jwt -audience spire-identity-exchange -socketPath "$SOCK" -timeout 5s > /data/jwt.txt; then + break + fi + i=$((i+1)) + /data/busybox sleep 2 + done + if [ ! -s /data/jwt.txt ]; then + echo "no SVID for this pod after ${i} attempts" + exit 1 + fi + /data/busybox grep -A1 'token(' /data/jwt.txt | /data/busybox tail -1 | /data/busybox tr -d '[:space:]' > /data/svid.jwt + test -s /data/svid.jwt + volumeMounts: + - name: data-volume + mountPath: /data + - name: spire-api + mountPath: /spire-agent + readOnly: true + - name: exchange + # Replaced by run-tests.sh with the toolkit image from the spiffe-oidc-discovery-provider chart + image: IMAGE_TOOLKIT + command: + - sh + - -xec + - | + cat /etc/ssl/certs/ca-certificates.crt /data/bundle.0.pem > /data/ca-bundle.pem + + PSAT="$(cat /var/run/secrets/tokens/token)" + SVID="$(cat /data/svid.jwt)" + # This must still succeed. A separate registration entry matches this pod's + # credentials and mints the read only identity, so the exchange hands back a + # token; it is zot that refuses the write. + TOKEN="$(curl -k -sS --fail-with-body --max-time 60 --connect-timeout 10 -X POST \ + -H "Authorization: Bearer k8s_psat=${PSAT}:spiffe=${SVID}" \ + -H "Content-Type: application/json" \ + -d '{"audiences": ["zot"]}' \ + "https://spire-identity-exchange-rest.production.other/api/v1/svid/image_pull/jwt" \ + | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')" + test -n "${TOKEN}" + + AUTH="$(printf 'zot:%s' "${TOKEN}" | base64 | tr -d '\n')" + printf '{"auths":{"zot.production.other":{"auth":"%s"}}}' "${AUTH}" > /docker-config/config.json + volumeMounts: + - name: data-volume + mountPath: /data + - name: docker-config + mountPath: /docker-config + - name: psat + mountPath: /var/run/secrets/tokens + readOnly: true + containers: + - name: push + image: gcr.io/go-containerregistry/crane:v0.21.9 + env: + - name: DOCKER_CONFIG + value: /docker-config + - name: SSL_CERT_FILE + value: /data/ca-bundle.pem + # The crane image is distroless, so borrow the static busybox copied out earlier. + command: ["/data/busybox", "sh", "-c"] + args: + - | + if /ko-app/crane copy docker.io/library/busybox:latest zot.production.other/test/denied:latest; then + echo "PUSH-SHOULD-HAVE-BEEN-DENIED" + exit 1 + fi + echo PUSH-DENIED-OK + volumeMounts: + - name: data-volume + mountPath: /data + - name: docker-config + mountPath: /docker-config + volumes: + - name: data-volume + emptyDir: {} + - name: docker-config + emptyDir: {} + - name: spire-api + csi: + driver: csi.spiffe.io + readOnly: true + - name: psat + projected: + sources: + - serviceAccountToken: + path: token + audience: spire-identity-exchange + expirationSeconds: 3600 diff --git a/examples/bottom-turtle-ha/image-push-job.yaml b/examples/bottom-turtle-ha/image-push-job.yaml new file mode 100644 index 0000000..943a340 --- /dev/null +++ b/examples/bottom-turtle-ha/image-push-job.yaml @@ -0,0 +1,121 @@ +# Pushes an image into zot using an identity minted by the spire-identity-exchange. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: zot-push +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: image-push +spec: + backoffLimit: 0 + template: + metadata: + labels: + app: image-push + spec: + serviceAccountName: zot-push + restartPolicy: Never + initContainers: + - name: static-busybox + # Replaced by run-tests.sh with the image from the spiffe-oidc-discovery-provider chart + image: IMAGE_BUSYBOX + command: ["sh", "-c", "cp /bin/busybox /data/busybox && chmod +x /data/busybox"] + volumeMounts: + - name: data-volume + mountPath: /data + - name: fetch-svid + # Replaced by run-tests.sh with the image from the spire-agent chart + image: IMAGE_SPIRE_AGENT + command: + - /data/busybox + - sh + - -xec + - | + SOCK=/spire-agent/spire-agent.sock + i=0 + while [ "$i" -lt 30 ]; do + if /opt/spire/bin/spire-agent api fetch x509 -socketPath "$SOCK" -write /data -timeout 5s && + /opt/spire/bin/spire-agent api fetch jwt -audience spire-identity-exchange -socketPath "$SOCK" -timeout 5s > /data/jwt.txt; then + break + fi + i=$((i+1)) + /data/busybox sleep 2 + done + if [ ! -s /data/jwt.txt ]; then + echo "no SVID for this pod after ${i} attempts" + exit 1 + fi + /data/busybox grep -A1 'token(' /data/jwt.txt | /data/busybox tail -1 | /data/busybox tr -d '[:space:]' > /data/svid.jwt + test -s /data/svid.jwt + volumeMounts: + - name: data-volume + mountPath: /data + - name: spire-api + mountPath: /spire-agent + readOnly: true + - name: exchange + # Replaced by run-tests.sh with the toolkit image from the spiffe-oidc-discovery-provider chart + image: IMAGE_TOOLKIT + command: + - sh + - -xec + - | + # crane talks to both docker.io and zot, so it needs the public roots and the + # SPIRE bundle in one file. + cat /etc/ssl/certs/ca-certificates.crt /data/bundle.0.pem > /data/ca-bundle.pem + + PSAT="$(cat /var/run/secrets/tokens/token)" + SVID="$(cat /data/svid.jwt)" + TOKEN="$(curl -k -sS --fail-with-body --max-time 60 --connect-timeout 10 -X POST \ + -H "Authorization: Bearer k8s_psat=${PSAT}:spiffe=${SVID}" \ + -H "Content-Type: application/json" \ + -d '{"audiences": ["zot"]}' \ + "https://spire-identity-exchange-rest.production.other/api/v1/svid/image_pull/jwt" \ + | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')" + test -n "${TOKEN}" + + AUTH="$(printf 'zot:%s' "${TOKEN}" | base64 | tr -d '\n')" + printf '{"auths":{"zot.production.other":{"auth":"%s"}}}' "${AUTH}" > /docker-config/config.json + volumeMounts: + - name: data-volume + mountPath: /data + - name: docker-config + mountPath: /docker-config + - name: psat + mountPath: /var/run/secrets/tokens + readOnly: true + containers: + - name: push + image: gcr.io/go-containerregistry/crane:v0.21.9 + env: + - name: DOCKER_CONFIG + value: /docker-config + - name: SSL_CERT_FILE + value: /data/ca-bundle.pem + args: + - copy + - docker.io/library/busybox:latest + - zot.production.other/test/busybox:latest + volumeMounts: + - name: data-volume + mountPath: /data + - name: docker-config + mountPath: /docker-config + volumes: + - name: data-volume + emptyDir: {} + - name: docker-config + emptyDir: {} + - name: spire-api + csi: + driver: csi.spiffe.io + readOnly: true + - name: psat + projected: + sources: + - serviceAccountToken: + path: token + audience: spire-identity-exchange + expirationSeconds: 3600 diff --git a/examples/bottom-turtle-ha/run-tests.sh b/examples/bottom-turtle-ha/run-tests.sh index e5a69e1..965838c 100755 --- a/examples/bottom-turtle-ha/run-tests.sh +++ b/examples/bottom-turtle-ha/run-tests.sh @@ -74,6 +74,10 @@ teardown() { sudo systemctl status spire-server@other || true kubectl describe job federation-test || true kubectl logs job/federation-test || true + sudo systemctl status spire-ha-agent@main || true + sudo systemctl status spiffe-socat-unix@k8s-kubelet-2 || true + sudo systemctl status spiffe-socat-unix@k8s-kubelet-3 || true + sudo systemctl status spiffe-socat-unix@k8s-kubelet-4 || true sudo spire-server entry show -instance a || true sudo spire-server entry show -instance b || true sudo systemctl status spire-controller-manager@a || true @@ -107,10 +111,20 @@ teardown() { if [[ "$1" -ne 0 ]]; then get_namespace_details spire-server spire-system kubectl describe pod -n spire-system + # Only on failure: these are verbose, and the kubelet journal in particular is what + # tells you why an image pull came back anonymous rather than using the plugin. + for JOB in image-push image-pull image-push-denied; do + dump_job "${JOB}" + done + dump_zot + dump_kubelet_all fi if [ "${CLEANUP}" -eq 1 ]; then kubectl delete job federation-test 2>/dev/null || true + kubectl delete job image-push image-pull image-push-denied 2>/dev/null || true + helm uninstall --namespace zot zot 2>/dev/null || true + kubectl delete ns zot 2>/dev/null || true helm uninstall --namespace spire-mgmt spire-b 2>/dev/null || true helm uninstall --namespace spire-mgmt spire-a 2>/dev/null || true helm uninstall --namespace spire-mgmt spire 2>/dev/null || true @@ -154,6 +168,120 @@ wait_for_trust_sync() { return 1 } +# Dump everything useful about a job in one block. The trace goes to stderr while command +# output goes to stdout, and the two are separate streams in the CI log, so anything printed +# here can interleave or drop. Suspend the trace, merge each command's streams, and bracket +# the whole thing so it stays readable. +dump_job() { + local job="$1" + set +x + echo "===== BEGIN ${job} =====" + kubectl get pods -l "job-name=${job}" -o wide 2>&1 || true + kubectl describe job "${job}" 2>&1 || true + # Pod events are where image pull and volume failures show up; the job has none of this. + kubectl describe pod -l "job-name=${job}" 2>&1 || true + # --prefix labels each line with its container. These jobs have three init containers and + # the interesting output is rarely the last one. + kubectl logs "job/${job}" --all-containers --prefix 2>&1 || true + # Everything kubelet said about this pod on the node that ran it. Filtering on the image + # misses the credential provider path, which names the pod and service account instead, + # and only the first pull attempt carries the real error; the retries are all backoff. + local pod node + for pod in $(kubectl get pods -l "job-name=${job}" -o name 2>/dev/null | cut -d/ -f2); do + node="$(kubectl get pod "${pod}" -o jsonpath='{.spec.nodeName}' 2>/dev/null)" + [ -n "${node}" ] || continue + echo "----- kubelet ${node} for pod ${pod} -----" + # Only this pod. A broader filter matches every provider line since boot and the + # window fills long before the pull happens. + docker exec -i "${node}" journalctl -u kubelet --no-pager 2>&1 \ + | grep -F "${pod}" | head -60 || true + # The plugin exec is logged against the image and plugin name, not the pod, so a pod + # filter hides exactly the line that says whether it ran and what it returned. + echo "----- kubelet ${node} credential provider decisions -----" + docker exec -i "${node}" journalctl -u kubelet --no-pager 2>&1 \ + | grep -E 'exec plugin|image credentials|k8s-image-cred|without credentials|zot\.production\.other|[Ss]ervice account' \ + | tail -40 || true + done + echo "===== END ${job} =====" + set -x +} + +# Same treatment as dump_job. zot logs at debug, and its rejection reason for a bearer +# token only appears there, so take the whole log rather than a tail. +dump_zot() { + set +x + echo "===== BEGIN zot =====" + kubectl get pods -n zot -o wide 2>&1 || true + kubectl describe pod -n zot -l app.kubernetes.io/name=zot 2>&1 || true + kubectl logs -n zot -l app.kubernetes.io/name=zot --all-containers --prefix 2>&1 || true + echo "===== END zot =====" + set -x +} + +# Whether kubelet was configured with the image credential provider at all, and whether it +# ran it. The kubeadm patch landing is the whole question when a pull comes back anonymous. +dump_kubelet() { + local node="$1" + set +x + echo "===== BEGIN kubelet ${node} =====" + docker exec -i "${node}" cat /var/lib/kubelet/kubeadm-flags.env 2>&1 || true + docker exec -i "${node}" ps ax 2>&1 | grep '[k]ubelet' || true + docker exec -i "${node}" ls -l /credential-plugins /etc/kubernetes/credential-provider-config.yaml 2>&1 || true + # The plugin reaches the workload API through this bridge. If the socket is absent the + # plugin fails immediately, kubelet falls back to anonymous, and the pull 401s. + docker exec -i "${node}" ls -l /var/run/spire/agent/sockets/main/public/ 2>&1 || true + # Only the registry we care about. A broad credential grep is pure noise at v=4, which + # logs a provider line for every image pull on the node. + docker exec -i "${node}" journalctl -u kubelet --no-pager 2>&1 \ + | grep -E 'zot\.production\.other' -A3 | tail -60 || true + echo "===== END kubelet ${node} =====" + set -x +} + +dump_kubelet_all() { + for NODE in $(kubectl get nodes -o name 2>/dev/null | cut -d/ -f2); do + dump_kubelet "${NODE}" + done +} + +# kubectl wait --for=condition=complete blocks the full timeout when a job has already +# failed, which makes every failure look like a hang and delays the dump by minutes. Poll +# both terminal conditions instead. +wait_for_job() { + local job="$1" + local timeout="${2:-120}" + local count=0 + while [ "$count" -lt "$timeout" ]; do + if kubectl get job "$job" -o jsonpath='{.status.conditions[?(@.type=="Complete")].status}' 2>/dev/null | grep -q True; then + return 0 + fi + if kubectl get job "$job" -o jsonpath='{.status.conditions[?(@.type=="Failed")].status}' 2>/dev/null | grep -q True; then + echo "job/$job failed" + dump_job "$job" + return 1 + fi + sleep 1 + ((count++)) || true + done + echo "job/$job did not finish within ${timeout}s" + dump_job "$job" + return 1 +} + +wait_for_socket() { + local socket="$1" + local timeout=30 + local count=0 + while [ "$count" -lt "$timeout" ]; do + if [ -S "$socket" ]; then + return 0 + fi + sleep 1 + ((count++)) || true + done + return 1 +} + wait_for_jwt() { local socket="$1" local timeout=30 @@ -199,11 +327,19 @@ run_federation_test_job() { # Get the package repo and install the packages sudo curl -s -o /etc/apt/sources.list.d/spire-examples.list https://raw.githubusercontent.com/spiffe/spire-examples/refs/heads/main/examples/debs/amd64/spire-examples.list sudo apt-get update -sudo apt-get install -y spire-common spire-agent spire-server spire-controller-manager spiffe-socat-unix socat spire-trust-sync spiffe-helper +sudo apt-get install -y spire-common spire-agent spire-server spire-controller-manager spiffe-socat-unix socat spire-trust-sync spiffe-helper spire-ha-agent # Set our testing trust domain sudo sed -i 's/example.org/production.other/' /etc/spiffe/default-trust-domain.env +# A trust domain has one OIDC discovery endpoint, but the packaged root server config +# advertises oidc-discovery-provider. while the charts advertise +# oidc-discovery.. The identity exchange checks the iss claim by exact string, +# so a JWT-SVID minted by a root server, which is what kubelet's credential provider +# presents, is rejected unless the two agree. Align the roots with the charts. +sudo sed -i 's|jwt_issuer = "https://oidc-discovery-provider\.|jwt_issuer = "https://oidc-discovery.|' /etc/spire/server/default.conf +grep jwt_issuer /etc/spire/server/default.conf + if [ "${BROKER}" -eq 1 ]; then # Pull the federation test job images out of the charts so they always sync up. AGENT_IMAGE=$(helm template t charts/spire -s charts/spire-agent/templates/daemonset.yaml --values "${COMMON_TEST_YOUR_VALUES}" --set spire-agent.enabled=true | yq e 'select(.kind=="DaemonSet") | .spec.template.spec.containers[] | select(.name=="spire-agent") | .image' -) @@ -317,6 +453,36 @@ wait_for_jwt /var/run/spiffe/socat/unix/k8s-spire-agent-3-b/public/api.sock wait_for_jwt /var/run/spiffe/socat/unix/k8s-spire-agent-4-a/public/api.sock wait_for_jwt /var/run/spiffe/socat/unix/k8s-spire-agent-4-b/public/api.sock +# Start the host spire-ha-agent. It merges the two root agents into one workload API, which is +# what lets host services keep their identity when a single root server goes away. The compiled +# in defaults already point at /var/run/spire/agent/sockets/{a,b}/private/admin.sock and listen +# on the main instance socket, and the packaged agent config already lists the ha-agent in its +# authorized_delegates, so no configuration is needed. +sudo systemctl start spire-ha-agent@main +# Not wait_for_healthcheck: that calls the grpc.health.v1 service, which the ha-agent does +# not serve, so it always reports "unable to determine health". Not wait_for_jwt either: +# the ha-agent attests callers by pid, and the cli invoking it is in no registered unit. +# Readiness is proven through the bridges below, where the caller does have an entry. +wait_for_socket /var/run/spire/agent/sockets/main/public/api.sock + +# Bridge the merged workload API into each virtual node for kubelet's image credential provider. +# A real deployment runs one ha-agent per host and kubelet talks to it directly. Here a single VM +# backs three virtual nodes, so we put one socat instance in front of the shared ha-agent per +# node. The ha-agent attests each caller by pid, so every bridge resolves to its own entry and +# each node still gets a distinct identity. Each bridge is mounted into its node at +# /var/run/spire/agent/sockets/main/public, where a package installed ha-agent listens, so +# kubelet's configuration inside the node is the same one a real host would use. +sudo /bin/bash -c "echo SPIFFE_INSTANCE=main > /etc/spiffe/socat/unix/k8s-kubelet-2.conf" +sudo /bin/bash -c "echo SPIFFE_INSTANCE=main > /etc/spiffe/socat/unix/k8s-kubelet-3.conf" +sudo /bin/bash -c "echo SPIFFE_INSTANCE=main > /etc/spiffe/socat/unix/k8s-kubelet-4.conf" +sudo systemctl start spiffe-socat-unix@k8s-kubelet-2 spiffe-socat-unix@k8s-kubelet-3 spiffe-socat-unix@k8s-kubelet-4 +# These front the ha-agent rather than a spire-agent, so healthcheck does not apply here +# either. Fetching an svid is the real signal: it exercises the bridge, the ha-agent and +# whichever root agent answered. +wait_for_jwt /var/run/spiffe/socat/unix/k8s-kubelet-2/public/api.sock +wait_for_jwt /var/run/spiffe/socat/unix/k8s-kubelet-3/public/api.sock +wait_for_jwt /var/run/spiffe/socat/unix/k8s-kubelet-4/public/api.sock + # Deploy an ingress controller IP=$(kubectl get nodes chart-testing-control-plane -o go-template='{{ range .status.addresses }}{{ if eq .type "InternalIP" }}{{ .address }}{{ end }}{{ end }}') helm upgrade --install ingress-nginx ingress-nginx --version "$VERSION_INGRESS_NGINX" --repo "$HELM_REPO_INGRESS_NGINX" \ @@ -332,7 +498,7 @@ common_test_url "$IP" # Get the host IP And add spire-server-[ab].${trust_domain} records to it so the spire-servers can talk back to root servers running on the host HOSTIP=$(ip addr show docker0 | grep 'inet ' | awk '{print $2}' | cut -d/ -f1) kubectl get configmap -n kube-system coredns -o yaml | grep hosts || kubectl get configmap -n kube-system coredns -o yaml | sed "/ready/a\ hosts {\n fallthrough\n }" | kubectl apply -f - -kubectl get configmap -n kube-system coredns -o yaml | grep production.other || kubectl get configmap -n kube-system coredns -o yaml | sed "/hosts/a\ $HOSTIP spire-server-a.production.other\n $IP oidc-discovery.production.other\n $HOSTIP spire-server-b.production.other\n 127.0.0.1 $FEDERATION_ENDPOINT_HOST\n" | kubectl apply -f - +kubectl get configmap -n kube-system coredns -o yaml | grep production.other || kubectl get configmap -n kube-system coredns -o yaml | sed "/hosts/a\ $HOSTIP spire-server-a.production.other\n $IP oidc-discovery.production.other\n $HOSTIP spire-server-b.production.other\n $IP zot.production.other\n $IP spire-identity-exchange-rest.production.other\n 127.0.0.1 $FEDERATION_ENDPOINT_HOST\n" | kubectl apply -f - kubectl rollout restart -n kube-system deployment/coredns kubectl rollout status -n kube-system -w --timeout=1m deploy/coredns @@ -343,6 +509,10 @@ helm upgrade --install --create-namespace --namespace spire-mgmt --values "${COM --set "global.spire.namespaces.create=true" \ --set "global.spire.ingressControllerType=ingress-nginx" \ --set "spiffe-oidc-discovery-provider.ingress.enabled=true" \ + --set "spireIdentityExchange.tls.rest.enabled=true" \ + --set "spireIdentityExchange.tls.rest.ingress.enabled=true" \ + --set "spireIdentityExchange.spiffe.rest.enabled=true" \ + --set "spireIdentityExchange.spiffe.rest.ingress.enabled=true" \ "${BROKER_MODE_ARGS[@]}" # Create spire-identity-exchange cert for testing. @@ -422,6 +592,80 @@ TOKEN=$(kubectl logs job/test) curl --fail-with-body -H "Authorization: Bearer ${TOKEN}" -X POST --resolve "spire-identity-exchange-a-rest.production.other:443:$IP" "https://spire-identity-exchange-a-rest.production.other/api/v1/svid/k8s_psat/x509" -k -sS -q curl --fail-with-body -H "Authorization: Bearer ${TOKEN}" -X POST --resolve "spire-identity-exchange-b-rest.production.other:443:$IP" "https://spire-identity-exchange-b-rest.production.other/api/v1/svid/k8s_psat/x509" -k -sS -q +# Registry image pull. zot serves a SPIRE issued certificate, an in cluster job pushes an +# image with an identity minted by the exchange, and kubelet pulls it back through the +# image credential provider staged on every node by .github/scripts. + +# Nodes are not cluster DNS clients, so coredns does nothing for containerd. Give each +# node the name directly, and a hosts.toml so it trusts the registry's SPIRE certificate. +# The bundle has to carry both roots: after a failover the certificate is issued by the +# other side's chain. +sudo spire-server bundle show -socketPath /run/spire/server/sockets/a/private/api.sock | sudo tee /tmp/zot-ca.pem > /dev/null +sudo spire-server bundle show -socketPath /run/spire/server/sockets/b/private/api.sock | sudo tee -a /tmp/zot-ca.pem > /dev/null +for NODE in $(kubectl get nodes -o name | cut -d/ -f2); do + # The credential provider runs on the node, not in a pod, so it resolves the registry + # and the exchange here rather than through coredns. + docker exec -i "${NODE}" /bin/bash -c "grep -q zot.production.other /etc/hosts || echo '$IP zot.production.other spire-identity-exchange-rest-spiffe.production.other' >> /etc/hosts" + docker exec -i "${NODE}" /bin/bash -c "mkdir -p /etc/containerd/certs.d/zot.production.other" + docker exec -i "${NODE}" /bin/bash -c "cat > /etc/containerd/certs.d/zot.production.other/zot-ca.pem" < /tmp/zot-ca.pem + docker exec -i "${NODE}" /bin/bash -c "cat > /etc/containerd/certs.d/zot.production.other/hosts.toml" < "${rendered}" + # Fail loudly rather than applying a half substituted manifest. + if grep -q 'IMAGE_BUSYBOX\|IMAGE_SPIRE_AGENT\|IMAGE_TOOLKIT' "${rendered}"; then + echo "unsubstituted image placeholder left in ${rendered}" + exit 1 + fi + kubectl apply -f "${rendered}" +} + +# Push with the writer identity. +apply_registry_job "${SCRIPTPATH}/image-push-job.yaml" +wait_for_job image-push + +# Pull it back. Nothing in the job fetches a credential; kubelet runs the plugin, which is +# the whole point of the test. +kubectl apply -f "${SCRIPTPATH}/image-pull-job.yaml" +wait_for_job image-pull +# Completing at all is the assertion: zot grants no anonymous access, so the image only +# comes down if kubelet ran the plugin and the exchange minted a token zot accepted. The +# kubelet log line naming the plugin needs -v=4, which is not worth turning on for every +# example, so teardown prints it as a diagnostic rather than asserting on it. +kubectl logs job/image-pull | grep IMAGE-PULL-OK + +# The pull identity is read only. This job completes only when zot refuses the write. +apply_registry_job "${SCRIPTPATH}/image-push-denied-job.yaml" +wait_for_job image-push-denied +kubectl logs job/image-push-denied | grep PUSH-DENIED-OK + if [ "${BROKER}" -eq 1 ]; then # Verify a workload on the ha-agent socket receives the other.invalid federated trust bundles, # x509 and jwt, merged from both sides. @@ -441,3 +685,12 @@ if [ "${BROKER}" -eq 1 ]; then run_federation_test_job fi +# The image pull path has to survive losing a side too. Everything it depends on is HA: +# the node's identity comes from the host spire-ha-agent, and the credential provider +# talks to the combined exchange endpoint rather than either side directly. Delete the +# job first so this is a genuine second pull rather than a cached result. +kubectl delete job image-pull +kubectl apply -f "${SCRIPTPATH}/image-pull-job.yaml" +wait_for_job image-pull +kubectl logs job/image-pull | grep IMAGE-PULL-OK + diff --git a/examples/bottom-turtle-ha/spire-identity-exchange-values.yaml b/examples/bottom-turtle-ha/spire-identity-exchange-values.yaml index d6a93f9..5c7e0f2 100644 --- a/examples/bottom-turtle-ha/spire-identity-exchange-values.yaml +++ b/examples/bottom-turtle-ha/spire-identity-exchange-values.yaml @@ -1,6 +1,14 @@ internal-spire-server-bottom-turtle-ha-a: &server controllerManager: identities: + clusterSPIFFEIDs: + zot: + spiffeIDTemplate: spiffe://{{ .TrustDomain }}/zot + podSelector: + matchLabels: + app.kubernetes.io/name: zot + dnsNameTemplates: + - zot.{{ .TrustDomain }} clusterStaticEntries: test: parentID: spiffe://production.other/spire-identity-exchange @@ -8,6 +16,33 @@ internal-spire-server-bottom-turtle-ha-a: &server selectors: - k8s_psat:namespace:default - k8s_psat:service_account_name:default + + image-push: + parentID: spiffe://production.other/spire-identity-exchange + spiffeID: spiffe://production.other/image-push + selectors: + - k8s_psat:namespace:default + - k8s_psat:service_account_name:zot-push + - spiffe:source_path:/ns/default/sa/zot-push + - spire_identity_exchange:stack:name:image_pull + + image-pull: + parentID: spiffe://production.other/spire-identity-exchange + spiffeID: spiffe://production.other/image-pull + selectors: + - k8s_psat:namespace:default + - k8s_psat:service_account_name:zot-pull + - spiffe:source_path:/kubelet + - spire_identity_exchange:stack:name:image_pull + + image-pull-from-pod: + parentID: spiffe://production.other/spire-identity-exchange + spiffeID: spiffe://production.other/image-pull + selectors: + - k8s_psat:namespace:default + - k8s_psat:service_account_name:zot-pull + - spiffe:source_path:/ns/default/sa/zot-pull + - spire_identity_exchange:stack:name:image_pull spireIdentityExchange: enabled: true @@ -30,6 +65,14 @@ spire-identity-exchange-bottom-turtle-ha-a: &six config: allowedServiceAccounts: - default/default + - default/zot-push + - default/zot-pull + spiffe: + config: + pathPatterns: + - "^/kubelet$" + - "^/ns/default/sa/zot-push$" + - "^/ns/default/sa/zot-pull$" #Set the same settings on the B side spire-identity-exchange-bottom-turtle-ha-b: *six diff --git a/examples/bottom-turtle-ha/zot-values.yaml b/examples/bottom-turtle-ha/zot-values.yaml new file mode 100644 index 0000000..953b8f4 --- /dev/null +++ b/examples/bottom-turtle-ha/zot-values.yaml @@ -0,0 +1,154 @@ +# zot registry with a SPIRE issued serving certificate. + +image: + tag: v2.1.20 + +initContainers: + - name: spiffe-helper-init + image: ghcr.io/spiffe/spiffe-helper:0.11.0 + args: ["-config", "/etc/spiffe-helper.conf", "-daemon-mode=false"] + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: spiffe-workload-api + mountPath: /spiffe-workload-api + readOnly: true + - name: zot-config + mountPath: /etc/spiffe-helper.conf + subPath: spiffe-helper.conf + readOnly: true + - name: spire-svid + mountPath: /svid + +extraContainers: + - name: spiffe-helper + image: ghcr.io/spiffe/spiffe-helper:0.11.0 + args: ["-config", "/etc/spiffe-helper.conf"] + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + readOnlyRootFilesystem: true + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + volumeMounts: + - name: spiffe-workload-api + mountPath: /spiffe-workload-api + readOnly: true + - name: zot-config + mountPath: /etc/spiffe-helper.conf + subPath: spiffe-helper.conf + readOnly: true + - name: spire-svid + mountPath: /svid + +extraVolumes: + - name: spire-svid + emptyDir: {} + - name: spiffe-workload-api + csi: + driver: csi.spiffe.io + readOnly: true + +extraVolumeMounts: + - name: spire-svid + mountPath: /svid + readOnly: true + +podSecurityContext: + fsGroupChangePolicy: OnRootMismatch + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + +securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + capabilities: + drop: [ALL] + seccompProfile: + type: RuntimeDefault + +resources: {} + +httpGet: + scheme: HTTPS + port: 5000 + +startupProbe: + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 30 + +mountConfig: true +configFiles: + spiffe-helper.conf: |- + agent_address = "/spiffe-workload-api/spire-agent.sock" + cert_dir = "/svid" + svid_file_name = "tls.crt" + svid_key_file_name = "tls.key" + svid_bundle_file_name = "ca.pem" + config.json: |- + { + "storage": { "rootDirectory": "/var/lib/registry" }, + "http": { + "address": "0.0.0.0", + "port": "5000", + "compat": ["docker2s2"], + "tls": { "cert": "/svid/tls.crt", "key": "/svid/tls.key" }, + "realm": "zot", + "auth": { + "bearer": { + "realm": "https://zot.production.other/zot/auth/token", + "service": "https://zot.production.other", + "oidc": [ + { + "issuer": "https://oidc-discovery.production.other", + "audiences": ["zot"], + "certificateAuthorityFile": "/svid/ca.pem", + "claimMapping": { "username": "claims.sub" } + } + ] + } + }, + "accessControl": { + "repositories": { + "**": { + "policies": [ + { + "users": ["spiffe://production.other/image-push"], + "actions": ["read", "create", "update", "delete"] + }, + { + "users": ["spiffe://production.other/image-pull"], + "actions": ["read"] + } + ] + } + } + } + }, + "log": { "level": "debug" } + } + +service: + type: ClusterIP + +ingress: + enabled: true + className: nginx + pathtype: Prefix + annotations: + nginx.ingress.kubernetes.io/ssl-passthrough: "true" + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + hosts: + - host: zot.production.other + paths: + - path: / From 90e3518dcaead08fb61c4f1c794acd951bd9afa1 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Fri, 4 Sep 2026 13:34:10 -0700 Subject: [PATCH 11/12] Update spire-ha-agent (#936) * Update spire-ha-agent Signed-off-by: Kevin Fox * Update spire-ha-agent Signed-off-by: Kevin Fox * Update with new features Signed-off-by: Kevin Fox * Updates Signed-off-by: Kevin Fox * Point at release Signed-off-by: Kevin Fox * Fix version Signed-off-by: Kevin Fox --------- Signed-off-by: Kevin Fox Co-authored-by: Faisal Memon --- charts/spire-ha-agent/Chart.yaml | 2 +- charts/spire-ha-agent/README.md | 149 ++++---- charts/spire-ha-agent/templates/_helpers.tpl | 9 + .../spire-ha-agent/templates/configmap.yaml | 94 ++++++ .../spire-ha-agent/templates/daemonset.yaml | 77 +++-- .../spire-ha-agent/templates/podmonitor.yaml | 27 ++ charts/spire-ha-agent/values.yaml | 55 +++ charts/spire/charts/spire-agent/README.md | 319 +++++++++--------- .../charts/spire-agent/templates/_helpers.tpl | 46 +++ .../spire-agent/templates/configmap.yaml | 2 +- .../charts/spire-agent/templates/roles.yaml | 55 +++ charts/spire/charts/spire-agent/values.yaml | 7 +- 12 files changed, 592 insertions(+), 250 deletions(-) create mode 100644 charts/spire-ha-agent/templates/configmap.yaml create mode 100644 charts/spire-ha-agent/templates/podmonitor.yaml diff --git a/charts/spire-ha-agent/Chart.yaml b/charts/spire-ha-agent/Chart.yaml index b576192..5ecadea 100644 --- a/charts/spire-ha-agent/Chart.yaml +++ b/charts/spire-ha-agent/Chart.yaml @@ -3,7 +3,7 @@ name: spire-ha-agent description: A Helm chart to install the SPIRE HA agent. type: application version: 0.3.1 -appVersion: "0.4.0" +appVersion: "0.5.0" keywords: ["spiffe", "spire-ha-agent"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire-ha-agent sources: diff --git a/charts/spire-ha-agent/README.md b/charts/spire-ha-agent/README.md index a665cc8..2f8d44e 100644 --- a/charts/spire-ha-agent/README.md +++ b/charts/spire-ha-agent/README.md @@ -1,6 +1,6 @@ # spire-ha-agent -![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.4.0](https://img.shields.io/badge/AppVersion-0.4.0-informational?style=flat-square) +![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0](https://img.shields.io/badge/AppVersion-0.5.0-informational?style=flat-square) A Helm chart to install the SPIRE HA agent. @@ -24,67 +24,86 @@ A Helm chart to install the SPIRE HA agent. ### Chart parameters -| Name | Description | Value | -| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `image.repository` | The repository within the registry | `spiffe/spire-ha-agent` | -| `image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | -| `mode` | If the spire-ha-agent will run in delegated or broker mode | `delegated` | -| `singleSocket` | If in singleSocket mode, only one driver is used | `false` | -| `sockets.single.admin.hostPath` | Where the admin socket is on disk when in single socket mode | `/var/run/spire/agent/sockets/main/csi.spiffe.io/admin` | -| `sockets.a.admin.hostPath` | Where the a admin socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/admin` | -| `sockets.b.admin.hostPath` | Where the b admin sockets is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/admin` | -| `sockets.single.broker.hostPath` | Where the broker socket is on disk when in single socket mode | `/var/run/spire/agent/sockets/main/csi.spiffe.io/broker` | -| `sockets.a.broker.hostPath` | Where the a broker socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/broker` | -| `sockets.b.broker.hostPath` | Where the b broker socket is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/broker` | -| `sockets.single.workload.hostPath` | Where the broker socket is on disk when in single socket mode | `/var/run/spire/agent-sockets` | -| `sockets.a.workload.hostPath` | Where the a workload socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/public` | -| `sockets.b.workload.hostPath` | Where the b workload socket is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/public` | -| `vsock` | Use a vsockets to expose the service rather then a unix socket | `false` | -| `port` | Port number to listen on | `999` | -| `imagePullSecrets` | Pull secrets for images | `[]` | -| `nameOverride` | Name override | `""` | -| `namespaceOverride` | Namespace override | `""` | -| `fullnameOverride` | Fullname override | `""` | -| `serviceAccount.create` | Specifies whether a service account should be created | `true` | -| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | -| `serviceAccount.name` | The name of the service account to use. | `""` | -| `podAnnotations` | Annotations to add to pods | `{}` | -| `podLabels` | Labels to add to pods | `{}` | -| `podSecurityContext` | Pod security context | `{}` | -| `securityContext` | Security context | `{}` | -| `resources` | Resource requests and limits | `{}` | -| `nodeSelector` | Node selector | `{}` | -| `tolerations` | List of tolerations | `[]` | -| `affinity` | Node affinity | `{}` | -| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` | -| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` | -| `fsGroupFix.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `fsGroupFix.image.repository` | The repository within the registry | `chainguard/bash` | -| `fsGroupFix.image.pullPolicy` | The image pull policy | `Always` | -| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ea74a5487d6a76198fb651b48e953a01d13128c68ecf38df3d6e22307f0b93c1` | -| `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | -| `cid2PID.image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `cid2PID.image.repository` | The repository within the registry | `kfox1111/cid2pid` | -| `cid2PID.image.pullPolicy` | The image pull policy | `Always` | -| `cid2PID.image.tag` | Overrides the image tag whose default is the chart appVersion | `v0.0.3` | -| `cid2PID.busybox.image.registry` | The OCI registry to pull the image from | `docker.io` | -| `cid2PID.busybox.image.repository` | The repository within the registry | `library/busybox` | -| `cid2PID.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `cid2PID.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.36.1-uclibc` | -| `cid2PID.busybox.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | -| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | -| `socketAlternate.names` | List of alternate names for the socket that workloads might expect to be able to access in the driver mount. | `["socket","spire-agent.sock","api.sock"]` | -| `socketAlternate.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `socketAlternate.image.repository` | The repository within the registry | `chainguard/bash` | -| `socketAlternate.image.pullPolicy` | The image pull policy | `Always` | -| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ea74a5487d6a76198fb651b48e953a01d13128c68ecf38df3d6e22307f0b93c1` | -| `socketAlternate.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | -| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` | -| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container | `[]` | -| `extraVolumes` | Extra volumes to be mounted on Spire Agent pods | `[]` | -| `extraVolumeMounts` | Extra volume mounts for Spire Agent pods | `[]` | -| `extraContainers` | Additional containers to create with Spire Agent pods | `[]` | -| `initContainers` | Additional init containers to create with Spire Agent pods | `[]` | -| `hostAliases` | Customize /etc/hosts file as described here https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ | `[]` | +| Name | Description | Value | +| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | +| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `image.repository` | The repository within the registry | `spiffe/spire-ha-agent` | +| `image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | +| `mode` | If the spire-ha-agent will run in delegated or broker mode | `delegated` | +| `trustDomain` | The trust domain to be used for the SPIFFE identifiers | `example.org` | +| `singleSocket` | If in singleSocket mode, only one driver is used | `false` | +| `sockets.single.admin.hostPath` | Where the admin socket is on disk when in single socket mode | `/var/run/spire/agent/sockets/main/csi.spiffe.io/admin` | +| `sockets.a.admin.hostPath` | Where the a admin socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/admin` | +| `sockets.b.admin.hostPath` | Where the b admin sockets is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/admin` | +| `sockets.single.broker.hostPath` | Where the broker socket is on disk when in single socket mode | `/var/run/spire/agent/sockets/main/csi.spiffe.io/broker` | +| `sockets.a.broker.hostPath` | Where the a broker socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/broker` | +| `sockets.b.broker.hostPath` | Where the b broker socket is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/broker` | +| `sockets.single.workload.hostPath` | Where the broker socket is on disk when in single socket mode | `/var/run/spire/agent-sockets` | +| `sockets.a.workload.hostPath` | Where the a workload socket is on disk | `/var/run/spire/agent/sockets/a/csi.spiffe.io/public` | +| `sockets.b.workload.hostPath` | Where the b workload socket is on disk | `/var/run/spire/agent/sockets/b/csi.spiffe.io/public` | +| `vsock` | Use a vsockets to expose the service rather then a unix socket | `false` | +| `port` | Port number to listen on | `999` | +| `brokerAPI.enabled` | Serve the SPIFFE Broker API to downstream consumers. Only supported when mode is broker. | `false` | +| `brokerAPI.socket.enabled` | Serve the broker api on a unix socket | `true` | +| `brokerAPI.socket.mountOnHost` | Make the served broker socket visible on the host, so consumers running in other pods on the node can reach it. When false the socket stays in an emptyDir, reachable only from this pod. | `true` | +| `brokerAPI.socket.hostPath` | Where the served broker socket is made available on the host when mountOnHost is true | `/run/spire/agent/sockets/csi.spiffe.io/broker` | +| `brokerAPI.tcp.enabled` | Serve the broker api over tcp | `false` | +| `brokerAPI.tcp.bindAddress` | The tcp address to bind to | `0.0.0.0:8788` | +| `brokerAPI.brokers.spiffefs.enabled` | Enable spiffefs as a broker. This feature is experimental. | `false` | +| `brokerAPI.brokers.spiffefs.idTemplate` | The default id template | `spiffe://{{ .TrustDomain }}/spiffefs` | +| `brokerAPI.brokers.spiffefs.allowedReferenceTypes[0].typeURL` | The type of reference allowed | `type.googleapis.com/spiffe.broker.WorkloadPIDReference` | +| `brokerAPI.brokers.spiffefs.allowedReferenceTypes[0].allowOverTCP` | Allow access over TCP | `false` | +| `upstreamKeepalive.time` | How often to ping an upstream broker to notice a connection that died silently. 0 disables. Do not lower below 5m: a spire-agent that does not configure a keepalive enforcement policy answers more frequent pings with GOAWAY too_many_pings and drops the connection. | `5m` | +| `upstreamKeepalive.timeout` | How long to wait for a keepalive ping response before considering the connection dead | `20s` | +| `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | +| `telemetry.prometheus.port` | Port for prometheus metrics | `9988` | +| `telemetry.prometheus.host` | Host for prometheus metrics | `0.0.0.0` | +| `telemetry.prometheus.podMonitor.enabled` | Enable podMonitor for prometheus | `false` | +| `telemetry.prometheus.podMonitor.namespace` | Override where to install the podMonitor, if not set will use the same namespace as the spire-ha-agent | `""` | +| `telemetry.prometheus.podMonitor.labels` | Pod labels to filter for prometheus monitoring | `{}` | +| `imagePullSecrets` | Pull secrets for images | `[]` | +| `nameOverride` | Name override | `""` | +| `namespaceOverride` | Namespace override | `""` | +| `fullnameOverride` | Fullname override | `""` | +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | +| `serviceAccount.name` | The name of the service account to use. | `""` | +| `podAnnotations` | Annotations to add to pods | `{}` | +| `podLabels` | Labels to add to pods | `{}` | +| `podSecurityContext` | Pod security context | `{}` | +| `securityContext` | Security context | `{}` | +| `resources` | Resource requests and limits | `{}` | +| `nodeSelector` | Node selector | `{}` | +| `tolerations` | List of tolerations | `[]` | +| `affinity` | Node affinity | `{}` | +| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` | +| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` | +| `fsGroupFix.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `fsGroupFix.image.repository` | The repository within the registry | `chainguard/bash` | +| `fsGroupFix.image.pullPolicy` | The image pull policy | `Always` | +| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ea74a5487d6a76198fb651b48e953a01d13128c68ecf38df3d6e22307f0b93c1` | +| `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | +| `cid2PID.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `cid2PID.image.repository` | The repository within the registry | `kfox1111/cid2pid` | +| `cid2PID.image.pullPolicy` | The image pull policy | `Always` | +| `cid2PID.image.tag` | Overrides the image tag whose default is the chart appVersion | `v0.0.3` | +| `cid2PID.busybox.image.registry` | The OCI registry to pull the image from | `docker.io` | +| `cid2PID.busybox.image.repository` | The repository within the registry | `library/busybox` | +| `cid2PID.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `cid2PID.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.36.1-uclibc` | +| `cid2PID.busybox.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | +| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | +| `socketAlternate.names` | List of alternate names for the socket that workloads might expect to be able to access in the driver mount. | `["socket","spire-agent.sock","api.sock"]` | +| `socketAlternate.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `socketAlternate.image.repository` | The repository within the registry | `chainguard/bash` | +| `socketAlternate.image.pullPolicy` | The image pull policy | `Always` | +| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ea74a5487d6a76198fb651b48e953a01d13128c68ecf38df3d6e22307f0b93c1` | +| `socketAlternate.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | +| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` | +| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container | `[]` | +| `extraVolumes` | Extra volumes to be mounted on Spire Agent pods | `[]` | +| `extraVolumeMounts` | Extra volume mounts for Spire Agent pods | `[]` | +| `extraContainers` | Additional containers to create with Spire Agent pods | `[]` | +| `initContainers` | Additional init containers to create with Spire Agent pods | `[]` | +| `hostAliases` | Customize /etc/hosts file as described here https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ | `[]` | diff --git a/charts/spire-ha-agent/templates/_helpers.tpl b/charts/spire-ha-agent/templates/_helpers.tpl index bbe212a..c4c34f9 100644 --- a/charts/spire-ha-agent/templates/_helpers.tpl +++ b/charts/spire-ha-agent/templates/_helpers.tpl @@ -110,6 +110,15 @@ Create the name of the service account to use {{- end }} {{- end }} +{{/* +Whether prometheus metrics are on. +*/}} +{{- define "spire-ha-agent.prometheus-enabled" -}} +{{- if or (dig "telemetry" "prometheus" "enabled" .Values.telemetry.prometheus.enabled .Values.global) (and (dig "spire" "recommendations" "enabled" false .Values.global) (dig "spire" "recommendations" "prometheus" true .Values.global)) }} +{{- printf "true" }} +{{- end }} +{{- end }} + {{- define "spire-ha-agent.socket-path" -}} {{- print .Values.socketPath }} {{- end }} diff --git a/charts/spire-ha-agent/templates/configmap.yaml b/charts/spire-ha-agent/templates/configmap.yaml new file mode 100644 index 0000000..d2b12ca --- /dev/null +++ b/charts/spire-ha-agent/templates/configmap.yaml @@ -0,0 +1,94 @@ +{{- define "spire-ha-agent.check-config-values" -}} +{{- if not (has .Values.mode (list "delegated" "broker")) }} +{{- fail (printf "mode must be one of [delegated, broker], got: %s" .Values.mode) }} +{{- end }} +{{- if .Values.brokerAPI.enabled }} +{{- if ne .Values.mode "broker" }} +{{- fail "brokerAPI.enabled is true but mode is not broker. The served broker api is only available in broker mode." }} +{{- end }} +{{- if and (not .Values.brokerAPI.socket.enabled) (not .Values.brokerAPI.tcp.enabled) }} +{{- fail "brokerAPI.enabled is true but neither brokerAPI.socket.enabled nor brokerAPI.tcp.enabled is set. At least one listener is required." }} +{{- end }} +{{- $enabledBrokers := 0 }} +{{- range $name, $value := .Values.brokerAPI.brokers }} +{{- if or (not (hasKey $value "enabled")) $value.enabled }} +{{- $enabledBrokers = add1 $enabledBrokers }} +{{- end }} +{{- end }} +{{- if eq $enabledBrokers 0 }} +{{- fail "brokerAPI.enabled is true but no entry in brokerAPI.brokers is enabled. Only listed brokers may connect, so at least one is required." }} +{{- end }} +{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set when brokerAPI is enabled, as broker ids are derived from it" (eq (include "spire-lib.trust-domain" .) "example.org")) }} +{{- end }} +{{- end }} + +{{/* +The agent reads this config as YAML, so it is emitted directly rather than +going through spire-lib.reformat-and-yaml2json. That helper exists to hand +spire an HCL-compatible JSON document and to reshape its plugins dict into +lists; neither applies here. +*/}} +{{- define "spire-ha-agent.yaml-config" -}} +{{- $trustDomain := include "spire-lib.trust-domain" . | trim -}} +single: {{ eq .Values.singleSocket true }} +{{- if .Values.vsock }} +vsock: + enabled: true + port: {{ .Values.port }} +{{- else }} +socket: /tmp/spire-ha-agent/public/spire-agent.sock +{{- end }} +upstream_a: + broker_address: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/broker/broker.sock + workload_socket: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/public/spire-agent.sock +{{- if not .Values.singleSocket }} +upstream_b: + broker_address: unix:///var/run/spire/agent/sockets/b/csi.spiffe.io/broker/broker.sock + workload_socket: unix:///var/run/spire/agent/sockets/b/csi.spiffe.io/public/spire-agent.sock +{{- end }} +upstream_keepalive: + time: {{ .Values.upstreamKeepalive.time | quote }} + timeout: {{ .Values.upstreamKeepalive.timeout | quote }} +{{- if include "spire-ha-agent.prometheus-enabled" . }} +metrics: + bind_address: {{ printf "%s:%v" .Values.telemetry.prometheus.host .Values.telemetry.prometheus.port | quote }} +{{- end }} +{{- if .Values.brokerAPI.enabled }} +broker_endpoint: + {{- /* Deliberately not under the workload api socket directory: the agent + rejects a socket_path that shares a directory with it. */}} + {{- if .Values.brokerAPI.socket.enabled }} + socket_path: /tmp/spire-ha-agent/broker/broker.sock + {{- end }} + {{- if .Values.brokerAPI.tcp.enabled }} + bind_address: {{ .Values.brokerAPI.tcp.bindAddress | quote }} + {{- end }} + brokers: + {{- range $name, $value := .Values.brokerAPI.brokers }} + {{- if or (not (hasKey $value "enabled")) $value.enabled }} + - id: {{ tpl $value.idTemplate (dict "TrustDomain" $trustDomain) | quote }} + allowed_reference_types: + {{- range $value.allowedReferenceTypes }} + - type_url: {{ .typeURL | quote }} + allow_over_tcp: {{ eq .allowOverTCP true }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} + +{{- /* Validation runs for every mode: two of its checks exist precisely to + catch a mode that is not broker. */}} +{{- include "spire-ha-agent.check-config-values" . }} +{{- if eq .Values.mode "broker" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "spire-ha-agent.fullname" . | quote }} + namespace: {{ include "spire-ha-agent.namespace" . | quote }} + labels: + {{- include "spire-ha-agent.labels" . | nindent 4 }} +data: + config.yaml: | + {{- include "spire-ha-agent.yaml-config" . | nindent 4 }} +{{- end }} diff --git a/charts/spire-ha-agent/templates/daemonset.yaml b/charts/spire-ha-agent/templates/daemonset.yaml index 46f542f..72e50bd 100644 --- a/charts/spire-ha-agent/templates/daemonset.yaml +++ b/charts/spire-ha-agent/templates/daemonset.yaml @@ -2,6 +2,7 @@ {{- $mainSecurityContext := deepCopy .Values.securityContext }} {{- $socketAlternateNames := index (include "spire-ha-agent.socket-alternate-names" . | fromYaml) "names" }} {{- $socketPath := include "spire-ha-agent.socket-path" . }} +{{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }} apiVersion: apps/v1 kind: DaemonSet metadata: @@ -30,6 +31,12 @@ spec: metadata: annotations: kubectl.kubernetes.io/default-container: spire-ha-agent + {{- if eq .Values.mode "broker" }} + checksum/config: {{ $configSum | quote }} + {{- end }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} labels: {{- include "spire-ha-agent.selectorLabels" . | nindent 8 }} app.kubernetes.io/component: spire-ha-agent @@ -122,53 +129,51 @@ spec: args: - "-mode" - {{ .Values.mode | quote }} + {{- if eq .Values.mode "broker" }} + - "-config" + - "/opt/spire-ha-agent/conf/config.yaml" + {{- end }} securityContext: privileged: true #FIXME read permission to api socket runAsUser: 0 runAsGroup: 0 #{- $mainSecurityContext | toYaml | nindent 12 }} + {{- /* Broker mode is configured entirely by the rendered config + file, so it has nothing to put here unless the user supplied + extraEnvVars. Emitting a bare env: would render env: null. */}} + {{- if or (eq .Values.mode "delegated") (gt (len .Values.extraEnvVars) 0) }} env: + {{- if eq .Values.mode "delegated" }} - name: SPIRE_HA_AGENT_SOCK value: /tmp/spire-ha-agent/public/spire-agent.sock - {{- if .Values.singleSocket }} + {{- if .Values.singleSocket }} - name: SPIRE_HA_AGENT_SINGLE value: enabled - {{- if eq .Values.mode "delegated" }} - name: SPIRE_HA_AGENT_SOCKET value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/admin/admin.sock - {{- else }} - - name: SPIRE_HA_AGENT_BROKER - value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/broker/broker.sock - - name: SPIRE_HA_AGENT_WORKLOAD_SOCKET - value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/public/spire-agent.sock - {{- end }} - {{- else }} - {{- if eq .Values.mode "delegated" }} + {{- else }} - name: SPIRE_HA_AGENT_SOCKET_A value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/admin/admin.sock - name: SPIRE_HA_AGENT_SOCKET_B value: unix:///var/run/spire/agent/sockets/b/csi.spiffe.io/admin/admin.sock - {{- else }} - - name: SPIRE_HA_AGENT_BROKER_A - value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/broker/broker.sock - - name: SPIRE_HA_AGENT_BROKER_B - value: unix:///var/run/spire/agent/sockets/b/csi.spiffe.io/broker/broker.sock - - name: SPIRE_HA_AGENT_WORKLOAD_SOCKET_A - value: unix:///var/run/spire/agent/sockets/a/csi.spiffe.io/public/spire-agent.sock - - name: SPIRE_HA_AGENT_WORKLOAD_SOCKET_B - value: unix:///var/run/spire/agent/sockets/b/csi.spiffe.io/public/spire-agent.sock - {{- end }} - {{- end }} - {{- if .Values.vsock }} + {{- end }} + {{- if .Values.vsock }} - name: SPIRE_HA_AGENT_VSOCK value: enabled - name: SPIRE_HA_AGENT_PORT value: {{ .Values.port | quote }} + {{- end }} {{- end }} {{- with .Values.extraEnvVars }} {{- toYaml . | nindent 12 }} {{- end }} + {{- end }} + {{- if include "spire-ha-agent.prometheus-enabled" . }} + ports: + - containerPort: {{ .Values.telemetry.prometheus.port }} + name: prom + {{- end }} volumeMounts: # - name: spire-ha-agent-persistence # mountPath: /var/lib/spire @@ -201,6 +206,18 @@ spec: mountPath: /var/run/spire/agent/sockets/b/csi.spiffe.io/public {{- end }} {{- end }} + {{- if eq .Values.mode "broker" }} + - name: spire-ha-agent-config + mountPath: /opt/spire-ha-agent/conf + readOnly: true + {{- if .Values.brokerAPI.enabled }} + {{- if .Values.brokerAPI.socket.enabled }} + - name: spire-ha-agent-broker-socket-dir + mountPath: /tmp/spire-ha-agent/broker + readOnly: false + {{- end }} + {{- end }} + {{- end }} - name: dev mountPath: /dev {{- if gt (len .Values.extraVolumeMounts) 0 }} @@ -261,6 +278,22 @@ spec: type: DirectoryOrCreate {{- end }} {{- end }} + {{- if eq .Values.mode "broker" }} + - name: spire-ha-agent-config + configMap: + name: {{ include "spire-ha-agent.fullname" . | quote }} + {{- if and .Values.brokerAPI.enabled .Values.brokerAPI.socket.enabled }} + {{- if .Values.brokerAPI.socket.mountOnHost }} + - name: spire-ha-agent-broker-socket-dir + hostPath: + path: {{ .Values.brokerAPI.socket.hostPath | quote }} + type: DirectoryOrCreate + {{- else }} + - name: spire-ha-agent-broker-socket-dir + emptyDir: {} + {{- end }} + {{- end }} + {{- end }} - name: dev hostPath: path: /dev diff --git a/charts/spire-ha-agent/templates/podmonitor.yaml b/charts/spire-ha-agent/templates/podmonitor.yaml new file mode 100644 index 0000000..fc6b98f --- /dev/null +++ b/charts/spire-ha-agent/templates/podmonitor.yaml @@ -0,0 +1,27 @@ +{{- if (dig "telemetry" "prometheus" "podMonitor" "enabled" .Values.telemetry.prometheus.podMonitor.enabled .Values.global) }} +{{- $namespace := include "spire-ha-agent.podMonitor.namespace" . }} +{{- $podNamespace := ( include "spire-ha-agent.namespace" . ) }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "spire-ha-agent.fullname" . }} + namespace: {{ $namespace | quote }} + labels: + {{- include "spire-ha-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-ha-agent.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: prom + {{- if ne $namespace $podNamespace }} + namespaceSelector: + kubernetes.io/metadata.name: {{ $podNamespace | quote }} + {{- end }} +{{- end }} diff --git a/charts/spire-ha-agent/values.yaml b/charts/spire-ha-agent/values.yaml index 31d3837..a6cef9b 100644 --- a/charts/spire-ha-agent/values.yaml +++ b/charts/spire-ha-agent/values.yaml @@ -20,6 +20,9 @@ image: ## @param mode If the spire-ha-agent will run in delegated or broker mode mode: delegated +## @param trustDomain The trust domain to be used for the SPIFFE identifiers +trustDomain: example.org + ## @param singleSocket If in singleSocket mode, only one driver is used singleSocket: false @@ -61,6 +64,58 @@ vsock: false ## @param port Port number to listen on port: 999 +brokerAPI: + ## @param brokerAPI.enabled Serve the SPIFFE Broker API to downstream consumers. Only supported when mode is broker. + enabled: false + socket: + ## @param brokerAPI.socket.enabled Serve the broker api on a unix socket + enabled: true + ## @param brokerAPI.socket.mountOnHost Make the served broker socket visible on the host, so consumers running in other pods on the node can reach it. When false the socket stays in an emptyDir, reachable only from this pod. + mountOnHost: true + ## @param brokerAPI.socket.hostPath Where the served broker socket is made available on the host when mountOnHost is true + hostPath: /run/spire/agent/sockets/csi.spiffe.io/broker + tcp: + ## @param brokerAPI.tcp.enabled Serve the broker api over tcp + enabled: false + ## @param brokerAPI.tcp.bindAddress The tcp address to bind to + bindAddress: 0.0.0.0:8788 + ## Brokers allowed to use the served broker api, keyed by name. At least one + ## must be enabled when brokerAPI.enabled is true. Add your own alongside + ## these following the same shape. + brokers: + spiffefs: + ## @param brokerAPI.brokers.spiffefs.enabled Enable spiffefs as a broker. This feature is experimental. + enabled: false + ## @param brokerAPI.brokers.spiffefs.idTemplate The default id template + idTemplate: spiffe://{{ .TrustDomain }}/spiffefs + allowedReferenceTypes: + ## @param brokerAPI.brokers.spiffefs.allowedReferenceTypes[0].typeURL The type of reference allowed + ## @param brokerAPI.brokers.spiffefs.allowedReferenceTypes[0].allowOverTCP Allow access over TCP + - typeURL: "type.googleapis.com/spiffe.broker.WorkloadPIDReference" + allowOverTCP: false + +upstreamKeepalive: + ## @param upstreamKeepalive.time How often to ping an upstream broker to notice a connection that died silently. 0 disables. Do not lower below 5m: a spire-agent that does not configure a keepalive enforcement policy answers more frequent pings with GOAWAY too_many_pings and drops the connection. + time: 5m + ## @param upstreamKeepalive.timeout How long to wait for a keepalive ping response before considering the connection dead + timeout: 20s + +telemetry: + prometheus: + ## @param telemetry.prometheus.enabled Flag to enable prometheus monitoring + enabled: false + ## @param telemetry.prometheus.port Port for prometheus metrics + port: 9988 + ## @param telemetry.prometheus.host Host for prometheus metrics + host: "0.0.0.0" + podMonitor: + ## @param telemetry.prometheus.podMonitor.enabled Enable podMonitor for prometheus + enabled: false + ## @param telemetry.prometheus.podMonitor.namespace Override where to install the podMonitor, if not set will use the same namespace as the spire-ha-agent + namespace: "" + ## @param telemetry.prometheus.podMonitor.labels [object] Pod labels to filter for prometheus monitoring + labels: {} + ## @param imagePullSecrets [array] Pull secrets for images imagePullSecrets: [] diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index ddb1f01..cbefa2f 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -25,162 +25,163 @@ A Helm chart to install the SPIRE agent. ### Chart parameters -| Name | Description | Value | -| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `image.repository` | The repository within the registry | `spiffe/spire-agent` | -| `image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | -| `imagePullSecrets` | Pull secrets for images | `[]` | -| `nameOverride` | Name override | `""` | -| `namespaceOverride` | Namespace override | `""` | -| `fullnameOverride` | Fullname override | `""` | -| `serviceAccount.create` | Specifies whether a service account should be created | `true` | -| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | -| `serviceAccount.name` | The name of the service account to use. | `""` | -| `configMap.annotations` | Annotations to add to the SPIRE Agent ConfigMap | `{}` | -| `podAnnotations` | Annotations to add to pods | `{}` | -| `podLabels` | Labels to add to pods | `{}` | -| `podSecurityContext` | Pod security context | `{}` | -| `securityContext` | Security context | `{}` | -| `resources` | Resource requests and limits for the spire-agent container and all its initContainers | `{}` | -| `nodeSelector` | Node selector | `{}` | -| `tolerations` | List of tolerations | `[]` | -| `affinity` | Node affinity | `{}` | -| `authorizedDelegates` | A list of the authorized delegates SPIFFE IDs. See Delegated Identity API for more information. | `[]` | -| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | -| `logFormat` | The log format, valid values are "text" and "json" | `text` | -| `clusterName` | The name of the Kubernetes cluster (`kubeadm init --service-dns-domain`) | `example-cluster` | -| `trustDomain` | The trust domain to be used for the SPIFFE identifiers | `example.org` | -| `trustBundleURL` | If set, obtain trust bundle from url instead of Kubernetes ConfigMap | `""` | -| `trustBundleFormat` | If using trustBundleURL, what format is the url. Choices are "pem" and "spiffe" | `spiffe` | -| `trustBundleHostPath` | If set, obtain trust bundle from a file on the host instead of from the ConfigMap | `""` | -| `bundleConfigMap` | Configmap name for Spire bundle | `spire-bundle` | -| `availabilityTarget` | The minimum amount of time desired to gracefully handle SPIRE Server or Agent downtime. This configurable influences how aggressively X509 SVIDs should be rotated. If set, must be at least 24h. | `""` | -| `rebootstrapMode` | How the agent will behave when seeing an unknown x509 cert from the server. It can be set to never, auto, or always | `always` | -| `rebootstrapDelay` | The agent will rebootstrap after configured amount of time on unknown x509 cert from the server | `10m` | -| `server.address` | Address for Spire server | `""` | -| `server.port` | Port number for Spire server | `443` | -| `server.namespaceOverride` | Override the namespace for Spire server | `""` | -| `server.nameOverride` | Override the name for Spire server. Should only be changed when building your own nested chart to ensure names align. | `""` | -| `healthChecks.port` | override the host port used for health checking | `9982` | -| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` | -| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` | -| `livenessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | -| `livenessProbe.periodSeconds` | Period seconds for probe | `60` | -| `readinessProbe.initialDelaySeconds` | Initial delay seconds for probe | `10` | -| `readinessProbe.periodSeconds` | Period seconds for probe | `30` | -| `fsGroupFix.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `fsGroupFix.image.repository` | The repository within the registry | `chainguard/bash` | -| `fsGroupFix.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:90041f375e30f41aa7e0390075d8a69dc61900771d52fa98d63ee5d03d866a58` | -| `keyManager.memory.enabled` | Enable the memory based Key Manager | `true` | -| `keyManager.disk.enabled` | Enable the disk based Key Manager (must have persistence.type set to hostPath when enabled) | `false` | -| `keyManager.disk.mode` | Where to store the data. Supported options are hostPath and emptyDir | `hostPath` | -| `nodeAttestor.k8sPSAT.enabled` | Enable PSAT k8s Node Attestor | `true` | -| `nodeAttestor.httpChallenge.enabled` | Enable the http challenge Node Attestor | `false` | -| `nodeAttestor.httpChallenge.agentname` | Name of this agent. Useful if you have multiple agents bound to different spire servers on the same host and sharing the same port. | `default` | -| `nodeAttestor.httpChallenge.port` | The port to listen on. If 0, a random value will be used. | `0` | -| `nodeAttestor.httpChallenge.advertisedPort` | The port to tell the server to call back on. Set only if your using an http proxy on the hosts. If 0, will use the port setting. | `0` | -| `nodeAttestor.tpmDirect.enabled` | Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental. | `false` | -| `nodeAttestor.tpmDirect.plugin.image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `nodeAttestor.tpmDirect.plugin.image.repository` | The repository within the registry | `spiffe/spire-tpm-plugin-tpm-attestor-agent` | -| `nodeAttestor.tpmDirect.plugin.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `nodeAttestor.tpmDirect.plugin.image.tag` | Overrides the image tag | `v1.9.0` | -| `nodeAttestor.tpmDirect.plugin.checksum` | The sha256 checksum of the plugin binary | `22f67063f1699330e70cdedc9b923e517688f5ae71085a26bd9b83b3060ee86e` | -| `nodeAttestor.tpmDirect.plugin.path` | The filename in the container of the plugin | `/app/tpm_attestor_agent` | -| `nodeAttestor.tpmDirect.pubHash.enabled` | Display pubhash in logs | `true` | -| `nodeAttestor.tpmDirect.pubHash.image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `nodeAttestor.tpmDirect.pubHash.image.repository` | The repository within the registry | `spiffe/spire-tpm-plugin-get-tpm-pubhash` | -| `nodeAttestor.tpmDirect.pubHash.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `nodeAttestor.tpmDirect.pubHash.image.tag` | Overrides the image tag | `v1.9.0` | -| `nodeAttestor.awsIID.enabled` | Enable the aws_iid Node Attestor | `false` | -| `nodeAttestor.gcpIIT.enabled` | Enable the gcp_iit Node Attestor | `false` | -| `nodeAttestor.x509POP.enabled` | Enable the x509_pop Node Attestor | `false` | -| `nodeAttestor.x509POP.mode` | Which mode to use. Currently only spiffe is supported | `spiffe` | -| `nodeAttestor.x509POP.spiffeEndpointSocket` | Where the socket is to use for mode spiffe | `/var/run/spiffe/socat/unix/k8s-spire-agent/public/api.sock` | -| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | -| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | -| `workloadAttestors.k8s.verification.type` | What kind of verification to do against kubelet. auto will first attempt to use hostCert, and then fall back to apiServerCA. Valid options are [auto, hostCert, apiServerCA, skip] | `skip` | -| `workloadAttestors.k8s.verification.hostCert.basePath` | Path where kubelet places its certificates | `/var/lib/kubelet/pki` | -| `workloadAttestors.k8s.verification.hostCert.fileName` | File name where kubelet places its certificates. If blank, it will be auto detected. | `""` | -| `workloadAttestors.k8s.disableContainerSelectors` | Set to true if using holdApplicationUntilProxyStarts in Istio | `false` | -| `workloadAttestors.k8s.useNewContainerLocator` | If true, enables the new container locator algorithm that has support for cgroups v2. Defaults to true | `true` | -| `workloadAttestors.k8s.verboseContainerLocatorLogs` | If true, enables verbose logging of mountinfo and cgroup information used to locate containers. Defaults to false | `false` | -| `workloadAttestors.k8s.brokerAPI.accessPolicy` | Which access policy to use. Supported values: enforced, permissive | `enforced` | -| `workloadAttestors.k8s.brokerAPI.brokers.spire-ha-agent.enabled` | Enables the broker api | `false` | -| `dynamicRegistration.enabled` | Deploys the sidecar helper for dynamic registration | `false` | -| `dynamicRegistration.image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `dynamicRegistration.image.repository` | The repository within the registry | `spiffe/spire-controller-manager-dynamic-registration/spire-controller-manager-dynamic-registration-agent` | -| `dynamicRegistration.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `dynamicRegistration.image.tag` | Overrides the image tag to be whatever you need it to be. It will always be the flag you set without modifications | `0.1.0` | -| `dynamicRegistration.audience` | The audience to get the k8s psat for | `spire-controller-manager-dynamic-registration` | -| `dynamicRegistration.serverSPIFFEID` | Expected SPIFFE ID of the server. If blank, it will use a sane default. | `""` | -| `dynamicRegistration.address` | Address for Spire server | `""` | -| `dynamicRegistration.nameOverride` | Override the name for Spire server. Should only be changed when building your own nested chart to ensure names align. | `""` | -| `dynamicRegistration.securityContext` | Security context | `{}` | -| `sds.enabled` | Enables Envoy SDS configuration | `false` | -| `sds.defaultSVIDName` | The TLS Certificate resource name to use for the default X509-SVID with Envoy SDS | `default` | -| `sds.defaultBundleName` | The Validation Context resource name to use for the default X.509 bundle with Envoy SDS | `ROOTCA` | -| `sds.defaultAllBundlesName` | The Validation Context resource name to use for all bundles (including federated) with Envoy SDS | `ALL` | -| `sds.disableSPIFFECertValidation` | Disable Envoy SDS custom validation | `false` | -| `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | -| `telemetry.prometheus.port` | Port for prometheus metrics | `9988` | -| `telemetry.prometheus.host` | Host for prometheus metrics | `0.0.0.0` | -| `telemetry.prometheus.podMonitor.enabled` | Enable podMonitor for prometheus | `false` | -| `telemetry.prometheus.podMonitor.namespace` | Override where to install the podMonitor, if not set will use the same namespace as the spire-agent | `""` | -| `telemetry.prometheus.podMonitor.labels` | Pod labels to filter for prometheus monitoring | `{}` | -| `telemetry.datadog.enabled` | Flag to enable datadog monitoring | `false` | -| `telemetry.datadog.address` | The address of the datadog service to send metrics to. The default URL for services are `..svc` | `datadog.kube-system.svc` | -| `telemetry.datadog.port` | The port of the datadog service to send metrics to | `8125` | -| `kubeletConnectByHostname` | (DEPRECATED) Use kubeletAddress.mode instead. If true, connect to kubelet using the nodes hostname. If false, uses localhost. If unset, defaults to true on OpenShift and false otherwise. | `""` | -| `kubeletAddress.mode` | How to connect to kubelet for workload attestation | `auto` | -| `hostNetwork` | Enable hostNetwork for the DaemonSet. If auto or empty, auto-disables when kubeletAddress.mode is hostname/hostip. Set true/false to override. | `""` | -| `dnsPolicy` | DNS policy for the DaemonSet. If empty, uses ClusterFirstWithHostNet when hostNetwork is enabled. See https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | `""` | -| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | -| `socketAlternate.names` | List of alternate names for the socket that workloads might expect to be able to access in the driver mount. | `["socket","spire-agent.sock","api.sock"]` | -| `socketAlternate.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `socketAlternate.image.repository` | The repository within the registry | `chainguard/bash` | -| `socketAlternate.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:90041f375e30f41aa7e0390075d8a69dc61900771d52fa98d63ee5d03d866a58` | -| `hostCert.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `hostCert.image.repository` | The repository within the registry | `chainguard/min-toolkit-debug` | -| `hostCert.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `hostCert.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:9e45e6836c28489a6e57ca1210ec66927e88eca2409e403616a1278e210e86c9` | -| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` | -| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container and init containers | `[]` | -| `extraVolumes` | Extra volumes to be mounted on Spire Agent pods | `[]` | -| `extraVolumeMounts` | Extra volume mounts for Spire Agent pods | `[]` | -| `extraContainers` | Additional containers to create with Spire Agent pods | `[]` | -| `initContainers` | Additional init containers to create with Spire Agent pods | `[]` | -| `hostAliases` | Customize /etc/hosts file as described here https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ | `[]` | -| `customPlugins.keyManager` | Custom plugins of type KeyManager are configured here | `{}` | -| `customPlugins.nodeAttestor` | Custom plugins of type NodeAttestor are configured here | `{}` | -| `customPlugins.svidStore` | Custom plugins of type SVIDStore are configured here | `{}` | -| `customPlugins.workloadAttestor` | Custom plugins of type WorkloadAttestor are configured here | `{}` | -| `experimental.enabled` | Allow configuration of experimental features | `false` | -| `experimental.syncInterval` | Sync interval with SPIRE server with exponential backoff | `5s` | -| `experimental.requirePQKEM` | Require use of a post-quantum-safe key exchange method for TLS handshakes. | `false` | -| `experimental.featureFlags` | List of developer feature flags | `[]` | -| `agents` | Configure multiple agent DaemonSets. Useful when you have different node types and nodeAttestors | `{}` | -| `tools.kubectl.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` | -| `tools.kubectl.image.repository` | The repository within the registry | `kubectl` | -| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | -| `tools.busybox.image.registry` | The OCI registry to pull the image from | `""` | -| `tools.busybox.image.repository` | The repository within the registry | `busybox` | -| `tools.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `tools.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.37.0-uclibc` | -| `sockets.hostBasePath` | Path on which the agent socket is made available when admin.mountOnHost is true | `/run/spire/agent/sockets` | -| `sockets.admin.enabled` | Enable the admin socket. Useful for admin tasks or the Delegated Identity API. | `false` | -| `sockets.admin.mountOnHost` | Enable the admin socket to be visible on the host. | `false` | -| `sockets.broker.enabled` | Enable the broker socket. | `false` | -| `sockets.broker.mountOnHost` | Enable the broker socket to be visible on the host. | `false` | -| `persistence.type` | What type of volume to use for persistence. Valid options emptyDir (reattestable node attestors) or hostPath (nonr-reattestable node attestors) | `emptyDir` | -| `persistence.hostPath` | Which path to use on the host when persistence.type = hostPath | `/var/lib/spire/k8s/agent` | -| `brokerAPI.tcp.enabled` | Enable the broker api endpoint | `false` | -| `brokerAPI.tcp.bindAddress` | The tcp address to bind to | `0.0.0.0:8788` | -| `brokerAPI.brokers.spire-ha-agent.enabled` | Enable the spire-ha-agent | `false` | -| `brokerAPI.brokers.spire-ha-agent.idTemplate` | The default id template | `spiffe://{{ .TrustDomain }}/spire-ha-agent` | -| `brokerAPI.brokers.spire-ha-agent.allowedReferenceTypes[0].typeURL` | The type of reference allowed | `type.googleapis.com/spiffe.broker.WorkloadPIDReference` | -| `brokerAPI.brokers.spire-ha-agent.allowedReferenceTypes[0].allowOverTCP` | Allow access over TCP | `false` | +| Name | Description | Value | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `image.repository` | The repository within the registry | `spiffe/spire-agent` | +| `image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | +| `imagePullSecrets` | Pull secrets for images | `[]` | +| `nameOverride` | Name override | `""` | +| `namespaceOverride` | Namespace override | `""` | +| `fullnameOverride` | Fullname override | `""` | +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | +| `serviceAccount.name` | The name of the service account to use. | `""` | +| `configMap.annotations` | Annotations to add to the SPIRE Agent ConfigMap | `{}` | +| `podAnnotations` | Annotations to add to pods | `{}` | +| `podLabels` | Labels to add to pods | `{}` | +| `podSecurityContext` | Pod security context | `{}` | +| `securityContext` | Security context | `{}` | +| `resources` | Resource requests and limits for the spire-agent container and all its initContainers | `{}` | +| `nodeSelector` | Node selector | `{}` | +| `tolerations` | List of tolerations | `[]` | +| `affinity` | Node affinity | `{}` | +| `authorizedDelegates` | A list of the authorized delegates SPIFFE IDs. See Delegated Identity API for more information. | `[]` | +| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | +| `logFormat` | The log format, valid values are "text" and "json" | `text` | +| `clusterName` | The name of the Kubernetes cluster (`kubeadm init --service-dns-domain`) | `example-cluster` | +| `trustDomain` | The trust domain to be used for the SPIFFE identifiers | `example.org` | +| `trustBundleURL` | If set, obtain trust bundle from url instead of Kubernetes ConfigMap | `""` | +| `trustBundleFormat` | If using trustBundleURL, what format is the url. Choices are "pem" and "spiffe" | `spiffe` | +| `trustBundleHostPath` | If set, obtain trust bundle from a file on the host instead of from the ConfigMap | `""` | +| `bundleConfigMap` | Configmap name for Spire bundle | `spire-bundle` | +| `availabilityTarget` | The minimum amount of time desired to gracefully handle SPIRE Server or Agent downtime. This configurable influences how aggressively X509 SVIDs should be rotated. If set, must be at least 24h. | `""` | +| `rebootstrapMode` | How the agent will behave when seeing an unknown x509 cert from the server. It can be set to never, auto, or always | `always` | +| `rebootstrapDelay` | The agent will rebootstrap after configured amount of time on unknown x509 cert from the server | `10m` | +| `server.address` | Address for Spire server | `""` | +| `server.port` | Port number for Spire server | `443` | +| `server.namespaceOverride` | Override the namespace for Spire server | `""` | +| `server.nameOverride` | Override the name for Spire server. Should only be changed when building your own nested chart to ensure names align. | `""` | +| `healthChecks.port` | override the host port used for health checking | `9982` | +| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` | +| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | +| `livenessProbe.periodSeconds` | Period seconds for probe | `60` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for probe | `10` | +| `readinessProbe.periodSeconds` | Period seconds for probe | `30` | +| `fsGroupFix.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `fsGroupFix.image.repository` | The repository within the registry | `chainguard/bash` | +| `fsGroupFix.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:90041f375e30f41aa7e0390075d8a69dc61900771d52fa98d63ee5d03d866a58` | +| `keyManager.memory.enabled` | Enable the memory based Key Manager | `true` | +| `keyManager.disk.enabled` | Enable the disk based Key Manager (must have persistence.type set to hostPath when enabled) | `false` | +| `keyManager.disk.mode` | Where to store the data. Supported options are hostPath and emptyDir | `hostPath` | +| `nodeAttestor.k8sPSAT.enabled` | Enable PSAT k8s Node Attestor | `true` | +| `nodeAttestor.httpChallenge.enabled` | Enable the http challenge Node Attestor | `false` | +| `nodeAttestor.httpChallenge.agentname` | Name of this agent. Useful if you have multiple agents bound to different spire servers on the same host and sharing the same port. | `default` | +| `nodeAttestor.httpChallenge.port` | The port to listen on. If 0, a random value will be used. | `0` | +| `nodeAttestor.httpChallenge.advertisedPort` | The port to tell the server to call back on. Set only if your using an http proxy on the hosts. If 0, will use the port setting. | `0` | +| `nodeAttestor.tpmDirect.enabled` | Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental. | `false` | +| `nodeAttestor.tpmDirect.plugin.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `nodeAttestor.tpmDirect.plugin.image.repository` | The repository within the registry | `spiffe/spire-tpm-plugin-tpm-attestor-agent` | +| `nodeAttestor.tpmDirect.plugin.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `nodeAttestor.tpmDirect.plugin.image.tag` | Overrides the image tag | `v1.9.0` | +| `nodeAttestor.tpmDirect.plugin.checksum` | The sha256 checksum of the plugin binary | `22f67063f1699330e70cdedc9b923e517688f5ae71085a26bd9b83b3060ee86e` | +| `nodeAttestor.tpmDirect.plugin.path` | The filename in the container of the plugin | `/app/tpm_attestor_agent` | +| `nodeAttestor.tpmDirect.pubHash.enabled` | Display pubhash in logs | `true` | +| `nodeAttestor.tpmDirect.pubHash.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `nodeAttestor.tpmDirect.pubHash.image.repository` | The repository within the registry | `spiffe/spire-tpm-plugin-get-tpm-pubhash` | +| `nodeAttestor.tpmDirect.pubHash.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `nodeAttestor.tpmDirect.pubHash.image.tag` | Overrides the image tag | `v1.9.0` | +| `nodeAttestor.awsIID.enabled` | Enable the aws_iid Node Attestor | `false` | +| `nodeAttestor.gcpIIT.enabled` | Enable the gcp_iit Node Attestor | `false` | +| `nodeAttestor.x509POP.enabled` | Enable the x509_pop Node Attestor | `false` | +| `nodeAttestor.x509POP.mode` | Which mode to use. Currently only spiffe is supported | `spiffe` | +| `nodeAttestor.x509POP.spiffeEndpointSocket` | Where the socket is to use for mode spiffe | `/var/run/spiffe/socat/unix/k8s-spire-agent/public/api.sock` | +| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | +| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | +| `workloadAttestors.k8s.verification.type` | What kind of verification to do against kubelet. auto will first attempt to use hostCert, and then fall back to apiServerCA. Valid options are [auto, hostCert, apiServerCA, skip] | `skip` | +| `workloadAttestors.k8s.verification.hostCert.basePath` | Path where kubelet places its certificates | `/var/lib/kubelet/pki` | +| `workloadAttestors.k8s.verification.hostCert.fileName` | File name where kubelet places its certificates. If blank, it will be auto detected. | `""` | +| `workloadAttestors.k8s.disableContainerSelectors` | Set to true if using holdApplicationUntilProxyStarts in Istio | `false` | +| `workloadAttestors.k8s.useNewContainerLocator` | If true, enables the new container locator algorithm that has support for cgroups v2. Defaults to true | `true` | +| `workloadAttestors.k8s.verboseContainerLocatorLogs` | If true, enables verbose logging of mountinfo and cgroup information used to locate containers. Defaults to false | `false` | +| `workloadAttestors.k8s.brokerAPI.accessPolicy` | Which access policy to use. Supported values: auto, enforced, permissive. auto uses permissive while all broker access is node local, and enforced otherwise. | `auto` | +| `workloadAttestors.k8s.brokerAPI.brokers.spire-ha-agent.enabled` | Enables the broker api | `false` | +| `workloadAttestors.k8s.brokerAPI.brokers.spire-ha-agent.impersonation.clusterWidePodsOnly` | Grant this broker the impersonate-via-spire verb on pods cluster wide. auto grants it when the resolved accessPolicy is enforced. | `auto` | +| `dynamicRegistration.enabled` | Deploys the sidecar helper for dynamic registration | `false` | +| `dynamicRegistration.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `dynamicRegistration.image.repository` | The repository within the registry | `spiffe/spire-controller-manager-dynamic-registration/spire-controller-manager-dynamic-registration-agent` | +| `dynamicRegistration.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `dynamicRegistration.image.tag` | Overrides the image tag to be whatever you need it to be. It will always be the flag you set without modifications | `0.1.0` | +| `dynamicRegistration.audience` | The audience to get the k8s psat for | `spire-controller-manager-dynamic-registration` | +| `dynamicRegistration.serverSPIFFEID` | Expected SPIFFE ID of the server. If blank, it will use a sane default. | `""` | +| `dynamicRegistration.address` | Address for Spire server | `""` | +| `dynamicRegistration.nameOverride` | Override the name for Spire server. Should only be changed when building your own nested chart to ensure names align. | `""` | +| `dynamicRegistration.securityContext` | Security context | `{}` | +| `sds.enabled` | Enables Envoy SDS configuration | `false` | +| `sds.defaultSVIDName` | The TLS Certificate resource name to use for the default X509-SVID with Envoy SDS | `default` | +| `sds.defaultBundleName` | The Validation Context resource name to use for the default X.509 bundle with Envoy SDS | `ROOTCA` | +| `sds.defaultAllBundlesName` | The Validation Context resource name to use for all bundles (including federated) with Envoy SDS | `ALL` | +| `sds.disableSPIFFECertValidation` | Disable Envoy SDS custom validation | `false` | +| `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | +| `telemetry.prometheus.port` | Port for prometheus metrics | `9988` | +| `telemetry.prometheus.host` | Host for prometheus metrics | `0.0.0.0` | +| `telemetry.prometheus.podMonitor.enabled` | Enable podMonitor for prometheus | `false` | +| `telemetry.prometheus.podMonitor.namespace` | Override where to install the podMonitor, if not set will use the same namespace as the spire-agent | `""` | +| `telemetry.prometheus.podMonitor.labels` | Pod labels to filter for prometheus monitoring | `{}` | +| `telemetry.datadog.enabled` | Flag to enable datadog monitoring | `false` | +| `telemetry.datadog.address` | The address of the datadog service to send metrics to. The default URL for services are `..svc` | `datadog.kube-system.svc` | +| `telemetry.datadog.port` | The port of the datadog service to send metrics to | `8125` | +| `kubeletConnectByHostname` | (DEPRECATED) Use kubeletAddress.mode instead. If true, connect to kubelet using the nodes hostname. If false, uses localhost. If unset, defaults to true on OpenShift and false otherwise. | `""` | +| `kubeletAddress.mode` | How to connect to kubelet for workload attestation | `auto` | +| `hostNetwork` | Enable hostNetwork for the DaemonSet. If auto or empty, auto-disables when kubeletAddress.mode is hostname/hostip. Set true/false to override. | `""` | +| `dnsPolicy` | DNS policy for the DaemonSet. If empty, uses ClusterFirstWithHostNet when hostNetwork is enabled. See https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | `""` | +| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | +| `socketAlternate.names` | List of alternate names for the socket that workloads might expect to be able to access in the driver mount. | `["socket","spire-agent.sock","api.sock"]` | +| `socketAlternate.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `socketAlternate.image.repository` | The repository within the registry | `chainguard/bash` | +| `socketAlternate.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:90041f375e30f41aa7e0390075d8a69dc61900771d52fa98d63ee5d03d866a58` | +| `hostCert.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `hostCert.image.repository` | The repository within the registry | `chainguard/min-toolkit-debug` | +| `hostCert.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `hostCert.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:9e45e6836c28489a6e57ca1210ec66927e88eca2409e403616a1278e210e86c9` | +| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` | +| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container and init containers | `[]` | +| `extraVolumes` | Extra volumes to be mounted on Spire Agent pods | `[]` | +| `extraVolumeMounts` | Extra volume mounts for Spire Agent pods | `[]` | +| `extraContainers` | Additional containers to create with Spire Agent pods | `[]` | +| `initContainers` | Additional init containers to create with Spire Agent pods | `[]` | +| `hostAliases` | Customize /etc/hosts file as described here https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/ | `[]` | +| `customPlugins.keyManager` | Custom plugins of type KeyManager are configured here | `{}` | +| `customPlugins.nodeAttestor` | Custom plugins of type NodeAttestor are configured here | `{}` | +| `customPlugins.svidStore` | Custom plugins of type SVIDStore are configured here | `{}` | +| `customPlugins.workloadAttestor` | Custom plugins of type WorkloadAttestor are configured here | `{}` | +| `experimental.enabled` | Allow configuration of experimental features | `false` | +| `experimental.syncInterval` | Sync interval with SPIRE server with exponential backoff | `5s` | +| `experimental.requirePQKEM` | Require use of a post-quantum-safe key exchange method for TLS handshakes. | `false` | +| `experimental.featureFlags` | List of developer feature flags | `[]` | +| `agents` | Configure multiple agent DaemonSets. Useful when you have different node types and nodeAttestors | `{}` | +| `tools.kubectl.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` | +| `tools.kubectl.image.repository` | The repository within the registry | `kubectl` | +| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | +| `tools.busybox.image.registry` | The OCI registry to pull the image from | `""` | +| `tools.busybox.image.repository` | The repository within the registry | `busybox` | +| `tools.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `tools.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.37.0-uclibc` | +| `sockets.hostBasePath` | Path on which the agent socket is made available when admin.mountOnHost is true | `/run/spire/agent/sockets` | +| `sockets.admin.enabled` | Enable the admin socket. Useful for admin tasks or the Delegated Identity API. | `false` | +| `sockets.admin.mountOnHost` | Enable the admin socket to be visible on the host. | `false` | +| `sockets.broker.enabled` | Enable the broker socket. | `false` | +| `sockets.broker.mountOnHost` | Enable the broker socket to be visible on the host. | `false` | +| `persistence.type` | What type of volume to use for persistence. Valid options emptyDir (reattestable node attestors) or hostPath (nonr-reattestable node attestors) | `emptyDir` | +| `persistence.hostPath` | Which path to use on the host when persistence.type = hostPath | `/var/lib/spire/k8s/agent` | +| `brokerAPI.tcp.enabled` | Enable the broker api endpoint | `false` | +| `brokerAPI.tcp.bindAddress` | The tcp address to bind to | `0.0.0.0:8788` | +| `brokerAPI.brokers.spire-ha-agent.enabled` | Enable the spire-ha-agent | `false` | +| `brokerAPI.brokers.spire-ha-agent.idTemplate` | The default id template | `spiffe://{{ .TrustDomain }}/spire-ha-agent` | +| `brokerAPI.brokers.spire-ha-agent.allowedReferenceTypes[0].typeURL` | The type of reference allowed | `type.googleapis.com/spiffe.broker.WorkloadPIDReference` | +| `brokerAPI.brokers.spire-ha-agent.allowedReferenceTypes[0].allowOverTCP` | Allow access over TCP | `false` | diff --git a/charts/spire/charts/spire-agent/templates/_helpers.tpl b/charts/spire/charts/spire-agent/templates/_helpers.tpl index ef4c272..f3b009a 100644 --- a/charts/spire/charts/spire-agent/templates/_helpers.tpl +++ b/charts/spire/charts/spire-agent/templates/_helpers.tpl @@ -199,3 +199,49 @@ Kept for backward compatibility names: {{ $l | toYaml }} {{- end }} + +{{/* +Resolve workloadAttestors.k8s.brokerAPI.accessPolicy to one of the two values +spire itself accepts. "auto" picks permissive only when every enabled broker is +confined to references that cannot name anything off this node, and enforced +otherwise -- including for anything unrecognized, so it fails closed. + +The enforced triggers, in order below: a cluster pod reference scope, which lets +a pod reference fall through to the apiserver; an absent or empty +allowedReferenceTypes, which is the case spire treats as "no policy" and leaves +every reference type open over unix; any reference type other than a pid; and +any type reachable over tcp. The types are looked up with dig rather than index +so a broker missing from brokerAPI.brokers resolves to enforced instead of +erroring. +*/}} +{{- define "spire-agent.broker-access-policy" -}} +{{- $configured := .Values.workloadAttestors.k8s.brokerAPI.accessPolicy | toString }} +{{- if and (ne $configured "auto") (ne $configured "") }} +{{- if not (has $configured (list "enforced" "permissive")) }} +{{- fail (printf "workloadAttestors.k8s.brokerAPI.accessPolicy must be one of [auto, enforced, permissive], got: %s" $configured) }} +{{- end }} +{{- $configured }} +{{- else }} +{{- $policy := "permissive" }} +{{- range $key, $value := .Values.workloadAttestors.k8s.brokerAPI.brokers }} +{{- if or (not (hasKey $value "enabled")) $value.enabled }} +{{- if eq (dig "podReferenceScope" "" $value | toString) "cluster" }} +{{- $policy = "enforced" }} +{{- end }} +{{- $types := dig $key "allowedReferenceTypes" (list) $.Values.brokerAPI.brokers }} +{{- if not $types }} +{{- $policy = "enforced" }} +{{- end }} +{{- range $types }} +{{- if ne (.typeURL | toString) "type.googleapis.com/spiffe.broker.WorkloadPIDReference" }} +{{- $policy = "enforced" }} +{{- end }} +{{- if eq (.allowOverTCP | toString) "true" }} +{{- $policy = "enforced" }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- $policy }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-agent/templates/configmap.yaml b/charts/spire/charts/spire-agent/templates/configmap.yaml index 14cbc7f..2a43f82 100644 --- a/charts/spire/charts/spire-agent/templates/configmap.yaml +++ b/charts/spire/charts/spire-agent/templates/configmap.yaml @@ -217,7 +217,7 @@ plugins: {{- if or .Values.sockets.broker.enabled .Values.brokerAPI.tcp.enabled }} experimental: broker: - access_policy: {{ .Values.workloadAttestors.k8s.brokerAPI.accessPolicy | quote }} + access_policy: {{ include "spire-agent.broker-access-policy" . | quote }} brokers: {{- range $key, $value := .Values.workloadAttestors.k8s.brokerAPI.brokers }} {{- if or (not (hasKey $value "enabled")) $value.enabled }} diff --git a/charts/spire/charts/spire-agent/templates/roles.yaml b/charts/spire/charts/spire-agent/templates/roles.yaml index f4df1ce..39a7cb3 100644 --- a/charts/spire/charts/spire-agent/templates/roles.yaml +++ b/charts/spire/charts/spire-agent/templates/roles.yaml @@ -1,3 +1,5 @@ +{{- $brokerEndpoint := or .Values.sockets.broker.enabled .Values.brokerAPI.tcp.enabled }} +{{- $enforced := and $brokerEndpoint (eq (include "spire-agent.broker-access-policy" .) "enforced") }} # Required cluster role to allow spire-agent to query k8s API server kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 @@ -10,6 +12,14 @@ rules: - nodes - nodes/proxy verbs: ["get"] + {{- if $enforced }} + {{- /* The enforced broker access policy asks the cluster's authorizer whether + a broker may speak for the pod it named, which the agent does by + creating a SubjectAccessReview on its behalf. */}} + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] + {{- end }} --- # Binds above cluster role to spire-agent service account kind: ClusterRoleBinding @@ -24,3 +34,48 @@ roleRef: kind: ClusterRole name: {{ include "spire-agent.fullname" . | quote }} apiGroup: rbac.authorization.k8s.io + +{{- if $enforced }} +{{- $trustDomain := include "spire-lib.trust-domain" . }} +{{- range $key, $value := .Values.workloadAttestors.k8s.brokerAPI.brokers }} +{{- /* Defaulting to false, not auto, is deliberate: a broker someone adds + themselves gets no grant unless they ask for one. */}} +{{- $imp := dig "impersonation" "clusterWidePodsOnly" false $value | toString }} +{{- $grant := ternary $enforced (eq $imp "true") (eq $imp "auto") }} +{{- if and (or (not (hasKey $value "enabled")) $value.enabled) $grant }} +{{- $idTemplate := (index $.Values.brokerAPI.brokers $key).idTemplate }} +{{- if hasKey $value "idTemplate" }} +{{- $idTemplate = $value.idTemplate }} +{{- end }} +{{- $name := printf "%s-broker-impersonation-%s" (include "spire-agent.fullname" $) $key | trunc 63 | trimSuffix "-" }} +--- +# What the SubjectAccessReview above asks about for this broker. The review +# names the broker's SPIFFE ID as the user, so the grant is bound to that name +# rather than to any service account. A pair per broker, because a future grant +# covering more than pods needs rules of its own. +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ $name | quote }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["impersonate-via-spire"] +--- +# Cluster wide: a broker serves whatever pods land on its node, so the set of +# namespaces is not known ahead of time. +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ $name | quote }} +subjects: + - kind: User + name: {{ tpl $idTemplate (dict "TrustDomain" $trustDomain) | quote }} + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ $name | quote }} + apiGroup: rbac.authorization.k8s.io +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-agent/values.yaml b/charts/spire/charts/spire-agent/values.yaml index efa0cd8..f9d852e 100644 --- a/charts/spire/charts/spire-agent/values.yaml +++ b/charts/spire/charts/spire-agent/values.yaml @@ -253,12 +253,15 @@ workloadAttestors: ## @param workloadAttestors.k8s.verboseContainerLocatorLogs If true, enables verbose logging of mountinfo and cgroup information used to locate containers. Defaults to false verboseContainerLocatorLogs: false brokerAPI: - ## @param workloadAttestors.k8s.brokerAPI.accessPolicy Which access policy to use. Supported values: enforced, permissive - accessPolicy: enforced + ## @param workloadAttestors.k8s.brokerAPI.accessPolicy Which access policy to use. Supported values: auto, enforced, permissive. auto uses permissive while all broker access is node local, and enforced otherwise. + accessPolicy: auto brokers: spire-ha-agent: ## @param workloadAttestors.k8s.brokerAPI.brokers.spire-ha-agent.enabled Enables the broker api enabled: false + impersonation: + ## @param workloadAttestors.k8s.brokerAPI.brokers.spire-ha-agent.impersonation.clusterWidePodsOnly Grant this broker the impersonate-via-spire verb on pods cluster wide. auto grants it when the resolved accessPolicy is enforced. + clusterWidePodsOnly: auto # idTemplate: spiffe://{{ .TrustDomain }}/spire-ha-agent # podReferenceScope: agent_node From dc689035c760a0ffeb82920ee4ee85fe4a3cc1dd Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 4 Sep 2026 14:16:50 -0700 Subject: [PATCH 12/12] Bump spire-lib and dependent Helm Chart versions (patch) * c6381219 feat(gateway): expose gatewayAPI.gateway.infrastructure passthrough (#939) Signed-off-by: Kevin Fox --- charts/spiffe-step-ssh/Chart.lock | 6 +++--- charts/spiffe-step-ssh/Chart.yaml | 4 ++-- charts/spire-ha-agent/Chart.lock | 6 +++--- charts/spire-ha-agent/Chart.yaml | 4 ++-- charts/spire-ha-agent/README.md | 2 +- charts/spire-identity-exchange/Chart.lock | 6 +++--- charts/spire-identity-exchange/Chart.yaml | 4 ++-- charts/spire-identity-exchange/README.md | 2 +- charts/spire-lib/Chart.yaml | 2 +- charts/spire-lib/README.md | 2 +- charts/spire-nested/Chart.lock | 12 ++++++------ charts/spire-nested/Chart.yaml | 10 +++++----- charts/spire-nested/README.md | 2 +- charts/spire/Chart.lock | 8 ++++---- charts/spire/Chart.yaml | 6 +++--- charts/spire/README.md | 2 +- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/charts/spiffe-step-ssh/Chart.lock b/charts/spiffe-step-ssh/Chart.lock index f9157ef..4ba9efc 100644 --- a/charts/spiffe-step-ssh/Chart.lock +++ b/charts/spiffe-step-ssh/Chart.lock @@ -1,9 +1,9 @@ dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: step-certificates repository: https://smallstep.github.io/helm-charts/ version: 1.27.4 -digest: sha256:11d3748666d0c9aa04a77a01ed3cde99553aae715bc9f00b311247e6a9c6ee91 -generated: "2026-08-21T14:41:49.31784-07:00" +digest: sha256:9b62d2daefc0199e874a43e80127cc1fd75486121d860bd36a5249978fde04ac +generated: "2026-09-04T14:16:46.86151-07:00" diff --git a/charts/spiffe-step-ssh/Chart.yaml b/charts/spiffe-step-ssh/Chart.yaml index 53db9ff..094a435 100644 --- a/charts/spiffe-step-ssh/Chart.yaml +++ b/charts/spiffe-step-ssh/Chart.yaml @@ -13,7 +13,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.3.1 +version: 0.3.2 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. @@ -30,7 +30,7 @@ maintainers: dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: step-certificates alias: step repository: https://smallstep.github.io/helm-charts/ diff --git a/charts/spire-ha-agent/Chart.lock b/charts/spire-ha-agent/Chart.lock index d286b70..740b383 100644 --- a/charts/spire-ha-agent/Chart.lock +++ b/charts/spire-ha-agent/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 -digest: sha256:fd4f15738349c83d9a1c60a1529ecc5cb8df6ecd9af21176df54f61f40d8973e -generated: "2026-08-21T14:41:50.554693-07:00" + version: 0.3.2 +digest: sha256:1360466b9040d3ec4947a299db81a6c1635f5b87042b73cf95c99c1badc4634f +generated: "2026-09-04T14:16:48.082704-07:00" diff --git a/charts/spire-ha-agent/Chart.yaml b/charts/spire-ha-agent/Chart.yaml index 5ecadea..ca2d398 100644 --- a/charts/spire-ha-agent/Chart.yaml +++ b/charts/spire-ha-agent/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: spire-ha-agent description: A Helm chart to install the SPIRE HA agent. type: application -version: 0.3.1 +version: 0.3.2 appVersion: "0.5.0" keywords: ["spiffe", "spire-ha-agent"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire-ha-agent @@ -20,4 +20,4 @@ maintainers: dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 diff --git a/charts/spire-ha-agent/README.md b/charts/spire-ha-agent/README.md index 2f8d44e..c5aa16c 100644 --- a/charts/spire-ha-agent/README.md +++ b/charts/spire-ha-agent/README.md @@ -1,6 +1,6 @@ # spire-ha-agent -![Version: 0.3.1](https://img.shields.io/badge/Version-0.3.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0](https://img.shields.io/badge/AppVersion-0.5.0-informational?style=flat-square) +![Version: 0.3.2](https://img.shields.io/badge/Version-0.3.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0](https://img.shields.io/badge/AppVersion-0.5.0-informational?style=flat-square) A Helm chart to install the SPIRE HA agent. diff --git a/charts/spire-identity-exchange/Chart.lock b/charts/spire-identity-exchange/Chart.lock index 57de7aa..0083bdf 100644 --- a/charts/spire-identity-exchange/Chart.lock +++ b/charts/spire-identity-exchange/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 -digest: sha256:fd4f15738349c83d9a1c60a1529ecc5cb8df6ecd9af21176df54f61f40d8973e -generated: "2026-08-21T14:41:50.632935-07:00" + version: 0.3.2 +digest: sha256:1360466b9040d3ec4947a299db81a6c1635f5b87042b73cf95c99c1badc4634f +generated: "2026-09-04T14:16:48.149156-07:00" diff --git a/charts/spire-identity-exchange/Chart.yaml b/charts/spire-identity-exchange/Chart.yaml index f7f3566..7452c77 100644 --- a/charts/spire-identity-exchange/Chart.yaml +++ b/charts/spire-identity-exchange/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: spire-identity-exchange description: A Helm chart to install the SPIRE Identity Exchange. type: application -version: 0.2.1 +version: 0.2.2 appVersion: "v0.5.0" keywords: ["spiffe", "spire", "identity exchange"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire-identity-exchange @@ -20,4 +20,4 @@ maintainers: dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 diff --git a/charts/spire-identity-exchange/README.md b/charts/spire-identity-exchange/README.md index ceef406..2d00ee8 100644 --- a/charts/spire-identity-exchange/README.md +++ b/charts/spire-identity-exchange/README.md @@ -1,6 +1,6 @@ # spire-identity-exchange -![Version: 0.2.1](https://img.shields.io/badge/Version-0.2.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.5.0](https://img.shields.io/badge/AppVersion-v0.5.0-informational?style=flat-square) +![Version: 0.2.2](https://img.shields.io/badge/Version-0.2.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v0.5.0](https://img.shields.io/badge/AppVersion-v0.5.0-informational?style=flat-square) A Helm chart to install the SPIRE Identity Exchange. diff --git a/charts/spire-lib/Chart.yaml b/charts/spire-lib/Chart.yaml index d3c02a5..7b76ccf 100644 --- a/charts/spire-lib/Chart.yaml +++ b/charts/spire-lib/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: spire-lib description: A library of helper templates for SPIRE charts. type: library -version: 0.3.1 +version: 0.3.2 appVersion: "0.1.0" keywords: ["spiffe", "spire", "library"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire-lib diff --git a/charts/spire-lib/README.md b/charts/spire-lib/README.md index c15dc7c..b1b1f8d 100644 --- a/charts/spire-lib/README.md +++ b/charts/spire-lib/README.md @@ -7,7 +7,7 @@ A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for gro ```yaml dependencies: - name: spire-lib - version: 0.3.1 + version: 0.3.2 repository: https://spiffe.github.io/helm-charts-hardened/ ``` diff --git a/charts/spire-nested/Chart.lock b/charts/spire-nested/Chart.lock index 25eba26..fdc25a8 100644 --- a/charts/spire-nested/Chart.lock +++ b/charts/spire-nested/Chart.lock @@ -1,7 +1,7 @@ dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: spire-server repository: file://../spire/charts/spire-server version: 0.1.0 @@ -43,7 +43,7 @@ dependencies: version: 0.1.0 - name: spire-ha-agent repository: file://../spire-ha-agent - version: 0.3.1 + version: 0.3.2 - name: spire-server repository: file://../spire/charts/spire-server version: 0.1.0 @@ -58,7 +58,7 @@ dependencies: version: 0.1.0 - name: spire-identity-exchange repository: file://../spire-identity-exchange - version: 0.2.1 + version: 0.2.2 - name: spire-server repository: file://../spire/charts/spire-server version: 0.1.0 @@ -73,6 +73,6 @@ dependencies: version: 0.1.0 - name: spire-identity-exchange repository: file://../spire-identity-exchange - version: 0.2.1 -digest: sha256:bd10aa2236190a29056e5b32300d16883bc01635d2446a32c91ead2639b98f1d -generated: "2026-08-21T14:41:50.936953-07:00" + version: 0.2.2 +digest: sha256:b107601c95dca75c1bc8be08699d8051200fc3e83d12c392c1853936cffe74ce +generated: "2026-09-04T14:16:48.37985-07:00" diff --git a/charts/spire-nested/Chart.yaml b/charts/spire-nested/Chart.yaml index d13590f..51718f8 100644 --- a/charts/spire-nested/Chart.yaml +++ b/charts/spire-nested/Chart.yaml @@ -4,7 +4,7 @@ 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.30.1 +version: 0.30.2 appVersion: "1.15.3" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire @@ -23,7 +23,7 @@ kubeVersion: ">=1.21.0-0" dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: spire-server alias: root-spire-server condition: root-spire-server.enabled @@ -121,7 +121,7 @@ dependencies: - haAgentCommon - name: spire-ha-agent repository: file://../spire-ha-agent - version: 0.3.1 + version: 0.3.2 condition: spire-ha-agent.enabled tags: - haAgentCommon @@ -157,7 +157,7 @@ dependencies: alias: spire-identity-exchange-bottom-turtle-ha-a condition: spire-identity-exchange-bottom-turtle-ha-a.enabled repository: file://../spire-identity-exchange - version: 0.2.1 + version: 0.2.2 tags: - bottomTurtleHAA - name: spire-server @@ -192,7 +192,7 @@ dependencies: alias: spire-identity-exchange-bottom-turtle-ha-b condition: spire-identity-exchange-bottom-turtle-ha-b.enabled repository: file://../spire-identity-exchange - version: 0.2.1 + version: 0.2.2 tags: - bottomTurtleHAB annotations: diff --git a/charts/spire-nested/README.md b/charts/spire-nested/README.md index e49319d..9b072be 100644 --- a/charts/spire-nested/README.md +++ b/charts/spire-nested/README.md @@ -1,6 +1,6 @@ # spire -![Version: 0.30.1](https://img.shields.io/badge/Version-0.30.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.15.3](https://img.shields.io/badge/AppVersion-1.15.3-informational?style=flat-square) +![Version: 0.30.2](https://img.shields.io/badge/Version-0.30.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.15.3](https://img.shields.io/badge/AppVersion-1.15.3-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. diff --git a/charts/spire/Chart.lock b/charts/spire/Chart.lock index 750dc36..351054d 100644 --- a/charts/spire/Chart.lock +++ b/charts/spire/Chart.lock @@ -1,7 +1,7 @@ dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: spire-server repository: file://./charts/spire-server version: 0.1.0 @@ -34,6 +34,6 @@ dependencies: version: 0.1.0 - name: spire-identity-exchange repository: file://../spire-identity-exchange - version: 0.2.1 -digest: sha256:2916c04b61f4813e2e107b84a2168fdf141c67086658e1adbb9501b8425cd6e1 -generated: "2026-08-21T14:41:50.353186-07:00" + version: 0.2.2 +digest: sha256:f2df7c3ec6008984f9987f181764c4773a8d8d2b3786656170f0dc45fd20b9d2 +generated: "2026-09-04T14:16:47.91006-07:00" diff --git a/charts/spire/Chart.yaml b/charts/spire/Chart.yaml index 8ff4174..a3f99a9 100644 --- a/charts/spire/Chart.yaml +++ b/charts/spire/Chart.yaml @@ -4,7 +4,7 @@ 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.30.1 +version: 0.30.2 appVersion: "1.15.3" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire @@ -25,7 +25,7 @@ kubeVersion: ">=1.21.0-0" dependencies: - name: spire-lib repository: file://../spire-lib - version: 0.3.1 + version: 0.3.2 - name: spire-server condition: spire-server.enabled repository: file://./charts/spire-server @@ -71,7 +71,7 @@ dependencies: - name: spire-identity-exchange condition: spire-identity-exchange.enabled repository: file://../spire-identity-exchange - version: 0.2.1 + version: 0.2.2 annotations: org.opencontainers.image.source: https://github.com/spiffe/helm-charts-hardened artifacthub.io/category: security diff --git a/charts/spire/README.md b/charts/spire/README.md index 531abf0..f312899 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -1,6 +1,6 @@ # spire -![Version: 0.30.1](https://img.shields.io/badge/Version-0.30.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.15.3](https://img.shields.io/badge/AppVersion-1.15.3-informational?style=flat-square) +![Version: 0.30.2](https://img.shields.io/badge/Version-0.30.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.15.3](https://img.shields.io/badge/AppVersion-1.15.3-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.