From f5d1376cb6a8f65c1a251beb9458d597402ee2a3 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Sat, 11 Nov 2023 12:28:41 -0800 Subject: [PATCH 01/21] Documentation cleanup (#97) Fix links to the repo after move. Remove references to other versions of images we don't support. Signed-off-by: Kevin Fox --- charts/spire/charts/spiffe-csi-driver/Chart.yaml | 4 ++-- charts/spire/charts/spiffe-csi-driver/README.md | 8 ++------ .../charts/spiffe-oidc-discovery-provider/Chart.yaml | 4 ++-- .../charts/spiffe-oidc-discovery-provider/README.md | 9 ++------- charts/spire/charts/spire-agent/Chart.yaml | 4 ++-- charts/spire/charts/spire-agent/README.md | 9 ++------- charts/spire/charts/spire-server/Chart.yaml | 4 ++-- charts/spire/charts/spire-server/README.md | 12 ++---------- charts/spire/charts/tornjak-frontend/Chart.yaml | 2 +- charts/spire/charts/tornjak-frontend/README.md | 4 +--- 10 files changed, 18 insertions(+), 42 deletions(-) diff --git a/charts/spire/charts/spiffe-csi-driver/Chart.yaml b/charts/spire/charts/spiffe-csi-driver/Chart.yaml index a7d5ab0..0d883d9 100644 --- a/charts/spire/charts/spiffe-csi-driver/Chart.yaml +++ b/charts/spire/charts/spiffe-csi-driver/Chart.yaml @@ -5,9 +5,9 @@ type: application version: 0.1.0 appVersion: "0.2.3" keywords: ["spiffe", "csi-driver"] -home: https://github.com/spiffe/helm-charts/tree/main/charts/spire +home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: - - https://github.com/spiffe/helm-charts/tree/main/charts/spire + - https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png maintainers: - name: marcofranssen diff --git a/charts/spire/charts/spiffe-csi-driver/README.md b/charts/spire/charts/spiffe-csi-driver/README.md index 2b2b115..d33e26b 100644 --- a/charts/spire/charts/spiffe-csi-driver/README.md +++ b/charts/spire/charts/spiffe-csi-driver/README.md @@ -4,11 +4,7 @@ A Helm chart to install the SPIFFE CSI driver. -**Homepage:** - -> [!Note] -> The recommended version is `0.2.3` to support arm64 nodes. If running with any -> prior version to `0.2.3` you have to use a `nodeSelector` to limit to `kubernetes.io/arch: amd64`. +**Homepage:** ## Maintainers @@ -21,7 +17,7 @@ A Helm chart to install the SPIFFE CSI driver. ## Source Code -* +* diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml index d38ddbf..023a1b5 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml @@ -5,9 +5,9 @@ type: application version: 0.1.0 appVersion: "1.8.4" keywords: ["spiffe", "oidc"] -home: https://github.com/spiffe/helm-charts/tree/main/charts/spire +home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: - - https://github.com/spiffe/helm-charts/tree/main/charts/spire + - https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png maintainers: - name: marcofranssen diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md index 38d9e86..0bf3bbb 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md @@ -4,12 +4,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider. -**Homepage:** - -> [!Note] -> Minimum Spire version is `1.5.3`. -> The recommended version is `1.6.0` to support arm64 nodes. If running with any -> prior version to `1.6.0` you have to use a `nodeSelector` to limit to `kubernetes.io/arch: amd64`. +**Homepage:** ## Maintainers @@ -22,7 +17,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider. ## Source Code -* +* diff --git a/charts/spire/charts/spire-agent/Chart.yaml b/charts/spire/charts/spire-agent/Chart.yaml index 514744f..ecf8501 100644 --- a/charts/spire/charts/spire-agent/Chart.yaml +++ b/charts/spire/charts/spire-agent/Chart.yaml @@ -5,9 +5,9 @@ type: application version: 0.1.0 appVersion: "1.8.4" keywords: ["spiffe", "spire-agent"] -home: https://github.com/spiffe/helm-charts/tree/main/charts/spire +home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: - - https://github.com/spiffe/helm-charts/tree/main/charts/spire + - https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png maintainers: - name: marcofranssen diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index 976eca7..d672c80 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -4,12 +4,7 @@ A Helm chart to install the SPIRE agent. -**Homepage:** - -> [!Note] -> Minimum Spire version is `1.5.3`. -> The recommended version is `1.6.0` to support arm64 nodes. If running with any -> prior version to `1.6.0` you have to use a `nodeSelector` to limit to `kubernetes.io/arch: amd64`. +**Homepage:** ## Maintainers @@ -22,7 +17,7 @@ A Helm chart to install the SPIRE agent. ## Source Code -* +* diff --git a/charts/spire/charts/spire-server/Chart.yaml b/charts/spire/charts/spire-server/Chart.yaml index a150171..4460bad 100644 --- a/charts/spire/charts/spire-server/Chart.yaml +++ b/charts/spire/charts/spire-server/Chart.yaml @@ -5,9 +5,9 @@ type: application version: 0.1.0 appVersion: "1.8.4" keywords: ["spiffe", "spire-server", "spire-controller-manager"] -home: https://github.com/spiffe/helm-charts/tree/main/charts/spire +home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: - - https://github.com/spiffe/helm-charts/tree/main/charts/spire + - https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire icon: https://spiffe.io/img/logos/spire/icon/color/spire-icon-color.png maintainers: - name: marcofranssen diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 4bf91ec..355c2a2 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -4,15 +4,7 @@ A Helm chart to install the SPIRE server. -**Homepage:** - -> [!Note] -> Minimum Spire version is `1.5.3`. -> The recommended version is `1.6.0` to support arm64 nodes. If running with any -> prior version to `1.6.0` you have to use a `nodeSelector` to limit to `kubernetes.io/arch: amd64`. -> -> The recommended spire-controller-manager version is `0.2.2` to support arm64 nodes. If running with any -> prior version to `0.2.2` you have to use a `nodeSelector` to limit to `kubernetes.io/arch: amd64`. +**Homepage:** ## Maintainers @@ -25,7 +17,7 @@ A Helm chart to install the SPIRE server. ## Source Code -* +* ## Tornjak diff --git a/charts/spire/charts/tornjak-frontend/Chart.yaml b/charts/spire/charts/tornjak-frontend/Chart.yaml index 38a2e7a..1e72c8e 100644 --- a/charts/spire/charts/tornjak-frontend/Chart.yaml +++ b/charts/spire/charts/tornjak-frontend/Chart.yaml @@ -4,7 +4,7 @@ description: A Helm chart to deploy Tornjak frontend type: application version: 0.1.0 appVersion: "v1.4.0" -home: https://github.com/spiffe/helm-charts/tree/main/charts/spire +home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: - https://github.com/spiffe/tornjak icon: https://raw.githubusercontent.com/spiffe/tornjak/main/logos/logo%2Btornjak.2132x1291.png diff --git a/charts/spire/charts/tornjak-frontend/README.md b/charts/spire/charts/tornjak-frontend/README.md index 38239d4..661e6a8 100644 --- a/charts/spire/charts/tornjak-frontend/README.md +++ b/charts/spire/charts/tornjak-frontend/README.md @@ -5,7 +5,7 @@ A Helm chart to deploy Tornjak frontend -**Homepage:** +**Homepage:** ## Version support @@ -16,8 +16,6 @@ A Helm chart to deploy Tornjak frontend | Dependency | Supported Versions | |:-----------|:-------------------| -| SPIRE | `1.5.3+`, `1.6.x` | -| Tornjak | `1.0.x` | | Helm | `3.x` | ## Tornjak From 91d262536e77c1e361a55f5127b1dc46694f1ea8 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Sat, 11 Nov 2023 15:15:21 -0800 Subject: [PATCH 02/21] Render notes correctly on vscode (#96) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea0704a..776df01 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -> [!Note] +> **Note** > Things to consider: > 1. We do not support running out of the git main branch. This is where development happens. Please use released versions via the published repo or git tags. > 2. All the helm charts in this repo are beta. We encourage you to try them out and contribute. The API may change as we move towards a production ready release. From ef3b1b7649887d489dd7fa5b6bb86965f3230e01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 03:40:34 +0000 Subject: [PATCH 03/21] Bump github.com/onsi/ginkgo/v2 from 2.13.0 to 2.13.1 in /tests Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.13.0 to 2.13.1. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.13.0...v2.13.1) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- tests/go.mod | 8 ++++---- tests/go.sum | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index b6cc037..e3a0560 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -3,7 +3,7 @@ module github.com/spiffe/helm-charts/tests go 1.20 require ( - github.com/onsi/ginkgo/v2 v2.13.0 + github.com/onsi/ginkgo/v2 v2.13.1 github.com/onsi/gomega v1.30.0 helm.sh/helm/v3 v3.13.2 ) @@ -16,7 +16,7 @@ require ( github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -48,11 +48,11 @@ require ( golang.org/x/crypto v0.14.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.12.0 // indirect + golang.org/x/tools v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/tests/go.sum b/tests/go.sum index 693fb29..12e99c6 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -20,8 +20,8 @@ github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKf github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -85,8 +85,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= +github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -132,7 +132,7 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -158,8 +158,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -179,8 +179,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= +golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 889d0af84d937432d7cae5a1df1af16a48b0b688 Mon Sep 17 00:00:00 2001 From: marcofranssen Date: Mon, 13 Nov 2023 08:01:59 +0000 Subject: [PATCH 04/21] Bump test chart dependencies Signed-off-by: GitHub --- .github/tests/charts.json | 6 +++--- charts/spire/charts/spiffe-csi-driver/README.md | 2 +- charts/spire/charts/spiffe-csi-driver/values.yaml | 2 +- .../spire/charts/spiffe-oidc-discovery-provider/README.md | 4 ++-- .../spire/charts/spiffe-oidc-discovery-provider/values.yaml | 4 ++-- charts/spire/charts/spire-agent/README.md | 4 ++-- charts/spire/charts/spire-agent/values.yaml | 4 ++-- charts/spire/charts/spire-server/README.md | 2 +- charts/spire/charts/spire-server/values.yaml | 2 +- charts/spire/charts/tornjak-frontend/README.md | 2 +- charts/spire/charts/tornjak-frontend/values.yaml | 2 +- 11 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/tests/charts.json b/.github/tests/charts.json index 31501de..e0ec8b2 100644 --- a/.github/tests/charts.json +++ b/.github/tests/charts.json @@ -2,7 +2,7 @@ { "name": "kube-prometheus-stack", "repo": "https://prometheus-community.github.io/helm-charts", - "version": "52.1.0" + "version": "53.0.0" }, { "name": "cert-manager", @@ -17,11 +17,11 @@ { "name": "mysql", "repo": "https://charts.bitnami.com/bitnami", - "version": "9.14.1" + "version": "9.14.3" }, { "name": "postgresql", "repo": "https://charts.bitnami.com/bitnami", - "version": "13.2.1" + "version": "13.2.5" } ] diff --git a/charts/spire/charts/spiffe-csi-driver/README.md b/charts/spire/charts/spiffe-csi-driver/README.md index d33e26b..c1371d6 100644 --- a/charts/spire/charts/spiffe-csi-driver/README.md +++ b/charts/spire/charts/spiffe-csi-driver/README.md @@ -56,7 +56,7 @@ A Helm chart to install the SPIFFE CSI driver. | `nodeDriverRegistrar.image.repository` | The repository within the registry | `sig-storage/csi-node-driver-registrar` | | `nodeDriverRegistrar.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `nodeDriverRegistrar.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.0` | +| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.1` | | `nodeDriverRegistrar.resources` | Resource requests and limits for CSI driver pods | `{}` | | `agentSocketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | | `kubeletPath` | Path to kubelet file | `/var/lib/kubelet` | diff --git a/charts/spire/charts/spiffe-csi-driver/values.yaml b/charts/spire/charts/spiffe-csi-driver/values.yaml index aa4e943..12eeb7b 100644 --- a/charts/spire/charts/spiffe-csi-driver/values.yaml +++ b/charts/spire/charts/spiffe-csi-driver/values.yaml @@ -110,7 +110,7 @@ nodeDriverRegistrar: repository: sig-storage/csi-node-driver-registrar pullPolicy: IfNotPresent version: "" - tag: v2.9.0 + tag: v2.9.1 ## @param nodeDriverRegistrar.resources Resource requests and limits for CSI driver pods resources: {} # We usually recommend not to specify default resources and to leave this as a conscious diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md index 0bf3bbb..20c2e67 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md @@ -105,12 +105,12 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | | `tests.toolkit.image.registry` | The OCI registry to pull the image from | `cgr.dev` | | `tests.toolkit.image.repository` | The repository within the registry | `chainguard/slim-toolkit-debug` | | `tests.toolkit.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.toolkit.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d1fc4d296994f28d7e0264c933a12ba75c9a80478ff1eb4b6f692bb91a073a4c` | +| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:4a924b13ecb3ad270ed47687d8ea36d39a9a4fe660bac0db31bd0fee00fbc803` | | `tests.busybox.image.registry` | The OCI registry to pull the image from | `""` | | `tests.busybox.image.repository` | The repository within the registry | `busybox` | | `tests.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml index 9b47296..ffacd4d 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml @@ -289,7 +289,7 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214 + tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 toolkit: ## @param tests.toolkit.image.registry The OCI registry to pull the image from @@ -303,7 +303,7 @@ tests: repository: chainguard/slim-toolkit-debug pullPolicy: IfNotPresent version: "" - tag: latest@sha256:d1fc4d296994f28d7e0264c933a12ba75c9a80478ff1eb4b6f692bb91a073a4c + tag: latest@sha256:4a924b13ecb3ad270ed47687d8ea36d39a9a4fe660bac0db31bd0fee00fbc803 busybox: ## @param tests.busybox.image.registry The OCI registry to pull the image from diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index d672c80..6fb347e 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -64,13 +64,13 @@ A Helm chart to install the SPIRE agent. | `waitForIt.image.repository` | The repository within the registry | `chainguard/wait-for-it` | | `waitForIt.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `waitForIt.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:c58a76f9241187615ab081ec73db6aeea6939369fba995206343bd9fb1975378` | +| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:9118ef59ae1daf6cea53ce1c536d99f58018247c364d06e2abdb845877061c3e` | | `waitForIt.resources` | Resource requests and limits | `{}` | | `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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214` | +| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | | `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | | `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | | `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | diff --git a/charts/spire/charts/spire-agent/values.yaml b/charts/spire/charts/spire-agent/values.yaml index 5b2f44e..b1d666c 100644 --- a/charts/spire/charts/spire-agent/values.yaml +++ b/charts/spire/charts/spire-agent/values.yaml @@ -134,7 +134,7 @@ waitForIt: repository: chainguard/wait-for-it pullPolicy: IfNotPresent version: "" - tag: latest@sha256:c58a76f9241187615ab081ec73db6aeea6939369fba995206343bd9fb1975378 + tag: latest@sha256:9118ef59ae1daf6cea53ce1c536d99f58018247c364d06e2abdb845877061c3e ## @param waitForIt.resources [object] Resource requests and limits resources: {} @@ -153,7 +153,7 @@ fsGroupFix: repository: chainguard/bash pullPolicy: Always version: "" - tag: latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214 + tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 ## @param fsGroupFix.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: {} diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 355c2a2..37d6cb1 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -314,4 +314,4 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 80315fa..cd1ac1d 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -724,4 +724,4 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214 + tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 diff --git a/charts/spire/charts/tornjak-frontend/README.md b/charts/spire/charts/tornjak-frontend/README.md index 661e6a8..89dd958 100644 --- a/charts/spire/charts/tornjak-frontend/README.md +++ b/charts/spire/charts/tornjak-frontend/README.md @@ -100,4 +100,4 @@ port forwarding. See the chart NOTES output for more details. | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | diff --git a/charts/spire/charts/tornjak-frontend/values.yaml b/charts/spire/charts/tornjak-frontend/values.yaml index 7917df4..72f0a2c 100644 --- a/charts/spire/charts/tornjak-frontend/values.yaml +++ b/charts/spire/charts/tornjak-frontend/values.yaml @@ -158,4 +158,4 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:3d077aae77eb552abd85a015d087047a7a7353d974e5f7fc6a402180c1501214 + tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 From 8f542f217073e68d99efebb47d97f1d9a2b03165 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Mon, 13 Nov 2023 14:14:24 -0800 Subject: [PATCH 05/21] Add some nested diagrams (#102) * Add some nested diagrams Signed-off-by: Kevin Fox * Fix typo Signed-off-by: Kevin Fox * Add md Signed-off-by: Kevin Fox * Apply suggestions from code review Co-authored-by: Faisal Memon Signed-off-by: kfox1111 --------- Signed-off-by: Kevin Fox Signed-off-by: kfox1111 Co-authored-by: Faisal Memon --- Makefile | 5 +++ examples/nested/README.md | 10 +++++ examples/nested/multicluster.dot | 61 +++++++++++++++++++++++++++++ examples/nested/multicluster.png | Bin 0 -> 129722 bytes examples/nested/singlehardened.dot | 55 ++++++++++++++++++++++++++ examples/nested/singlehardened.png | Bin 0 -> 110148 bytes 6 files changed, 131 insertions(+) create mode 100644 examples/nested/README.md create mode 100644 examples/nested/multicluster.dot create mode 100644 examples/nested/multicluster.png create mode 100644 examples/nested/singlehardened.dot create mode 100644 examples/nested/singlehardened.png diff --git a/Makefile b/Makefile index c3ad2d6..aff0da0 100644 --- a/Makefile +++ b/Makefile @@ -63,3 +63,8 @@ test-example-%: .PHONY: test-examples test-examples: $(patsubst examples/%/values.yaml,test-example-%,$(wildcard examples/*/values.yaml)) ## Run `helm install` and `helm test` for all the examples containing `run-tests.sh` + +.PHONY: diagrams +diagrams: ## Builds diagrams + @dot -Tpng examples/nested/singlehardened.dot > examples/nested/singlehardened.png + @dot -Tpng examples/nested/multicluster.dot > examples/nested/multicluster.png diff --git a/examples/nested/README.md b/examples/nested/README.md new file mode 100644 index 0000000..2b2986e --- /dev/null +++ b/examples/nested/README.md @@ -0,0 +1,10 @@ +# Possible Nesting Configurations + +There are multiple ways of configuring the chart depending on what you want to use nesting for. + +## Nesting across Kubernetes clusters: +![Multiple Kubernetes Cluster](./multicluster.png) + +## Nesting within a Kubernetes cluster: +![Single Hardened](./singlehardened.png) + diff --git a/examples/nested/multicluster.dot b/examples/nested/multicluster.dot new file mode 100644 index 0000000..fb92833 --- /dev/null +++ b/examples/nested/multicluster.dot @@ -0,0 +1,61 @@ +digraph G { + subgraph cluster_root { + label="Cluster: Root K8S"; + subgraph cluster_root_release { + label="Helm Release: Namespace=spire-root Name=spire" + spireRoot [label="Root Spire Server"]; + } + } + subgraph cluster_nested1 { + label="Cluster: K8S Workload 1"; + subgraph cluster_nested1_release { + label="Helm Release: Namespace=spire-server Name=spire" + subgraph cluster_nested1_ns1 { + label="Namespace: spire-system" + spireUpstreamAgent1 [label="Upstream Spire Agent/CSI"]; + } + subgraph cluster_nested1_ns2 { + label="Namespace: spire-server" + spireServerNested1 [label="Nested Spire Server"]; + } + subgraph cluster_nested1_ns3 { + label="Namespace: spire-system" + spireDownstreamAgent1 [label="Downstream Spire Agent/CSI"]; + } + } + subgraph cluster_nested1_user { + label="Namespace: user" + userWorkload1 [label="User Workload"]; + } + } + subgraph cluster_nested2 { + label="Cluster: K8S Workload 2"; + subgraph cluster_nested2_release { + label="Helm Release: Namespace=spire-server Name=spire" + subgraph cluster_nested2_ns1 { + label="Namespace: spire-system" + spireUpstreamAgent2 [label="Upstream Spire Agent/CSI"]; + } + subgraph cluster_nested2_ns2 { + label="Namespace: spire-server" + spireServerNested2 [label="Nested Spire Server"]; + } + subgraph cluster_nested2_ns3 { + label="Namespace: spire-system" + spireDownstreamAgent2 [label="Downstream Spire Agent/CSI"]; + } + } + subgraph cluster_nested2_user { + label="Namespace: user" + userWorkload2 [label="Other User Workload"]; + } + } + spireRoot -> spireUpstreamAgent1; + spireRoot -> spireUpstreamAgent2; + spireUpstreamAgent1 -> spireServerNested1; + spireServerNested1 -> spireDownstreamAgent1; + spireDownstreamAgent1 -> userWorkload1; + spireUpstreamAgent2 -> spireServerNested2; + spireServerNested2 -> spireDownstreamAgent2; + spireDownstreamAgent2 -> userWorkload2; +} diff --git a/examples/nested/multicluster.png b/examples/nested/multicluster.png new file mode 100644 index 0000000000000000000000000000000000000000..a0ffd8d3d2e7089ce1988a31d967fae3b29864e2 GIT binary patch literal 129722 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 literal 0 HcmV?d00001 diff --git a/examples/nested/singlehardened.dot b/examples/nested/singlehardened.dot new file mode 100644 index 0000000..9f3ac97 --- /dev/null +++ b/examples/nested/singlehardened.dot @@ -0,0 +1,55 @@ +digraph G { + subgraph cluster_baremetal { + label="(Bare Metal|Virtual) Node" + spireDownstreamAgent3 [label="Downstream Spire Agent"]; + userWorkload3 [label="External User Workload"]; + } + subgraph cluster_k8s { + label="Cluster: K8S"; + subgraph cluster_root_release { + label="Helm Release: Namespace=spire-root Name=spire"; + subgraph cluster_ns_root { + label="Namespace: spire-root" + spireRoot [label="Root Spire Server"]; + } + subgraph cluster_ns_1_system { + label="Namespace: spire-system" + spireUpstreamAgent1 [label="Upstream Spire Agent/CSI"]; + } + } + subgraph cluster_nested1_release { + label="Helm Release: Namespace=spire-server Name=spire" + subgraph cluster_ns_nested_server { + label="Namespace: spire-server"; + spireServerNested1 [label="Internal Nested Spire Server"]; + } + subgraph cluster_ns_nested_system { + label="Namespace: spire-system"; + spireDownstreamAgent1 [label="Downstream Spire Agent/CSI"]; + } + } + subgraph cluster_ns_nested_system { + label="Namespace: user"; + userWorkload1 [label="User Workload"]; + } + subgraph cluster_ns_nested2_system { + label="Namespace: user-other"; + userWorkload2 [label="Other User Workload"]; + } + subgraph cluster_nested3_release { + label="Helm Release: Namespace=spire-external Name=spire" + subgraph cluster_ns_nested2_system { + label="Namespace: spire-external"; + spireServerNested2 [label="External Nested Spire Server"]; + } + } + spireRoot -> spireUpstreamAgent1; + spireUpstreamAgent1 -> spireServerNested1; + spireServerNested1 -> spireDownstreamAgent1; + spireDownstreamAgent1 -> userWorkload1; + spireDownstreamAgent1 -> userWorkload2; + spireUpstreamAgent1 -> spireServerNested2; + spireServerNested2 -> spireDownstreamAgent3; + spireDownstreamAgent3 -> userWorkload3; + } +} diff --git a/examples/nested/singlehardened.png b/examples/nested/singlehardened.png new file mode 100644 index 0000000000000000000000000000000000000000..7b161bc9f97a29b5ccad6a3c11a7657139ee4fdc GIT binary patch literal 110148 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፵cydV8TFKR@T%Jw(F1gAw4ER&u)TH?*8RIMGTo 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 Date: Tue, 14 Nov 2023 22:54:17 -0600 Subject: [PATCH 06/21] Ordering of SecurityContextConstraint array items (#105) Signed-off-by: Andrew Block Co-authored-by: Faisal Memon --- .../templates/scc-spire-oidc-discovery-provider.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/scc-spire-oidc-discovery-provider.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/scc-spire-oidc-discovery-provider.yaml index 71c147c..abd9a73 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/templates/scc-spire-oidc-discovery-provider.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/templates/scc-spire-oidc-discovery-provider.yaml @@ -15,13 +15,13 @@ users: - system:serviceaccount:{{ include "spiffe-oidc-discovery-provider.namespace" . }}:{{ include "spiffe-oidc-discovery-provider.serviceAccountName" . }}-pre-delete volumes: - configMap + - csi + - downwardAPI + - emptyDir + - ephemeral - hostPath - projected - secret - - ephemeral - - downwardAPI - - csi - - emptyDir allowHostDirVolumePlugin: true allowHostIPC: true allowHostNetwork: true From 810709533be6efe7b3c409c169961ac1e72fd0e8 Mon Sep 17 00:00:00 2001 From: Mattias Gees Date: Thu, 16 Nov 2023 14:34:56 +0000 Subject: [PATCH 07/21] Fix typo ClusterSPIFFEID for workloadTSelectoremplates (#107) Signed-off-by: Mattias Gees --- .../spire-server/templates/controller-manager-cluster-ids.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml b/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml index 77cca5e..f82e48b 100644 --- a/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml +++ b/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml @@ -25,7 +25,7 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} {{- with .identities.workloadSelectorTemplates }} - workloadTSelectoremplates: + workloadSelectorTemplates: {{- toYaml . | nindent 4 }} {{- end }} {{- with .identities.ttl }} From 911f51b6795a5f8c0b941ebd524bbdde88cadb7f Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 16 Nov 2023 16:14:55 -0500 Subject: [PATCH 08/21] Consolidate all the examples to a common relative path (#109) Signed-off-by: Mariusz Sabath --- examples/external-mysql/README.md | 2 +- examples/external-postgresql/README.md | 2 +- examples/production/README.md | 18 +++++++++--------- examples/tornjak/README.md | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/external-mysql/README.md b/examples/external-mysql/README.md index f9afb3e..8a6864c 100644 --- a/examples/external-mysql/README.md +++ b/examples/external-mysql/README.md @@ -15,7 +15,7 @@ Next, edit values.yaml with your settings. Check it into your git repo if using Then, deploy the chart pointing at your mysql instance like so: ```shell -helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml --set "spire-server.dataStore.sql.password=${DBPW}" +helm upgrade --install --namespace spire-server spire charts/spire -f examples/external-mysql/values.yaml --set "spire-server.dataStore.sql.password=${DBPW}" ``` See the [production example](../production) for production recommendations. diff --git a/examples/external-postgresql/README.md b/examples/external-postgresql/README.md index 21fd1df..d4710fb 100644 --- a/examples/external-postgresql/README.md +++ b/examples/external-postgresql/README.md @@ -15,7 +15,7 @@ Next, edit values.yaml with your settings. Check it into your git repo if using Then, deploy the chart pointing at your postgresql instance like so: ```shell -helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml --set "spire-server.dataStore.sql.password=${DBPW}" +helm upgrade --install --namespace spire-server spire charts/spire -f examples/external-postgresql/values.yaml --set "spire-server.dataStore.sql.password=${DBPW}" ``` diff --git a/examples/production/README.md b/examples/production/README.md index 21119c2..e2c04e3 100644 --- a/examples/production/README.md +++ b/examples/production/README.md @@ -12,27 +12,27 @@ kubectl label namespace "spire-server" pod-security.kubernetes.io/enforce=restri Update the `example-your-values.yaml` file with your values, then: ```shell -helm upgrade --install --namespace spire-server spire ../../charts/spire \ - -f values.yaml -f example-your-values.yaml --render-subchart-notes +helm upgrade --install --namespace spire-server spire charts/spire \ + -f examples/production/values.yaml -f examples/production/example-your-values.yaml --render-subchart-notes ``` If your using ingress-nginx and want to expose the spiffe oidc discovery provider outside the cluster, add the following to the end of the helm upgrade example: ```shell --f values-expose-spiffe-oidc-discovery-provider-ingress-nginx.yaml +-f examples/production/values-expose-spiffe-oidc-discovery-provider-ingress-nginx.yaml ``` If you want to expose your spire-server outside of Kubernetes and are using ingress-nginx, add following values file when running `helm template/install/upgrade`. ```shell --f values-expose-spire-server-ingress-nginx.yaml +-f examples/production/values-expose-spire-server-ingress-nginx.yaml ``` For example: ```shell -helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml -f values-expose-spire-server-ingress-nginx.yaml +helm upgrade --install --namespace spire-server spire charts/spire -f examples/production/values.yaml -f examples/production/values-expose-spire-server-ingress-nginx.yaml ``` If you want to expose your federation endpoint outside of Kubernetes and are using ingress-nginx @@ -42,25 +42,25 @@ you have two options as described here: If you chose profile https_web, use: ```shell --f values-expose-federation-https-web-ingress-nginx.yaml +-f examples/production/values-expose-federation-https-web-ingress-nginx.yaml ``` For example: ```shell -helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml -f values-expose-federation-https-web-ingress-nginx.yaml +helm upgrade --install --namespace spire-server spire charts/spire -f examples/production/values.yaml -f examples/production/values-expose-federation-https-web-ingress-nginx.yaml ``` If you chose profile https_spiffe, use: ```shell --f values-expose-federation-https-spiffe-ingress-nginx.yaml +-f examples/production/values-expose-federation-https-spiffe-ingress-nginx.yaml ``` For example: ```shell -helm upgrade --install --namespace spire-server spire charts/spire -f values.yaml -f values-expose-federation-https-spiffe-ingress-nginx.yaml +helm upgrade --install --namespace spire-server spire charts/spire -f examples/production/values.yaml -f examples/production/values-expose-federation-https-spiffe-ingress-nginx.yaml ``` See [values.yaml](./values.yaml) for more details on the chart configurations to achieve this setup. diff --git a/examples/tornjak/README.md b/examples/tornjak/README.md index f0a5b51..51bdc4d 100644 --- a/examples/tornjak/README.md +++ b/examples/tornjak/README.md @@ -12,11 +12,11 @@ kubectl create namespace "spire-server" kubectl label namespace "spire-server" pod-security.kubernetes.io/enforce=restricted # deploy SPIRE with Tornjak enabled -helm upgrade --install --namespace spire-server \ - --values ../production/values.yaml \ - --values ./values.yaml \ - --render-subchart-notes \ - spire ../../charts/spire +helm upgrade --install --namespace spire-server spire charts/spire \ +--values examples/production/values.yaml \ +--values examples/tornjak/values.yaml \ +--render-subchart-notes + # test the Tornjak deployment helm test spire -n spire-server From c9885de5391b3af230ccc14b7338c33903972b40 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Thu, 16 Nov 2023 18:47:04 -0500 Subject: [PATCH 09/21] Introduce ReadOnlyRootFilesystem for Tornjak frontend (#110) Signed-off-by: Mariusz Sabath --- .../spire/charts/tornjak-frontend/templates/deployment.yaml | 4 ++++ examples/production/values.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/spire/charts/tornjak-frontend/templates/deployment.yaml b/charts/spire/charts/tornjak-frontend/templates/deployment.yaml index a1c4f42..8fbf210 100644 --- a/charts/spire/charts/tornjak-frontend/templates/deployment.yaml +++ b/charts/spire/charts/tornjak-frontend/templates/deployment.yaml @@ -56,6 +56,8 @@ spec: mountPath: {{ .Values.workingDir }}/node_modules/.cache - name: env mountPath: {{ .Values.workingDir }}/build/tmp + - name: logs + mountPath: /opt/app-root/src/.npm/ {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -77,3 +79,5 @@ spec: emptyDir: {} - name: env emptyDir: {} + - name: logs + emptyDir: {} diff --git a/examples/production/values.yaml b/examples/production/values.yaml index bd1aa18..dd6fb4e 100644 --- a/examples/production/values.yaml +++ b/examples/production/values.yaml @@ -124,7 +124,7 @@ tornjak-frontend: securityContext: allowPrivilegeEscalation: false runAsNonRoot: true - readOnlyRootFilesystem: false + readOnlyRootFilesystem: true capabilities: drop: [ALL] seccompProfile: From 966061c6c77fd4dc34d7dd5c8076c1f89dac16a8 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 17 Nov 2023 07:31:14 -0800 Subject: [PATCH 10/21] Auto add default CSIDriver labels on OpenShift Signed-off-by: Kevin Fox --- .../spiffe-csi-driver/templates/spiffe-csi-driver.yaml | 7 ++++++- examples/openshift/openshift-values.yaml | 2 -- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/charts/spire/charts/spiffe-csi-driver/templates/spiffe-csi-driver.yaml b/charts/spire/charts/spiffe-csi-driver/templates/spiffe-csi-driver.yaml index 95d0086..cd17fdd 100644 --- a/charts/spire/charts/spiffe-csi-driver/templates/spiffe-csi-driver.yaml +++ b/charts/spire/charts/spiffe-csi-driver/templates/spiffe-csi-driver.yaml @@ -1,8 +1,13 @@ +{{- $labels := dict }} +{{- if (dig "openshift" false .Values.global) }} +{{- $_ := set $labels "security.openshift.io/csi-ephemeral-volume-profile" "restricted" }} +{{- end }} +{{- $labels = mergeOverwrite $labels .Values.csiDriverLabels }} apiVersion: storage.k8s.io/v1 kind: CSIDriver metadata: name: {{ .Values.pluginName | quote }} - {{- with .Values.csiDriverLabels }} + {{- with $labels }} labels: {{- toYaml . | nindent 4 }} {{- end }} diff --git a/examples/openshift/openshift-values.yaml b/examples/openshift/openshift-values.yaml index 013a636..2763601 100644 --- a/examples/openshift/openshift-values.yaml +++ b/examples/openshift/openshift-values.yaml @@ -58,8 +58,6 @@ tornjak-frontend: fsGroup: null spiffe-csi-driver: - csiDriverLabels: - security.openshift.io/csi-ephemeral-volume-profile: restricted initContainers: - terminationMessagePath: /dev/termination-log name: set-context From 95e1eb7c575d1d264e4b2f639d12b9b7b32af1fc Mon Sep 17 00:00:00 2001 From: marcofranssen Date: Mon, 20 Nov 2023 08:04:41 +0000 Subject: [PATCH 11/21] Bump test chart dependencies Signed-off-by: GitHub Signed-off-by: Marco Franssen --- .github/tests/charts.json | 4 ++-- .../spire/charts/spiffe-oidc-discovery-provider/README.md | 6 +++--- .../spire/charts/spiffe-oidc-discovery-provider/values.yaml | 6 +++--- charts/spire/charts/spire-agent/README.md | 4 ++-- charts/spire/charts/spire-agent/values.yaml | 4 ++-- charts/spire/charts/spire-server/README.md | 2 +- charts/spire/charts/spire-server/values.yaml | 2 +- charts/spire/charts/tornjak-frontend/README.md | 2 +- charts/spire/charts/tornjak-frontend/values.yaml | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/tests/charts.json b/.github/tests/charts.json index e0ec8b2..d286f63 100644 --- a/.github/tests/charts.json +++ b/.github/tests/charts.json @@ -2,7 +2,7 @@ { "name": "kube-prometheus-stack", "repo": "https://prometheus-community.github.io/helm-charts", - "version": "53.0.0" + "version": "54.1.0" }, { "name": "cert-manager", @@ -22,6 +22,6 @@ { "name": "postgresql", "repo": "https://charts.bitnami.com/bitnami", - "version": "13.2.5" + "version": "13.2.11" } ] diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md index 20c2e67..eb55059 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md @@ -53,7 +53,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | `insecureScheme.nginx.image.repository` | The repository within the registry | `nginxinc/nginx-unprivileged` | | `insecureScheme.nginx.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `insecureScheme.nginx.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `insecureScheme.nginx.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.25.2-alpine` | +| `insecureScheme.nginx.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.25.3-alpine` | | `insecureScheme.nginx.resources` | Resource requests and limits | `{}` | | `jwtIssuer` | Path to JWT issuer. Defaults to oidc-discovery.$trustDomain if unset | `""` | | `config.logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | @@ -105,12 +105,12 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | | `tests.toolkit.image.registry` | The OCI registry to pull the image from | `cgr.dev` | | `tests.toolkit.image.repository` | The repository within the registry | `chainguard/slim-toolkit-debug` | | `tests.toolkit.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.toolkit.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:4a924b13ecb3ad270ed47687d8ea36d39a9a4fe660bac0db31bd0fee00fbc803` | +| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:6a31419c2c6d11fd1f3d0c2ebe9923cf887f321e103a46dd1ad63a20712e7f6e` | | `tests.busybox.image.registry` | The OCI registry to pull the image from | `""` | | `tests.busybox.image.repository` | The repository within the registry | `busybox` | | `tests.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml index ffacd4d..e8a32d2 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml @@ -111,7 +111,7 @@ insecureScheme: repository: nginxinc/nginx-unprivileged pullPolicy: IfNotPresent version: "" - tag: 1.25.2-alpine + tag: 1.25.3-alpine ## @param insecureScheme.nginx.resources Resource requests and limits resources: {} # We usually recommend not to specify default resources and to leave this as a conscious @@ -289,7 +289,7 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 + tag: latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e toolkit: ## @param tests.toolkit.image.registry The OCI registry to pull the image from @@ -303,7 +303,7 @@ tests: repository: chainguard/slim-toolkit-debug pullPolicy: IfNotPresent version: "" - tag: latest@sha256:4a924b13ecb3ad270ed47687d8ea36d39a9a4fe660bac0db31bd0fee00fbc803 + tag: latest@sha256:6a31419c2c6d11fd1f3d0c2ebe9923cf887f321e103a46dd1ad63a20712e7f6e busybox: ## @param tests.busybox.image.registry The OCI registry to pull the image from diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index 6fb347e..539356f 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -64,13 +64,13 @@ A Helm chart to install the SPIRE agent. | `waitForIt.image.repository` | The repository within the registry | `chainguard/wait-for-it` | | `waitForIt.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `waitForIt.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:9118ef59ae1daf6cea53ce1c536d99f58018247c364d06e2abdb845877061c3e` | +| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ffab5a8d7b7da2d04f433d0321cc5c34d8aa53bd15dd54eb2e4cd9c0d3d3cf5e` | | `waitForIt.resources` | Resource requests and limits | `{}` | | `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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | +| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | | `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | | `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | | `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | diff --git a/charts/spire/charts/spire-agent/values.yaml b/charts/spire/charts/spire-agent/values.yaml index b1d666c..3da6122 100644 --- a/charts/spire/charts/spire-agent/values.yaml +++ b/charts/spire/charts/spire-agent/values.yaml @@ -134,7 +134,7 @@ waitForIt: repository: chainguard/wait-for-it pullPolicy: IfNotPresent version: "" - tag: latest@sha256:9118ef59ae1daf6cea53ce1c536d99f58018247c364d06e2abdb845877061c3e + tag: latest@sha256:ffab5a8d7b7da2d04f433d0321cc5c34d8aa53bd15dd54eb2e4cd9c0d3d3cf5e ## @param waitForIt.resources [object] Resource requests and limits resources: {} @@ -153,7 +153,7 @@ fsGroupFix: repository: chainguard/bash pullPolicy: Always version: "" - tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 + tag: latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e ## @param fsGroupFix.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ resources: {} diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 37d6cb1..72ad0ac 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -314,4 +314,4 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index cd1ac1d..143cde8 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -724,4 +724,4 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 + tag: latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e diff --git a/charts/spire/charts/tornjak-frontend/README.md b/charts/spire/charts/tornjak-frontend/README.md index 89dd958..fc1ec95 100644 --- a/charts/spire/charts/tornjak-frontend/README.md +++ b/charts/spire/charts/tornjak-frontend/README.md @@ -100,4 +100,4 @@ port forwarding. See the chart NOTES output for more details. | `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` | | `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.bash.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2` | +| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | diff --git a/charts/spire/charts/tornjak-frontend/values.yaml b/charts/spire/charts/tornjak-frontend/values.yaml index 72f0a2c..78a0689 100644 --- a/charts/spire/charts/tornjak-frontend/values.yaml +++ b/charts/spire/charts/tornjak-frontend/values.yaml @@ -158,4 +158,4 @@ tests: repository: chainguard/bash pullPolicy: IfNotPresent version: "" - tag: latest@sha256:60ccbc708bc17803b8253a1c4fdf61e9a68b55e6d0a8ae5735cc276ad4afa2d2 + tag: latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e From d616632810436446ad5ca3b0e26d0f00b796e2b5 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Fri, 24 Nov 2023 09:32:27 -0800 Subject: [PATCH 12/21] Bump spire version to 1.8.5 (#115) --- charts/spire/Chart.yaml | 2 +- charts/spire/README.md | 2 +- charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml | 2 +- charts/spire/charts/spire-agent/Chart.yaml | 2 +- charts/spire/charts/spire-server/Chart.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/charts/spire/Chart.yaml b/charts/spire/Chart.yaml index d016b13..909785e 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.15.1 -appVersion: "1.8.4" +appVersion: "1.8.5" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts/tree/main/charts/spire sources: diff --git a/charts/spire/README.md b/charts/spire/README.md index 659c2f9..2696e6b 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -1,6 +1,6 @@ # spire -![Version: 0.15.1](https://img.shields.io/badge/Version-0.13.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.7.2](https://img.shields.io/badge/AppVersion-1.7.2-informational?style=flat-square) +![Version: 0.15.1](https://img.shields.io/badge/Version-0.15.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.8.5](https://img.shields.io/badge/AppVersion-1.7.2-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/charts/spiffe-oidc-discovery-provider/Chart.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml index 023a1b5..5109dfa 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/Chart.yaml @@ -3,7 +3,7 @@ name: spiffe-oidc-discovery-provider description: A Helm chart to install the SPIFFE OIDC discovery provider. type: application version: 0.1.0 -appVersion: "1.8.4" +appVersion: "1.8.5" keywords: ["spiffe", "oidc"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: diff --git a/charts/spire/charts/spire-agent/Chart.yaml b/charts/spire/charts/spire-agent/Chart.yaml index ecf8501..24c25e3 100644 --- a/charts/spire/charts/spire-agent/Chart.yaml +++ b/charts/spire/charts/spire-agent/Chart.yaml @@ -3,7 +3,7 @@ name: spire-agent description: A Helm chart to install the SPIRE agent. type: application version: 0.1.0 -appVersion: "1.8.4" +appVersion: "1.8.5" keywords: ["spiffe", "spire-agent"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: diff --git a/charts/spire/charts/spire-server/Chart.yaml b/charts/spire/charts/spire-server/Chart.yaml index 4460bad..7d13241 100644 --- a/charts/spire/charts/spire-server/Chart.yaml +++ b/charts/spire/charts/spire-server/Chart.yaml @@ -3,7 +3,7 @@ name: spire-server description: A Helm chart to install the SPIRE server. type: application version: 0.1.0 -appVersion: "1.8.4" +appVersion: "1.8.5" keywords: ["spiffe", "spire-server", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire sources: From e68f6170a68626373cdac073ff63e87f6ba32c17 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 06:20:42 -0800 Subject: [PATCH 13/21] Bump test chart dependencies (#116) Signed-off-by: GitHub Co-authored-by: marcofranssen --- .github/tests/charts.json | 6 +++--- .../spire/charts/spiffe-oidc-discovery-provider/README.md | 2 +- .../spire/charts/spiffe-oidc-discovery-provider/values.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/tests/charts.json b/.github/tests/charts.json index d286f63..79594dd 100644 --- a/.github/tests/charts.json +++ b/.github/tests/charts.json @@ -2,7 +2,7 @@ { "name": "kube-prometheus-stack", "repo": "https://prometheus-community.github.io/helm-charts", - "version": "54.1.0" + "version": "54.2.2" }, { "name": "cert-manager", @@ -17,11 +17,11 @@ { "name": "mysql", "repo": "https://charts.bitnami.com/bitnami", - "version": "9.14.3" + "version": "9.14.4" }, { "name": "postgresql", "repo": "https://charts.bitnami.com/bitnami", - "version": "13.2.11" + "version": "13.2.18" } ] diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md index eb55059..788f694 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/README.md +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/README.md @@ -110,7 +110,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider. | `tests.toolkit.image.repository` | The repository within the registry | `chainguard/slim-toolkit-debug` | | `tests.toolkit.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tests.toolkit.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:6a31419c2c6d11fd1f3d0c2ebe9923cf887f321e103a46dd1ad63a20712e7f6e` | +| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:99cafee4f14fe07a3298fcb7b90d4f0c396cba150b65d937856788b42ad83f79` | | `tests.busybox.image.registry` | The OCI registry to pull the image from | `""` | | `tests.busybox.image.repository` | The repository within the registry | `busybox` | | `tests.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | diff --git a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml index e8a32d2..405f96e 100644 --- a/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml +++ b/charts/spire/charts/spiffe-oidc-discovery-provider/values.yaml @@ -303,7 +303,7 @@ tests: repository: chainguard/slim-toolkit-debug pullPolicy: IfNotPresent version: "" - tag: latest@sha256:6a31419c2c6d11fd1f3d0c2ebe9923cf887f321e103a46dd1ad63a20712e7f6e + tag: latest@sha256:99cafee4f14fe07a3298fcb7b90d4f0c396cba150b65d937856788b42ad83f79 busybox: ## @param tests.busybox.image.registry The OCI registry to pull the image from From d936293d50bcc329e2f9c415f2d8908bd90375e5 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Mon, 27 Nov 2023 23:43:09 -0800 Subject: [PATCH 14/21] Enable agent to kubelet connection to use hostname (#112) Co-authored-by: Marco Franssen --- charts/spire/charts/spire-agent/README.md | 153 +++++++++--------- .../charts/spire-agent/templates/_helpers.tpl | 13 ++ .../spire-agent/templates/daemonset.yaml | 13 +- charts/spire/charts/spire-agent/values.yaml | 3 + examples/openshift/openshift-values.yaml | 6 - 5 files changed, 104 insertions(+), 84 deletions(-) diff --git a/charts/spire/charts/spire-agent/README.md b/charts/spire/charts/spire-agent/README.md index 539356f..a4e9c0b 100644 --- a/charts/spire/charts/spire-agent/README.md +++ b/charts/spire/charts/spire-agent/README.md @@ -25,79 +25,80 @@ 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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `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 | `{}` | -| `podSecurityContext` | Pod security context | `{}` | -| `securityContext` | Security context | `{}` | -| `resources` | Resource requests and limits | `{}` | -| `nodeSelector` | Node selector | `{}` | -| `tolerations` | List of tolerations | `[]` | -| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | -| `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" | `pem` | -| `bundleConfigMap` | Configmap name for Spire bundle | `spire-bundle` | -| `server.address` | Address for Spire server | `""` | -| `server.port` | Port number for Spire server | `8081` | -| `server.namespaceOverride` | Override the namespace for Spire server | `""` | -| `healthChecks.port` | override the host port used for health checking | `9982` | -| `livenessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | -| `livenessProbe.periodSeconds` | Period seconds for probe | `60` | -| `readinessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | -| `readinessProbe.periodSeconds` | Period seconds for probe | `60` | -| `waitForIt.image.registry` | The OCI registry to pull the image from | `cgr.dev` | -| `waitForIt.image.repository` | The repository within the registry | `chainguard/wait-for-it` | -| `waitForIt.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `waitForIt.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ffab5a8d7b7da2d04f433d0321cc5c34d8aa53bd15dd54eb2e4cd9c0d3d3cf5e` | -| `waitForIt.resources` | Resource requests and limits | `{}` | -| `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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | -| `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | -| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | -| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | -| `workloadAttestors.k8s.skipKubeletVerification` | If true, kubelet certificate verification is skipped | `true` | -| `workloadAttestors.k8s.disableContainerSelectors` | Set to true if using holdApplicationUntilProxyStarts in Istio | `false` | -| `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.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 | `{}` | -| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | -| `priorityClassName` | Priority class assigned to daemonset pods | `""` | -| `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/ | `[]` | -| `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.featureFlags` | List of developer feature flags | `[]` | +| 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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `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 | `{}` | +| `podSecurityContext` | Pod security context | `{}` | +| `securityContext` | Security context | `{}` | +| `resources` | Resource requests and limits | `{}` | +| `nodeSelector` | Node selector | `{}` | +| `tolerations` | List of tolerations | `[]` | +| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | +| `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" | `pem` | +| `bundleConfigMap` | Configmap name for Spire bundle | `spire-bundle` | +| `server.address` | Address for Spire server | `""` | +| `server.port` | Port number for Spire server | `8081` | +| `server.namespaceOverride` | Override the namespace for Spire server | `""` | +| `healthChecks.port` | override the host port used for health checking | `9982` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | +| `livenessProbe.periodSeconds` | Period seconds for probe | `60` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` | +| `readinessProbe.periodSeconds` | Period seconds for probe | `60` | +| `waitForIt.image.registry` | The OCI registry to pull the image from | `cgr.dev` | +| `waitForIt.image.repository` | The repository within the registry | `chainguard/wait-for-it` | +| `waitForIt.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `waitForIt.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:ffab5a8d7b7da2d04f433d0321cc5c34d8aa53bd15dd54eb2e4cd9c0d3d3cf5e` | +| `waitForIt.resources` | Resource requests and limits | `{}` | +| `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.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:d8e08cda119684ca08dcfcebdd63cbf3d3ff7c4f8a8effca80b962dddd42438e` | +| `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` | +| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` | +| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` | +| `workloadAttestors.k8s.skipKubeletVerification` | If true, kubelet certificate verification is skipped | `true` | +| `workloadAttestors.k8s.disableContainerSelectors` | Set to true if using holdApplicationUntilProxyStarts in Istio | `false` | +| `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.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 | `{}` | +| `kubeletConnectByHostname` | If true, connect to kubelet using the nodes hostname. If false, uses localhost. If unset, defaults to true on OpenShift and false otherwise. | `""` | +| `socketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` | +| `priorityClassName` | Priority class assigned to daemonset pods | `""` | +| `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/ | `[]` | +| `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.featureFlags` | List of developer feature flags | `[]` | diff --git a/charts/spire/charts/spire-agent/templates/_helpers.tpl b/charts/spire/charts/spire-agent/templates/_helpers.tpl index a28e1db..6964205 100644 --- a/charts/spire/charts/spire-agent/templates/_helpers.tpl +++ b/charts/spire/charts/spire-agent/templates/_helpers.tpl @@ -104,3 +104,16 @@ Create the name of the service account to use {{- print .Values.socketPath }} {{- end }} +{{- define "spire-agent.connect-by-hostname" -}} +{{- if ne .Values.kubeletConnectByHostname "" }} +{{- if eq (.Values.kubeletConnectByHostname | toString) "true" }} +{{- printf "true" }} +{{- else }} +{{- printf "false" }} +{{- end }} +{{- else if (dig "openshift" false .Values.global) }} +{{- printf "true" }} +{{- else }} +{{- printf "false" }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-agent/templates/daemonset.yaml b/charts/spire/charts/spire-agent/templates/daemonset.yaml index 57c3a31..071534a 100644 --- a/charts/spire/charts/spire-agent/templates/daemonset.yaml +++ b/charts/spire/charts/spire-agent/templates/daemonset.yaml @@ -1,4 +1,5 @@ {{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }} +{{- $cbh := eq (include "spire-agent.connect-by-hostname" .) "true" }} apiVersion: apps/v1 kind: DaemonSet metadata: @@ -71,9 +72,17 @@ spec: image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.image "global" .Values.global) }} imagePullPolicy: {{ .Values.image.pullPolicy }} args: ["-config", "/run/spire/config/agent.conf"] - {{- if gt (len .Values.extraEnvVars) 0 }} + {{- if or (gt (len .Values.extraEnvVars) 0) $cbh }} env: - {{- toYaml .Values.extraEnvVars | nindent 12 }} + {{- if $cbh }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- end }} + {{- with .Values.extraEnvVars }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- end }} ports: - containerPort: {{ .Values.healthChecks.port }} diff --git a/charts/spire/charts/spire-agent/values.yaml b/charts/spire/charts/spire-agent/values.yaml index 3da6122..80e3fb4 100644 --- a/charts/spire/charts/spire-agent/values.yaml +++ b/charts/spire/charts/spire-agent/values.yaml @@ -198,6 +198,9 @@ telemetry: ## @param telemetry.prometheus.podMonitor.labels [object] Pod labels to filter for prometheus monitoring labels: {} +## @param kubeletConnectByHostname If true, connect to kubelet using the nodes hostname. If false, uses localhost. If unset, defaults to true on OpenShift and false otherwise. +kubeletConnectByHostname: "" + ## @param socketPath The unix socket path to the spire-agent socketPath: /run/spire/agent-sockets/spire-agent.sock diff --git a/examples/openshift/openshift-values.yaml b/examples/openshift/openshift-values.yaml index 2763601..6f5dad6 100644 --- a/examples/openshift/openshift-values.yaml +++ b/examples/openshift/openshift-values.yaml @@ -27,12 +27,6 @@ spire-agent: runAsUser: null runAsGroup: null fsGroup: null - # Talk from the agent to kubelet based on hostname instead of localhost - extraEnvVars: - - name: MY_NODE_NAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName upstream-spire-agent: podSecurityContext: From e030fa171b7b045b89d4bed901d669ccfa986096 Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Tue, 28 Nov 2023 09:15:23 -0800 Subject: [PATCH 15/21] Allow additional CRs to be managed by the chart (#117) * Add support for the new spire-controller-manager class feature Signed-off-by: Kevin Fox * Fix docs. Swich nested deployment to use controller manager Signed-off-by: Kevin Fox * Incorperate feedback Signed-off-by: Kevin Fox * Test with nightly Signed-off-by: Kevin Fox * Fix global object naming clash Signed-off-by: Kevin Fox * Fix missing dot Signed-off-by: Kevin Fox * Fix naming conflict with cluster ids Signed-off-by: Kevin Fox * Fix scoping issue Signed-off-by: Kevin Fox * Fix typo Signed-off-by: Kevin Fox * Fix webhook name collision Signed-off-by: Kevin Fox * Fix webhook reference and add note to user about className Signed-off-by: Kevin Fox * Upgrade has to work on the old version of the object before rename Signed-off-by: Kevin Fox * Fix formatting Signed-off-by: Kevin Fox * Remove extra junk from job Signed-off-by: Kevin Fox * Easier local runs and wait for crds Signed-off-by: Kevin Fox * Add missing crd upgrade Signed-off-by: Kevin Fox * Update upgrade notes Signed-off-by: Kevin Fox * Update charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml Co-authored-by: Marco Franssen Signed-off-by: kfox1111 * Incorperate feedback Signed-off-by: Kevin Fox * Bump version to the released 0.4.0 Signed-off-by: kfox1111 * Fix docs Signed-off-by: Kevin Fox * Merge in crd changes from upstream Signed-off-by: Kevin Fox * Add auto populate dns Signed-off-by: Kevin Fox * Update charts/spire/README.md Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Add missing ClusterSPIFFEID fields There are a few options in the CRD not available via the chart. Sync them to the chart. Signed-off-by: Kevin Fox * Add another missing one Signed-off-by: Kevin Fox * Fix docs Signed-off-by: Kevin Fox * Allow additional CRs to be managed by the chart Sometimes additional ClusterSPIFFEIDs and the other CRs are needed. Add support for the end user to manage those extra CRs via the chart. Signed-off-by: Kevin Fox * Add validation Signed-off-by: Kevin Fox * Fix docs Signed-off-by: Kevin Fox * Add className to crs Signed-off-by: Kevin Fox * Fix docs Signed-off-by: Kevin Fox * Incorperate feedback Signed-off-by: Kevin Fox * Fix readme formatting Signed-off-by: Kevin Fox * Update charts/spire/README.md Signed-off-by: kfox1111 * Incorperate feedback Signed-off-by: Kevin Fox * Apply suggestions from code review Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Apply suggestions from code review Co-authored-by: Faisal Memon Signed-off-by: kfox1111 * Fix docs Signed-off-by: Kevin Fox * Remove dead code Signed-off-by: Kevin Fox * Fix extra newline Signed-off-by: Kevin Fox * Incorperate feedback Signed-off-by: Kevin Fox --------- Signed-off-by: Kevin Fox Signed-off-by: kfox1111 Co-authored-by: Marco Franssen Co-authored-by: Faisal Memon --- .../spire-root-server-values.yaml | 16 +- charts/spire/README.md | 4 + charts/spire/charts/spire-server/README.md | 374 +++++++++--------- .../controller-manager-cluster-ids.yaml | 60 ++- .../templates/controller-manager-ftd.yaml | 45 +++ .../controller-manager-static-entries.yaml | 63 +++ charts/spire/charts/spire-server/values.yaml | 96 +++-- examples/nested/values.yaml | 4 +- examples/production/run-tests.sh | 2 +- 9 files changed, 420 insertions(+), 244 deletions(-) create mode 100644 charts/spire/charts/spire-server/templates/controller-manager-ftd.yaml create mode 100644 charts/spire/charts/spire-server/templates/controller-manager-static-entries.yaml diff --git a/.github/tests/dependencies/spire-root-server-values.yaml b/.github/tests/dependencies/spire-root-server-values.yaml index 400a10c..124c8dd 100644 --- a/.github/tests/dependencies/spire-root-server-values.yaml +++ b/.github/tests/dependencies/spire-root-server-values.yaml @@ -6,13 +6,15 @@ global: spire-server: controllerManager: identities: - namespaceSelector: - kubernetes.io/metadata.name: spire-server - podSelector: - app.kubernetes.io/component: server - app.kubernetes.io/instance: spire - app.kubernetes.io/name: server - downstream: true + clusterSPIFFEIDs: + default: + namespaceSelector: + kubernetes.io/metadata.name: spire-server + podSelector: + app.kubernetes.io/component: server + app.kubernetes.io/instance: spire + app.kubernetes.io/name: server + downstream: true nodeAttestor: k8sPsat: serviceAccountAllowList: diff --git a/charts/spire/README.md b/charts/spire/README.md index 2696e6b..dba1641 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -32,6 +32,10 @@ For production installs, please see [the production example](https://github.com/ ## Upgrade notes +### 0.16.X + +The settings under "spire-server.controllerManager.identities" have all been moved under "spire-server.controllerManager.identities.clusterSPIFFEIDs.default". If you have changed any from the defaults, please update them to the new location during upgrade. + ### 0.15.X The spire-crds chart has been updated. Please ensure you have upgraded spire-crds before upgrading the spire chart. diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index 72ad0ac..0c21989 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -79,192 +79,194 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr ### Chart parameters -| Name | Description | Value | -| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | -| `replicaCount` | SPIRE server currently runs with a sqlite database. Scaling to multiple instances will not work until we use an external database. | `1` | -| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `image.repository` | The repository within the registry | `spiffe/spire-server` | -| `image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `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. If not set and create is true, a name is generated. | `""` | -| `podAnnotations` | Annotations to add to pods | `{}` | -| `podSecurityContext` | Pod security context | `{}` | -| `securityContext` | Security context | `{}` | -| `priorityClassName` | Priority class assigned to statefulset pods | `""` | -| `service.type` | Type of the Spire server service created | `ClusterIP` | -| `service.port` | Port for the created service | `8081` | -| `service.annotations` | Annotations to add to the service object | `{}` | -| `configMap.annotations` | Annotations to add to the SPIRE Server ConfigMap | `{}` | -| `resources` | Resource requests and limits | `{}` | -| `autoscaling.enabled` | Flag to enable autoscaling | `false` | -| `autoscaling.minReplicas` | Minimum replicas for autoscaling | `1` | -| `autoscaling.maxReplicas` | Maximum replicas for autoscaling | `100` | -| `autoscaling.targetCPUUtilizationPercentage` | Target CPU utlization that triggers autoscaling | `80` | -| `nodeSelector` | Select specific nodes to run on (currently only amd64 is supported by Tornjak) | `{}` | -| `tolerations` | List of tolerations | `[]` | -| `affinity` | List of node affinities | `{}` | -| `topologySpreadConstraints` | Topology spread constraints for resilience | `[]` | -| `livenessProbe.failureThreshold` | Failure threshold count for livenessProbe | `2` | -| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `15` | -| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `60` | -| `livenessProbe.timeoutSeconds` | Timeout in seconds for livenessProbe | `3` | -| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | -| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` | -| `persistence.type` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `pvc` | -| `persistence.size` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `1Gi` | -| `persistence.accessMode` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `ReadWriteOnce` | -| `persistence.storageClass` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `nil` | -| `persistence.hostPath` | Which path to use on the host when type = hostPath | `""` | -| `dataStore.sql.databaseType` | Other supported databases are "postgres" and "mysql" | `sqlite3` | -| `dataStore.sql.databaseName` | Only used by "postgres" or "mysql" | `spire` | -| `dataStore.sql.host` | Only used by "postgres" or "mysql" | `""` | -| `dataStore.sql.port` | If 0 (default), it will auto set to 5432 for postgres and 3306 for mysql. Only used by those databases. | `0` | -| `dataStore.sql.username` | Only used by "postgres" or "mysql" | `spire` | -| `dataStore.sql.password` | Only used by "postgres" or "mysql" | `""` | -| `dataStore.sql.options` | Only used by "postgres" or "mysql" | `[]` | -| `dataStore.sql.plugin_data` | Settings from https://github.com/spiffe/spire/blob/main/doc/plugin_server_datastore_sql.md go in this section | `{}` | -| `dataStore.sql.externalSecret.enabled` | Enable external secret for datastore creds | `false` | -| `dataStore.sql.externalSecret.name` | The name of the secret object | `""` | -| `dataStore.sql.externalSecret.key` | The key of the secret object whose value is the dataStore.sql password | `""` | -| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | -| `jwtIssuer` | The JWT issuer domain. Defaults to oidc-discovery.$trustDomain if unset | `""` | -| `clusterName` | Set the name of the Kubernetes cluster. (`kubeadm init --service-dns-domain`) | `example-cluster` | -| `trustDomain` | Set the trust domain to be used for the SPIFFE identifiers | `example.org` | -| `bundleConfigMap` | Set the trust domain to be used for the SPIFFE identifiers | `spire-bundle` | -| `clusterDomain` | This is the value of your clusters `kubeadm init --service-dns-domain` flag | `cluster.local` | -| `federation.enabled` | Flag to enable federation | `false` | -| `federation.bundleEndpoint.port` | Port value for trust bundle federation | `8443` | -| `federation.bundleEndpoint.address` | Address for trust bundle federation | `0.0.0.0` | -| `federation.ingress.enabled` | Flag to enable ingress for federation | `false` | -| `federation.ingress.className` | Ingress class name for federation | `""` | -| `federation.ingress.controllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` | -| `federation.ingress.annotations` | Annotations for the ingress object | `{}` | -| `federation.ingress.host` | Host name for the ingress. If no '.' in host, trustDomain is automatically appended. The rest of the rules will be autogenerated. For more customizability, use hosts[] instead. | `spire-server-federation` | -| `federation.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` | -| `federation.ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` | -| `federation.ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` | -| `ca_subject.country` | Country for Spire server CA | `ARPA` | -| `ca_subject.organization` | Organization for Spire server CA | `Example` | -| `ca_subject.common_name` | Common Name for Spire server CA | `example.org` | -| `keyManager.disk.enabled` | Flag to enable keyManager on disk | `true` | -| `keyManager.memory.enabled` | Flag to enable keyManager in memory | `false` | -| `keyManager.awsKMS.enabled` | Flag to enable keyManager in memory | `false` | -| `keyManager.awsKMS.region` | Specify the region for AWS KMS | `""` | -| `keyManager.awsKMS.keyPolicy` | Policy to use when creating keys. If no policy is specified, a default policy will be used. | | -| `keyManager.awsKMS.keyPolicy.policy` | Key policy in JSON format. | `""` | -| `keyManager.awsKMS.keyPolicy.existingConfigMap` | Name of a ConfigMap that has a `policy.json` file with the key policy in JSON format. | `""` | -| `keyManager.awsKMS.accessKeyID` | Access key ID for the AWS account. It's recommended to use an IAM role instead. See [here](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) to learn how to annotate your SPIRE Server Service Account to assume an IAM role. | `""` | -| `keyManager.awsKMS.secretAccessKey` | Secret access key for the AWS account. | `""` | -| `upstreamAuthority.disk.enabled` | Flag to enable upstream authority plugin on disk | `false` | -| `upstreamAuthority.disk.secret.create` | If disabled requires you to create a secret with the given keys (certificate, key and optional bundle) yourself. | `true` | -| `upstreamAuthority.disk.secret.name` | If secret creation is disabled, the secret with this name will be used. | `spiffe-upstream-ca` | -| `upstreamAuthority.disk.secret.data` | If secret creation is enabled, will create a secret with following certificate info | | -| `upstreamAuthority.disk.secret.data.certificate` | Certificate to store within disk upstreamAuthority. | `""` | -| `upstreamAuthority.disk.secret.data.key` | Key corresponding to the upstreamAuthority. | `""` | -| `upstreamAuthority.disk.secret.data.bundle` | Trust bundle for upstreamAuthority. | `""` | -| `upstreamAuthority.awsPCA.enabled` | Flag to enable upstream authority plugin with AWS PCA | `false` | -| `upstreamAuthority.awsPCA.region` | AWS Region to use | `""` | -| `upstreamAuthority.awsPCA.certificateAuthorityARN` | ARN of the "upstream" CA certificate | `""` | -| `upstreamAuthority.awsPCA.assumeRoleARN` | (Optional) ARN of an IAM role to assume | `""` | -| `upstreamAuthority.awsPCA.caSigningTemplateARN` | (Optional) ARN of the signing template to use for the server's CA. Defaults to a signing template for end-entity certificates only. See Using Templates (https://docs.aws.amazon.com/acm-pca/latest/userguide/UsingTemplates.html) for possible values. | `""` | -| `upstreamAuthority.awsPCA.signingAlgorithm` | (Optional) Signing algorithm to use for the server's CA. Defaults to the CA's default. See Issue Certificate (https://docs.aws.amazon.com/cli/latest/reference/acm-pca/issue-certificate.html) for possible values. | `""` | -| `upstreamAuthority.awsPCA.endpoint` | (Optional) Endpoint as hostname or fully-qualified URI that overrides the default endpoint. See AWS SDK Config docs (https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config) for more information. | `""` | -| `upstreamAuthority.awsPCA.supplementalBundlePath` | (Optional) Path to a file containing PEM-encoded CA certificates that should be additionally included in the bundle. | `""` | -| `upstreamAuthority.certManager.enabled` | Flag to enable upstream authority plugin with cert manager | `false` | -| `upstreamAuthority.certManager.rbac.create` | Flag to create RBAC roles | `true` | -| `upstreamAuthority.certManager.issuer_name` | Defaults to the release name, override if CA is provided outside of the chart | `""` | -| `upstreamAuthority.certManager.issuer_kind` | Defaults to "Issuer", override if CA is provided outside of the chart | `Issuer` | -| `upstreamAuthority.certManager.issuer_group` | Defaults to "cert-manager.io", override if CA is provided outside of the chart | `cert-manager.io` | -| `upstreamAuthority.certManager.namespace` | Specify to use a namespace other then the one the chart is installed into | `""` | -| `upstreamAuthority.certManager.kube_config_file` | Path to kube_config_file on node to setup cert manager | `""` | -| `upstreamAuthority.certManager.ca.create` | Creates a Cert-Manager CA | `false` | -| `upstreamAuthority.certManager.ca.duration` | Duration of the CA. Defaults to 10 years | `87600h` | -| `upstreamAuthority.certManager.ca.privateKey.algorithm` | Algorithm to generate private key for CA | `ECDSA` | -| `upstreamAuthority.certManager.ca.privateKey.size` | Size of generated private key for CA | `256` | -| `upstreamAuthority.certManager.ca.privateKey.rotationPolicy` | Rotation policy for generated private key | `""` | -| `upstreamAuthority.certManager.ca.renewBefore` | How long to wait before renewing the CA | `""` | -| `upstreamAuthority.spire.enabled` | Flag to use another Spire install as upstream CA | `false` | -| `upstreamAuthority.spire.upstreamDriver` | Driver for Spire as upstream CA | `""` | -| `upstreamAuthority.spire.server` | Server details for the Spire instance use as upstream CA | | -| `upstreamAuthority.spire.server.address` | Address for upstream Spire server | `""` | -| `upstreamAuthority.spire.server.port` | Port for upstream Spire server | `8081` | -| `upstreamAuthority.vault.enabled` | Enable Hashicorp Vault as upstream CA | `false` | -| `upstreamAuthority.vault.vaultAddr` | The URL of the Vault server. (e.g., https://vault.example.com:8443/) | `""` | -| `upstreamAuthority.vault.namespace` | Name of the Vault namespace. This is only available in the Vault Enterprise. | `""` | -| `upstreamAuthority.vault.pkiMountPoint` | Name of the mount point where PKI secret engine is mounted | `pki` | -| `upstreamAuthority.vault.insecureSkipVerify` | If true, caCert options are ignored and Spire accepts any server certificates claiming to be Vault | `false` | -| `upstreamAuthority.vault.caCert.type` | Type of resource representing the Vault server certificate, options are 'Secret' or 'Configmap', the item must be named `ca.crt` | `Secret` | -| `upstreamAuthority.vault.caCert.name` | Name of the Kubernetes resource containing the Vault server certificate | `vault-ca` | -| `upstreamAuthority.vault.k8sAuth.enabled` | Enable k8s authentication to Hashicorp Vault | `false` | -| `upstreamAuthority.vault.k8sAuth.k8sAuthMountPoint` | Name of the mount point where the Kubernetes auth method is mounted | `kubernetes` | -| `upstreamAuthority.vault.k8sAuth.k8sAuthRoleName` | Required - Name of the Vault role. The plugin authenticates against the named role | `""` | -| `upstreamAuthority.vault.k8sAuth.token.audience` | Intended audience of the PSAT, it must match one of the audiences supported by the Kubernetes API server. If no audience is specified, it defaults to the identifier of API Server. See ['Service Account Documentation'](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection) for more info. | `vault` | -| `upstreamAuthority.vault.k8sAuth.token.expiry` | Expiry time in seconds for the token | `7200` | -| `notifier.k8sbundle.namespace` | Namespace to push the bundle into, if blank will default to SPIRE Server namespace | `""` | -| `controllerManager.enabled` | Flag to enable controller manager | `false` | -| `controllerManager.className` | specify to use an explicit class name. If empty, it will be automatically set to Release.Namespace-Release.Name to not conflict with other installs, enabling parallel installs. | `""` | -| `controllerManager.watchClassless` | specify to process custom resources without class name specified. Useful to slowly migrate to class names from classless installs. Do not have two installs on the same k8s cluster both set to true. | `false` | -| `controllerManager.installAndUpgradeHook.enabled` | Enable Helm hook to autofix common install/upgrade issues (should be disabled when using `helm template`) | `true` | -| `controllerManager.deleteHook.enabled` | Enable Helm hook to autofix common delete issues (should be disabled when using `helm template`) | `true` | -| `controllerManager.image.registry` | The OCI registry to pull the image from | `ghcr.io` | -| `controllerManager.image.repository` | The repository within the registry | `spiffe/spire-controller-manager` | -| `controllerManager.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `controllerManager.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `controllerManager.image.tag` | Overrides the image tag whose default is the chart appVersion | `0.4.0` | -| `controllerManager.resources` | Resource requests and limits for controller manager | `{}` | -| `controllerManager.securityContext` | Security context | `{}` | -| `controllerManager.service.type` | Service type for controller manager | `ClusterIP` | -| `controllerManager.service.port` | Service port for controller manager | `443` | -| `controllerManager.service.annotations` | Annotations for service resource | `{}` | -| `controllerManager.configMap.annotations` | Annotations to add to the Controller Manager ConfigMap | `{}` | -| `controllerManager.ignoreNamespaces` | These namespaces are ignored by controller manager | `[]` | -| `controllerManager.identities.enabled` | Flag to enable default identities for controller manager | `true` | -| `controllerManager.identities.spiffeIDTemplate` | Spiffe ID template for identities | `spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}` | -| `controllerManager.identities.podSelector` | Selector for pods to issue identity | `{}` | -| `controllerManager.identities.namespaceSelector` | Selector for namespacs to issue identity | `{}` | -| `controllerManager.identities.dnsNameTemplates` | DNS name template for issued identities | `[]` | -| `controllerManager.identities.federatesWith` | Other Spire server URLs for identity federation | `[]` | -| `controllerManager.identities.workloadSelectorTemplates` | Templates to produce selectors that apply to a given workload before it will receive an ID | `[]` | -| `controllerManager.identities.ttl` | Indicates an upper-bound time-to-live for X509 SVIDs. If unset, the cluster default will be chosen. | `""` | -| `controllerManager.identities.jwtTTL` | Indicates an upper-bound time-to-live for JWT SVIDs. If unset, the cluster default will be chosen. | `""` | -| `controllerManager.identities.admin` | Indicates any pod matched by this identity will be an admin. Use this with extreme care. | `false` | -| `controllerManager.identities.downstream` | Set if this spire instance is a root server and the workloads are downstream servers. | `false` | -| `controllerManager.identities.autoPopulateDNSNames` | Auto populate DNS names from services attached to pods | `false` | -| `controllerManager.validatingWebhookConfiguration.failurePolicy` | Action when identity is not issued | `Fail` | -| `tools.kubectl.image.registry` | The OCI registry to pull the image from | `docker.io` | -| `tools.kubectl.image.repository` | The repository within the registry | `rancher/kubectl` | -| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` | -| `tools.kubectl.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | -| `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | -| `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | -| `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 | `{}` | -| `ingress.enabled` | Flag to enable ingress | `false` | -| `ingress.className` | Ingress class name | `""` | -| `ingress.controllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` | -| `ingress.annotations` | Annotations for the ingress object | `{}` | -| `ingress.host` | Host name for the ingress. If no '.' in host, trustDomain is automatically appended. The rest of the rules will be autogenerated. For more customizability, use hosts[] instead. | `spire-server` | -| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` | -| `ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` | -| `ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` | -| `extraVolumes` | Extra volumes to be mounted | `[]` | -| `extraVolumeMounts` | Extra volume mounts | `[]` | -| `extraContainers` | Additional containers to create | `[]` | -| `initContainers` | Additional init containers to create | `[]` | -| `caKeyType` | The CA key type to use, possible values are rsa-2048, rsa-4096, ec-p256, ec-p384 (AWS requires the use of RSA. EC cryptography is not supported) | `rsa-2048` | -| `caTTL` | TTL for CA | `24h` | -| `defaultX509SvidTTL` | TTL for X509 Svids | `4h` | -| `defaultJwtSvidTTL` | TTL for JWT Svids | `1h` | -| `nodeAttestor.k8sPsat.enabled` | Enable Psat k8s nodeattestor | `true` | -| `nodeAttestor.k8sPsat.serviceAccountAllowList` | Allowed service accounts for Psat nodeattestor | `[]` | +| Name | Description | Value | +| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `replicaCount` | SPIRE server currently runs with a sqlite database. Scaling to multiple instances will not work until we use an external database. | `1` | +| `image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `image.repository` | The repository within the registry | `spiffe/spire-server` | +| `image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `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. If not set and create is true, a name is generated. | `""` | +| `podAnnotations` | Annotations to add to pods | `{}` | +| `podSecurityContext` | Pod security context | `{}` | +| `securityContext` | Security context | `{}` | +| `priorityClassName` | Priority class assigned to statefulset pods | `""` | +| `service.type` | Type of the Spire server service created | `ClusterIP` | +| `service.port` | Port for the created service | `8081` | +| `service.annotations` | Annotations to add to the service object | `{}` | +| `configMap.annotations` | Annotations to add to the SPIRE Server ConfigMap | `{}` | +| `resources` | Resource requests and limits | `{}` | +| `autoscaling.enabled` | Flag to enable autoscaling | `false` | +| `autoscaling.minReplicas` | Minimum replicas for autoscaling | `1` | +| `autoscaling.maxReplicas` | Maximum replicas for autoscaling | `100` | +| `autoscaling.targetCPUUtilizationPercentage` | Target CPU utlization that triggers autoscaling | `80` | +| `nodeSelector` | Select specific nodes to run on (currently only amd64 is supported by Tornjak) | `{}` | +| `tolerations` | List of tolerations | `[]` | +| `affinity` | List of node affinities | `{}` | +| `topologySpreadConstraints` | Topology spread constraints for resilience | `[]` | +| `livenessProbe.failureThreshold` | Failure threshold count for livenessProbe | `2` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `15` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `60` | +| `livenessProbe.timeoutSeconds` | Timeout in seconds for livenessProbe | `3` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` | +| `persistence.type` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `pvc` | +| `persistence.size` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `1Gi` | +| `persistence.accessMode` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `ReadWriteOnce` | +| `persistence.storageClass` | What type of volume to use for persistence. Valid options pvc (recommended), hostPath, emptyDir (testing only) | `nil` | +| `persistence.hostPath` | Which path to use on the host when type = hostPath | `""` | +| `dataStore.sql.databaseType` | Other supported databases are "postgres" and "mysql" | `sqlite3` | +| `dataStore.sql.databaseName` | Only used by "postgres" or "mysql" | `spire` | +| `dataStore.sql.host` | Only used by "postgres" or "mysql" | `""` | +| `dataStore.sql.port` | If 0 (default), it will auto set to 5432 for postgres and 3306 for mysql. Only used by those databases. | `0` | +| `dataStore.sql.username` | Only used by "postgres" or "mysql" | `spire` | +| `dataStore.sql.password` | Only used by "postgres" or "mysql" | `""` | +| `dataStore.sql.options` | Only used by "postgres" or "mysql" | `[]` | +| `dataStore.sql.plugin_data` | Settings from https://github.com/spiffe/spire/blob/main/doc/plugin_server_datastore_sql.md go in this section | `{}` | +| `dataStore.sql.externalSecret.enabled` | Enable external secret for datastore creds | `false` | +| `dataStore.sql.externalSecret.name` | The name of the secret object | `""` | +| `dataStore.sql.externalSecret.key` | The key of the secret object whose value is the dataStore.sql password | `""` | +| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` | +| `jwtIssuer` | The JWT issuer domain. Defaults to oidc-discovery.$trustDomain if unset | `""` | +| `clusterName` | Set the name of the Kubernetes cluster. (`kubeadm init --service-dns-domain`) | `example-cluster` | +| `trustDomain` | Set the trust domain to be used for the SPIFFE identifiers | `example.org` | +| `bundleConfigMap` | Set the trust domain to be used for the SPIFFE identifiers | `spire-bundle` | +| `clusterDomain` | This is the value of your clusters `kubeadm init --service-dns-domain` flag | `cluster.local` | +| `federation.enabled` | Flag to enable federation | `false` | +| `federation.bundleEndpoint.port` | Port value for trust bundle federation | `8443` | +| `federation.bundleEndpoint.address` | Address for trust bundle federation | `0.0.0.0` | +| `federation.ingress.enabled` | Flag to enable ingress for federation | `false` | +| `federation.ingress.className` | Ingress class name for federation | `""` | +| `federation.ingress.controllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` | +| `federation.ingress.annotations` | Annotations for the ingress object | `{}` | +| `federation.ingress.host` | Host name for the ingress. If no '.' in host, trustDomain is automatically appended. The rest of the rules will be autogenerated. For more customizability, use hosts[] instead. | `spire-server-federation` | +| `federation.ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` | +| `federation.ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` | +| `federation.ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` | +| `ca_subject.country` | Country for Spire server CA | `ARPA` | +| `ca_subject.organization` | Organization for Spire server CA | `Example` | +| `ca_subject.common_name` | Common Name for Spire server CA | `example.org` | +| `keyManager.disk.enabled` | Flag to enable keyManager on disk | `true` | +| `keyManager.memory.enabled` | Flag to enable keyManager in memory | `false` | +| `keyManager.awsKMS.enabled` | Flag to enable keyManager in memory | `false` | +| `keyManager.awsKMS.region` | Specify the region for AWS KMS | `""` | +| `keyManager.awsKMS.keyPolicy` | Policy to use when creating keys. If no policy is specified, a default policy will be used. | | +| `keyManager.awsKMS.keyPolicy.policy` | Key policy in JSON format. | `""` | +| `keyManager.awsKMS.keyPolicy.existingConfigMap` | Name of a ConfigMap that has a `policy.json` file with the key policy in JSON format. | `""` | +| `keyManager.awsKMS.accessKeyID` | Access key ID for the AWS account. It's recommended to use an IAM role instead. See [here](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) to learn how to annotate your SPIRE Server Service Account to assume an IAM role. | `""` | +| `keyManager.awsKMS.secretAccessKey` | Secret access key for the AWS account. | `""` | +| `upstreamAuthority.disk.enabled` | Flag to enable upstream authority plugin on disk | `false` | +| `upstreamAuthority.disk.secret.create` | If disabled requires you to create a secret with the given keys (certificate, key and optional bundle) yourself. | `true` | +| `upstreamAuthority.disk.secret.name` | If secret creation is disabled, the secret with this name will be used. | `spiffe-upstream-ca` | +| `upstreamAuthority.disk.secret.data` | If secret creation is enabled, will create a secret with following certificate info | | +| `upstreamAuthority.disk.secret.data.certificate` | Certificate to store within disk upstreamAuthority. | `""` | +| `upstreamAuthority.disk.secret.data.key` | Key corresponding to the upstreamAuthority. | `""` | +| `upstreamAuthority.disk.secret.data.bundle` | Trust bundle for upstreamAuthority. | `""` | +| `upstreamAuthority.awsPCA.enabled` | Flag to enable upstream authority plugin with AWS PCA | `false` | +| `upstreamAuthority.awsPCA.region` | AWS Region to use | `""` | +| `upstreamAuthority.awsPCA.certificateAuthorityARN` | ARN of the "upstream" CA certificate | `""` | +| `upstreamAuthority.awsPCA.assumeRoleARN` | (Optional) ARN of an IAM role to assume | `""` | +| `upstreamAuthority.awsPCA.caSigningTemplateARN` | (Optional) ARN of the signing template to use for the server's CA. Defaults to a signing template for end-entity certificates only. See Using Templates (https://docs.aws.amazon.com/acm-pca/latest/userguide/UsingTemplates.html) for possible values. | `""` | +| `upstreamAuthority.awsPCA.signingAlgorithm` | (Optional) Signing algorithm to use for the server's CA. Defaults to the CA's default. See Issue Certificate (https://docs.aws.amazon.com/cli/latest/reference/acm-pca/issue-certificate.html) for possible values. | `""` | +| `upstreamAuthority.awsPCA.endpoint` | (Optional) Endpoint as hostname or fully-qualified URI that overrides the default endpoint. See AWS SDK Config docs (https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config) for more information. | `""` | +| `upstreamAuthority.awsPCA.supplementalBundlePath` | (Optional) Path to a file containing PEM-encoded CA certificates that should be additionally included in the bundle. | `""` | +| `upstreamAuthority.certManager.enabled` | Flag to enable upstream authority plugin with cert manager | `false` | +| `upstreamAuthority.certManager.rbac.create` | Flag to create RBAC roles | `true` | +| `upstreamAuthority.certManager.issuer_name` | Defaults to the release name, override if CA is provided outside of the chart | `""` | +| `upstreamAuthority.certManager.issuer_kind` | Defaults to "Issuer", override if CA is provided outside of the chart | `Issuer` | +| `upstreamAuthority.certManager.issuer_group` | Defaults to "cert-manager.io", override if CA is provided outside of the chart | `cert-manager.io` | +| `upstreamAuthority.certManager.namespace` | Specify to use a namespace other then the one the chart is installed into | `""` | +| `upstreamAuthority.certManager.kube_config_file` | Path to kube_config_file on node to setup cert manager | `""` | +| `upstreamAuthority.certManager.ca.create` | Creates a Cert-Manager CA | `false` | +| `upstreamAuthority.certManager.ca.duration` | Duration of the CA. Defaults to 10 years | `87600h` | +| `upstreamAuthority.certManager.ca.privateKey.algorithm` | Algorithm to generate private key for CA | `ECDSA` | +| `upstreamAuthority.certManager.ca.privateKey.size` | Size of generated private key for CA | `256` | +| `upstreamAuthority.certManager.ca.privateKey.rotationPolicy` | Rotation policy for generated private key | `""` | +| `upstreamAuthority.certManager.ca.renewBefore` | How long to wait before renewing the CA | `""` | +| `upstreamAuthority.spire.enabled` | Flag to use another Spire install as upstream CA | `false` | +| `upstreamAuthority.spire.upstreamDriver` | Driver for Spire as upstream CA | `""` | +| `upstreamAuthority.spire.server` | Server details for the Spire instance use as upstream CA | | +| `upstreamAuthority.spire.server.address` | Address for upstream Spire server | `""` | +| `upstreamAuthority.spire.server.port` | Port for upstream Spire server | `8081` | +| `upstreamAuthority.vault.enabled` | Enable Hashicorp Vault as upstream CA | `false` | +| `upstreamAuthority.vault.vaultAddr` | The URL of the Vault server. (e.g., https://vault.example.com:8443/) | `""` | +| `upstreamAuthority.vault.namespace` | Name of the Vault namespace. This is only available in the Vault Enterprise. | `""` | +| `upstreamAuthority.vault.pkiMountPoint` | Name of the mount point where PKI secret engine is mounted | `pki` | +| `upstreamAuthority.vault.insecureSkipVerify` | If true, caCert options are ignored and Spire accepts any server certificates claiming to be Vault | `false` | +| `upstreamAuthority.vault.caCert.type` | Type of resource representing the Vault server certificate, options are 'Secret' or 'Configmap', the item must be named `ca.crt` | `Secret` | +| `upstreamAuthority.vault.caCert.name` | Name of the Kubernetes resource containing the Vault server certificate | `vault-ca` | +| `upstreamAuthority.vault.k8sAuth.enabled` | Enable k8s authentication to Hashicorp Vault | `false` | +| `upstreamAuthority.vault.k8sAuth.k8sAuthMountPoint` | Name of the mount point where the Kubernetes auth method is mounted | `kubernetes` | +| `upstreamAuthority.vault.k8sAuth.k8sAuthRoleName` | Required - Name of the Vault role. The plugin authenticates against the named role | `""` | +| `upstreamAuthority.vault.k8sAuth.token.audience` | Intended audience of the PSAT, it must match one of the audiences supported by the Kubernetes API server. If no audience is specified, it defaults to the identifier of API Server. See ['Service Account Documentation'](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection) for more info. | `vault` | +| `upstreamAuthority.vault.k8sAuth.token.expiry` | Expiry time in seconds for the token | `7200` | +| `notifier.k8sbundle.namespace` | Namespace to push the bundle into, if blank will default to SPIRE Server namespace | `""` | +| `controllerManager.enabled` | Flag to enable controller manager | `false` | +| `controllerManager.className` | specify to use an explicit class name. If empty, it will be automatically set to Release.Namespace-Release.Name to not conflict with other installs, enabling parallel installs. | `""` | +| `controllerManager.watchClassless` | specify to process custom resources without class name specified. Useful to slowly migrate to class names from classless installs. Do not have two installs on the same k8s cluster both set to true. | `false` | +| `controllerManager.installAndUpgradeHook.enabled` | Enable Helm hook to autofix common install/upgrade issues (should be disabled when using `helm template`) | `true` | +| `controllerManager.deleteHook.enabled` | Enable Helm hook to autofix common delete issues (should be disabled when using `helm template`) | `true` | +| `controllerManager.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `controllerManager.image.repository` | The repository within the registry | `spiffe/spire-controller-manager` | +| `controllerManager.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `controllerManager.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `controllerManager.image.tag` | Overrides the image tag whose default is the chart appVersion | `0.4.0` | +| `controllerManager.resources` | Resource requests and limits for controller manager | `{}` | +| `controllerManager.securityContext` | Security context | `{}` | +| `controllerManager.service.type` | Service type for controller manager | `ClusterIP` | +| `controllerManager.service.port` | Service port for controller manager | `443` | +| `controllerManager.service.annotations` | Annotations for service resource | `{}` | +| `controllerManager.configMap.annotations` | Annotations to add to the Controller Manager ConfigMap | `{}` | +| `controllerManager.ignoreNamespaces` | These namespaces are ignored by controller manager | `[]` | +| `controllerManager.identities.clusterSPIFFEIDs.default.enabled` | Enable this identity for controller manager | `true` | +| `controllerManager.identities.clusterSPIFFEIDs.default.spiffeIDTemplate` | Spiffe ID template for identities | `spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}` | +| `controllerManager.identities.clusterSPIFFEIDs.default.podSelector` | Selector for pods to issue identity | `{}` | +| `controllerManager.identities.clusterSPIFFEIDs.default.namespaceSelector` | Selector for namespacs to issue identity | `{}` | +| `controllerManager.identities.clusterSPIFFEIDs.default.dnsNameTemplates` | DNS name template for issued identities | `[]` | +| `controllerManager.identities.clusterSPIFFEIDs.default.federatesWith` | Other Spire server URLs for identity federation | `[]` | +| `controllerManager.identities.clusterSPIFFEIDs.default.workloadSelectorTemplates` | Templates to produce selectors that apply to a given workload before it will receive an ID | `[]` | +| `controllerManager.identities.clusterSPIFFEIDs.default.ttl` | Indicates an upper-bound time-to-live for X509 SVIDs. If unset, the cluster default will be chosen. | `""` | +| `controllerManager.identities.clusterSPIFFEIDs.default.jwtTTL` | Indicates an upper-bound time-to-live for JWT SVIDs. If unset, the cluster default will be chosen. | `""` | +| `controllerManager.identities.clusterSPIFFEIDs.default.admin` | Indicates any pod matched by this identity will be an admin. Use this with extreme care. | `false` | +| `controllerManager.identities.clusterSPIFFEIDs.default.downstream` | Set if this spire instance is a root server and the workloads are downstream servers. | `false` | +| `controllerManager.identities.clusterSPIFFEIDs.default.autoPopulateDNSNames` | Auto populate DNS names from services attached to pods | `false` | +| `controllerManager.identities.clusterStaticEntries` | Specify ClusterStaticEntry objects. | `{}` | +| `controllerManager.identities.clusterFederatedTrustDomains` | Specify ClusterFederatedTrustDomain objects. | `{}` | +| `controllerManager.validatingWebhookConfiguration.failurePolicy` | Action when identity is not issued | `Fail` | +| `tools.kubectl.image.registry` | The OCI registry to pull the image from | `docker.io` | +| `tools.kubectl.image.repository` | The repository within the registry | `rancher/kubectl` | +| `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `tools.kubectl.image.version` | This value is deprecated in favor of tag. (Will be removed in a future release) | `""` | +| `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | +| `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | +| `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 | `{}` | +| `ingress.enabled` | Flag to enable ingress | `false` | +| `ingress.className` | Ingress class name | `""` | +| `ingress.controllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` | +| `ingress.annotations` | Annotations for the ingress object | `{}` | +| `ingress.host` | Host name for the ingress. If no '.' in host, trustDomain is automatically appended. The rest of the rules will be autogenerated. For more customizability, use hosts[] instead. | `spire-server` | +| `ingress.tlsSecret` | Secret that has the certs. If blank will use default certs. Used with host var. | `""` | +| `ingress.hosts` | Host paths for ingress object. If emtpy, rules will be built based on the host var. | `[]` | +| `ingress.tls` | Secrets containining TLS certs to enable https on ingress. If emtpy, rules will be built based on the host and tlsSecret vars. | `[]` | +| `extraVolumes` | Extra volumes to be mounted | `[]` | +| `extraVolumeMounts` | Extra volume mounts | `[]` | +| `extraContainers` | Additional containers to create | `[]` | +| `initContainers` | Additional init containers to create | `[]` | +| `caKeyType` | The CA key type to use, possible values are rsa-2048, rsa-4096, ec-p256, ec-p384 (AWS requires the use of RSA. EC cryptography is not supported) | `rsa-2048` | +| `caTTL` | TTL for CA | `24h` | +| `defaultX509SvidTTL` | TTL for X509 Svids | `4h` | +| `defaultJwtSvidTTL` | TTL for JWT Svids | `1h` | +| `nodeAttestor.k8sPsat.enabled` | Enable Psat k8s nodeattestor | `true` | +| `nodeAttestor.k8sPsat.serviceAccountAllowList` | Allowed service accounts for Psat nodeattestor | `[]` | ### Tornjak diff --git a/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml b/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml index f82e48b..8670f73 100644 --- a/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml +++ b/charts/spire/charts/spire-server/templates/controller-manager-cluster-ids.yaml @@ -1,42 +1,68 @@ {{- $root := . }} -{{- with .Values.controllerManager }} -{{- if and (eq (.enabled | toString) "true") (eq (.identities.enabled | toString) "true") }} +{{- range $key, $value := .Values.controllerManager.identities.clusterSPIFFEIDs }} +{{- range $skey, $svalue := $value }} +{{- if not (has $skey (list "name" "annotations" "labels" "enabled" "admin" "dnsNameTemplates" "downstream" "federatesWith" "jwtTTL" "namespaceSelector" "podSelector" "spiffeIDTemplate" "ttl" "workloadSelectorTemplates" "autoPopulateDNSNames")) }} +{{- fail (printf "Unsupported property specified: %s" $skey) }} +{{- end }} +{{- end }} +{{- range $rprop := list "spiffeIDTemplate" }} +{{- if not (hasKey $value $rprop) }} +{{- fail (printf "Required property %s was not specified" $rprop) }} +{{- end }} +{{- end }} +{{- if eq ($root.Values.controllerManager.enabled | toString) "true" }} +{{- if or (not (hasKey $value "enabled")) (eq ($value.enabled | toString) "true") }} +--- apiVersion: spire.spiffe.io/v1alpha1 kind: ClusterSPIFFEID metadata: - name: {{ $root.Release.Namespace }}-{{ include "spire-controller-manager.fullname" $root }}-service-account-based - namespace: {{ include "spire-server.namespace" $root }} + name: {{ $root.Release.Namespace }}-{{ $root.Release.Name }}-{{ $key }} + {{- with $value.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.labels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} spec: - spiffeIDTemplate: {{ .identities.spiffeIDTemplate | quote }} - {{- with .identities.federatesWith }} + className: {{ include "spire-server.controller-manager-class-name" $root | quote }} + spiffeIDTemplate: {{ $value.spiffeIDTemplate | quote }} + {{- with $value.federatesWith }} federatesWith: {{- toYaml . | nindent 4 }} {{- end }} - {{- with .identities.podSelector }} + {{- with $value.podSelector }} podSelector: {{- toYaml . | nindent 4 }} {{- end }} - {{- with .identities.namespaceSelector }} + {{- with $value.namespaceSelector }} namespaceSelector: {{- toYaml . | nindent 4 }} {{- end }} - {{- with .identities.dnsNameTemplates }} + {{- with $value.dnsNameTemplates }} dnsNameTemplates: {{- toYaml . | nindent 4 }} {{- end }} - {{- with .identities.workloadSelectorTemplates }} + {{- with $value.workloadSelectorTemplates }} workloadSelectorTemplates: {{- toYaml . | nindent 4 }} {{- end }} - {{- with .identities.ttl }} + {{- with $value.ttl }} ttl: {{ . | quote }} {{- end }} - {{- with .identities.jwtTTL }} + {{- with $value.jwtTTL }} jwtTtl: {{ . | quote }} {{- end }} - admin: {{ .identities.admin }} - downstream: {{ .identities.downstream }} - autoPopulateDNSNames: {{ .identities.autoPopulateDNSNames }} - className: {{ include "spire-server.controller-manager-class-name" $root | quote}} -{{- end }} + {{- with $value.admin }} + admin: {{ . }} + {{- end }} + {{- with $value.downstream }} + downstream: {{ . }} + {{- end }} + {{- with $value.autoPopulateDNSNames }} + autoPopulateDNSNames: {{ . }} + {{- end }} +{{- end }} +{{- end }} {{- end }} diff --git a/charts/spire/charts/spire-server/templates/controller-manager-ftd.yaml b/charts/spire/charts/spire-server/templates/controller-manager-ftd.yaml new file mode 100644 index 0000000..1c2b659 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/controller-manager-ftd.yaml @@ -0,0 +1,45 @@ +{{- $root := . }} +{{- range $key, $value := .Values.controllerManager.identities.clusterFederatedTrustDomains }} +{{- range $skey, $svalue := $value }} +{{- if not (has $skey (list "name" "annotations" "labels" "enabled" "bundleEndpointProfile" "bundleEndpointURL" "trustDomain" "trustDomainBundle")) }} +{{- fail (printf "Unsupported property specified: %s" $skey) }} +{{- end }} +{{- end }} +{{- range $rprop := list "bundleEndpointProfile" "bundleEndpointURL" "trustDomain" }} +{{- if not (hasKey $value $rprop) }} +{{- fail (printf "Required property %s was not specified" $rprop) }} +{{- end }} +{{- end }} +{{- if eq ($root.Values.controllerManager.enabled | toString) "true" }} +{{- if or (not (hasKey $value "enabled")) (eq ($value.enabled | toString) "true") }} +--- +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterFederatedTrustDomain +metadata: + name: {{ $root.Release.Namespace }}-{{ $root.Release.Name }}-{{ $key }} + {{- with $value.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.labels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + className: {{ include "spire-server.controller-manager-class-name" $root | quote }} + {{- with $value.bundleEndpointProfile }} + bundleEndpointProfile: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.bundleEndpointURL }} + bundleEndpointURL: {{ . | quote }} + {{- end }} + {{- with $value.trustDomain }} + trustDomain: {{ . | quote }} + {{- end }} + {{- with $value.trustDomainBundle }} + trustDomainBundle: {{ . | quote }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/templates/controller-manager-static-entries.yaml b/charts/spire/charts/spire-server/templates/controller-manager-static-entries.yaml new file mode 100644 index 0000000..47629c4 --- /dev/null +++ b/charts/spire/charts/spire-server/templates/controller-manager-static-entries.yaml @@ -0,0 +1,63 @@ +{{- $root := . }} +{{- range $key, $value := .Values.controllerManager.identities.clusterStaticEntries }} +{{- range $skey, $svalue := $value }} +{{- if not (has $skey (list "name" "annotations" "labels" "enabled" "admin" "dnsNames" "downstream" "federatesWith" "hint" "jwtSVIDTTL" "parentID" "selectors" "spiffeID" "x509SVIDTTL")) }} +{{- fail (printf "Unsupported property specified: %s" $skey) }} +{{- end }} +{{- end }} +{{- range $rprop := list "spiffeID" "selectors" "parentID" }} +{{- if not (hasKey $value $rprop) }} +{{- fail (printf "Required property %s was not specified" $rprop) }} +{{- end }} +{{- end }} +{{- if eq ($root.Values.controllerManager.enabled | toString) "true" }} +{{- if or (not (hasKey $value "enabled")) (eq ($value.enabled | toString) "true") }} +--- +apiVersion: spire.spiffe.io/v1alpha1 +kind: ClusterStaticEntry +metadata: + name: {{ $root.Release.Namespace }}-{{ $root.Release.Name }}-{{ $key }} + {{- with $value.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.labels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + className: {{ include "spire-server.controller-manager-class-name" $root | quote }} + spiffeID: {{ $value.spiffeID | quote }} + {{- with $value.federatesWith }} + federatesWith: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.selectors }} + selectors: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.parentID }} + parentID: {{ . | quote }} + {{- end }} + {{- with $value.dnsNames }} + dnsNames: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $value.hint }} + hint: {{ . | quote }} + {{- end }} + {{- with $value.x509SVIDTTL }} + x509SVIDTTL: {{ . | quote }} + {{- end }} + {{- with $value.jwtSVIDTTL }} + jwtSVIDTTL: {{ . | quote }} + {{- end }} + {{- with $value.admin }} + admin: {{ . }} + {{- end }} + {{- with $value.downstream }} + downstream: {{ . }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 143cde8..170d46e 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -445,38 +445,70 @@ controllerManager: - local-path-storage identities: - ## @param controllerManager.identities.enabled Flag to enable default identities for controller manager - enabled: true - - ## @param controllerManager.identities.spiffeIDTemplate Spiffe ID template for identities - spiffeIDTemplate: spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }} - ## @param controllerManager.identities.podSelector [object] Selector for pods to issue identity - podSelector: {} - # matchLabels: - # spiffe.io/spiffe-id: "true" - ## @param controllerManager.identities.namespaceSelector [object] Selector for namespacs to issue identity - namespaceSelector: {} - # matchLabels: - # spiffe.io/spiffe-id: "true" - ## @param controllerManager.identities.dnsNameTemplates [array] DNS name template for issued identities - dnsNameTemplates: [] - # - '{{ index .PodMeta.Labels "app.kubernetes.io/name" }}.{{ .PodMeta.Namespace }}.svc.cluster.local' - ## @param controllerManager.identities.federatesWith [array] Other Spire server URLs for identity federation - federatesWith: [] - # - example.io - # - example.ai - ## @param controllerManager.identities.workloadSelectorTemplates [array] Templates to produce selectors that apply to a given workload before it will receive an ID - workloadSelectorTemplates: [] - ## @param controllerManager.identities.ttl Indicates an upper-bound time-to-live for X509 SVIDs. If unset, the cluster default will be chosen. - ttl: "" - ## @param controllerManager.identities.jwtTTL Indicates an upper-bound time-to-live for JWT SVIDs. If unset, the cluster default will be chosen. - jwtTTL: "" - ## @param controllerManager.identities.admin Indicates any pod matched by this identity will be an admin. Use this with extreme care. - admin: false - ## @param controllerManager.identities.downstream Set if this spire instance is a root server and the workloads are downstream servers. - downstream: false - ## @param controllerManager.identities.autoPopulateDNSNames Auto populate DNS names from services attached to pods - autoPopulateDNSNames: false + clusterSPIFFEIDs: + # NOTE you can add multiple uniquely named entries to create multiple ClusterSPIFFEID objects. See example below. + default: + ## @param controllerManager.identities.clusterSPIFFEIDs.default.enabled Enable this identity for controller manager + enabled: true + ## @param controllerManager.identities.clusterSPIFFEIDs.default.spiffeIDTemplate Spiffe ID template for identities + spiffeIDTemplate: spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }} + ## @param controllerManager.identities.clusterSPIFFEIDs.default.podSelector [object] Selector for pods to issue identity + podSelector: {} + # matchLabels: + # spiffe.io/spiffe-id: "true" + ## @param controllerManager.identities.clusterSPIFFEIDs.default.namespaceSelector [object] Selector for namespacs to issue identity + namespaceSelector: {} + # matchLabels: + # spiffe.io/spiffe-id: "true" + ## @param controllerManager.identities.clusterSPIFFEIDs.default.dnsNameTemplates [array] DNS name template for issued identities + dnsNameTemplates: [] + # - '{{ index .PodMeta.Labels "app.kubernetes.io/name" }}.{{ .PodMeta.Namespace }}.svc.cluster.local' + ## @param controllerManager.identities.clusterSPIFFEIDs.default.federatesWith [array] Other Spire server URLs for identity federation + federatesWith: [] + # - example.io + # - example.ai + ## @param controllerManager.identities.clusterSPIFFEIDs.default.workloadSelectorTemplates [array] Templates to produce selectors that apply to a given workload before it will receive an ID + workloadSelectorTemplates: [] + ## @param controllerManager.identities.clusterSPIFFEIDs.default.ttl Indicates an upper-bound time-to-live for X509 SVIDs. If unset, the cluster default will be chosen. + ttl: "" + ## @param controllerManager.identities.clusterSPIFFEIDs.default.jwtTTL Indicates an upper-bound time-to-live for JWT SVIDs. If unset, the cluster default will be chosen. + jwtTTL: "" + ## @param controllerManager.identities.clusterSPIFFEIDs.default.admin Indicates any pod matched by this identity will be an admin. Use this with extreme care. + admin: false + ## @param controllerManager.identities.clusterSPIFFEIDs.default.downstream Set if this spire instance is a root server and the workloads are downstream servers. + downstream: false + ## @param controllerManager.identities.clusterSPIFFEIDs.default.autoPopulateDNSNames Auto populate DNS names from services attached to pods + autoPopulateDNSNames: false + + # You can specify additional ClusterSPIFFEIDs following this example: + # foo: + # labels: + # foo: bar + # spiffeIDTemplate: spiffe://{{ .TrustDomain }}/foo + # namespaceSelector: + # matchLabels: + # foo: bar + + ## @param controllerManager.identities.clusterStaticEntries Specify ClusterStaticEntry objects. + clusterStaticEntries: {} + # foo: + # labels: + # foo: bar + # parentID: spiffe://example.com/bar + # spiffeID: spiffe://example.com/foo + # selectors: + # - k8s:pod-label:app.kubernetes.io/name:server + + ## @param controllerManager.identities.clusterFederatedTrustDomains Specify ClusterFederatedTrustDomain objects. + clusterFederatedTrustDomains: {} + # foo: + # labels: + # foo: bar + # bundleEndpointProfile: + # endpointSPIFFEID: spiffe://example.com/foo + # type: https_spiffe + # bundleEndpointURL: https://rootserver.example.com:1234 + # trustDomain: example.com validatingWebhookConfiguration: ## @param controllerManager.validatingWebhookConfiguration.failurePolicy Action when identity is not issued diff --git a/examples/nested/values.yaml b/examples/nested/values.yaml index d24df6e..0a26f73 100644 --- a/examples/nested/values.yaml +++ b/examples/nested/values.yaml @@ -11,7 +11,9 @@ spire-server: controllerManager: enabled: true identities: - spiffeIDTemplate: spiffe://{{ .TrustDomain }}/k8s/{{ .ClusterName }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }} + clusterSPIFFEIDs: + default: + spiffeIDTemplate: spiffe://{{ .TrustDomain }}/k8s/{{ .ClusterName }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }} spiffe-oidc-discovery-provider: enabled: true diff --git a/examples/production/run-tests.sh b/examples/production/run-tests.sh index 5ef92b6..a60342a 100755 --- a/examples/production/run-tests.sh +++ b/examples/production/run-tests.sh @@ -2,7 +2,7 @@ set -xe -UPGRADE_VERSION=v0.14.0 +UPGRADE_VERSION=v0.15.1 UPGRADE_REPO=https://spiffe.github.io/helm-charts-hardened SCRIPT="$(readlink -f "$0")" From 4281114b4931be66467c241599a5ad308b0fc9dd Mon Sep 17 00:00:00 2001 From: kfox1111 Date: Tue, 28 Nov 2023 12:57:11 -0800 Subject: [PATCH 16/21] Fix missing release name from install documentation (#118) Signed-off-by: Kevin Fox --- charts/spire/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/spire/README.md b/charts/spire/README.md index dba1641..496545e 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -12,8 +12,8 @@ A Helm chart for deploying the complete Spire stack including: spire-server, spi To do a quick non production install suitable for quick testing in something like minikube: ```shell -helm install -n spire-server spire-crds --repo https://spiffe.github.io/helm-charts-hardened/ --create-namespace -helm install -n spire-server spire --repo https://spiffe.github.io/helm-charts-hardened/ +helm install -n spire-server spire-crds spire-crds --repo https://spiffe.github.io/helm-charts-hardened/ --create-namespace +helm install -n spire-server spire spire --repo https://spiffe.github.io/helm-charts-hardened/ ``` To customize, start with a base values file and edit as needed: From 1ef207c7b2e92d5d27f9ebaf1e3d2a366ba4f145 Mon Sep 17 00:00:00 2001 From: Faisal Memon Date: Tue, 28 Nov 2023 14:01:16 -0800 Subject: [PATCH 17/21] Add note about supported version upgrades (#119) Signed-off-by: Faisal Memon --- README.md | 2 +- charts/spire/README.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 776df01..8e4903a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ A suite of [Helm Charts](https://helm.sh/docs) for standardized installations of ## How to install or upgrade You most likely want to do an integrated setup based on the spire chart. -See the [Instructions](https://artifacthub.io/packages/helm/spiffe/spire). +See the [Instructions](https://artifacthub.io/packages/helm/spiffe/spire#install-notes). ## Contributing diff --git a/charts/spire/README.md b/charts/spire/README.md index 496545e..f13bc9e 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -32,6 +32,8 @@ For production installs, please see [the production example](https://github.com/ ## Upgrade notes +We only support upgrading one major version at a time. Version skipping isn't supported. + ### 0.16.X The settings under "spire-server.controllerManager.identities" have all been moved under "spire-server.controllerManager.identities.clusterSPIFFEIDs.default". If you have changed any from the defaults, please update them to the new location during upgrade. From b7d8590b775e57da4450a6a80a46258e66766564 Mon Sep 17 00:00:00 2001 From: Mariusz Sabath Date: Tue, 28 Nov 2023 19:13:32 -0500 Subject: [PATCH 18/21] Fix missing protocol in JWT Issuer (#120) * Add missing protocol to jwt_issuer Signed-off-by: Mariusz Sabath * Removed trailing spaces Signed-off-by: Mariusz Sabath --------- Signed-off-by: Mariusz Sabath --- .../charts/spire-server/templates/configmap.yaml | 12 ++++++------ charts/spire/templates/_spire-lib.tpl | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index e366716..a677810 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -206,7 +206,7 @@ plugins: {{- fail "You can only enable a single authentication mechanism to an upstream Vault." }} {{- end }} {{- end }} - {{- end }} + {{- end }} {{- with .Values.upstreamAuthority.awsPCA }} {{- if eq (.enabled | toString) "true" }} @@ -219,18 +219,18 @@ plugins: ca_signing_template_arn: {{ .caSigningTemplateARN | default "arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen0/V1" | quote }} {{- if ne .signingAlgorithm "" }} signing_algorithm: {{ .signingAlgorithm | quote }} - {{- end }} + {{- end }} {{- if ne .assumeRoleARN "" }} assume_role_arn: {{ .assumeRoleARN | quote }} - {{- end }} + {{- end }} {{- if ne .endpoint "" }} endpoint: {{ .endpoint | quote }} - {{- end }} + {{- end }} {{- if ne .supplementalBundlePath "" }} supplemental_bundle_path: {{ .supplementalBundlePath | quote }} - {{- end }} + {{- end }} + {{- end }} {{- end }} - {{- end }} {{- if gt $upstreamAuthorityUsed 1 }} {{- fail "You can only enable a single Upstream Authority." }} {{- end }} diff --git a/charts/spire/templates/_spire-lib.tpl b/charts/spire/templates/_spire-lib.tpl index 2208abe..8536e22 100644 --- a/charts/spire/templates/_spire-lib.tpl +++ b/charts/spire/templates/_spire-lib.tpl @@ -20,7 +20,7 @@ {{- else if ne (len .Values.jwtIssuer) 0 }} {{- .Values.jwtIssuer }} {{- else }} -{{- printf "oidc-discovery.%s" (include "spire-lib.trust-domain" .) }} +{{- printf "https://oidc-discovery.%s" (include "spire-lib.trust-domain" .) }} {{- end }} {{- end }} From 7145ebccc88723d4ce3f1c0ab4c13db04352b32c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 20:03:27 -0800 Subject: [PATCH 19/21] Bump github.com/onsi/ginkgo/v2 from 2.13.1 to 2.13.2 in /tests (#126) Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.13.1 to 2.13.2. - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](https://github.com/onsi/ginkgo/compare/v2.13.1...v2.13.2) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tests/go.mod | 2 +- tests/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/go.mod b/tests/go.mod index e3a0560..44a6a08 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -3,7 +3,7 @@ module github.com/spiffe/helm-charts/tests go 1.20 require ( - github.com/onsi/ginkgo/v2 v2.13.1 + github.com/onsi/ginkgo/v2 v2.13.2 github.com/onsi/gomega v1.30.0 helm.sh/helm/v3 v3.13.2 ) diff --git a/tests/go.sum b/tests/go.sum index 12e99c6..0140bd9 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -85,8 +85,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU= -github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= +github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs= +github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= From a22838a532b81c588b5f2c522be2eba0dfbcae3b Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Fri, 10 Nov 2023 14:57:17 +0100 Subject: [PATCH 20/21] Add additional instructions to release PR to also check other charts Signed-off-by: Marco Franssen --- release-chart.sh | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/release-chart.sh b/release-chart.sh index 1369567..9955992 100755 --- a/release-chart.sh +++ b/release-chart.sh @@ -6,12 +6,12 @@ ## ## Usage example(s): ## -## ./__PROG__ --chart spire --current-version 0.15.1 --new-version 0.16.0 +## ./__PROG__ --chart spire --new-version 0.16.0 +## ./__PROG__ --chart spire-crds --new-version 0.3.0 ## ## Options: ## --help Show this help message ## --chart The chart to release -## --current-version The current version number ## --new-version The new version number ## --dry-run Will not actually submit the PR ## @@ -39,6 +39,24 @@ function print_error_and_exit { exit 1 } +function unreleased_changes_other_charts { + for chart in "${1[@]}" ; do + latest_tag="$(git tag --list "${chart}-[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -n 1)" + changes="$(git log "${latest_tag}..HEAD" --pretty=format:'* %h %s' "charts/${chart}")" + if [ -n "${changes}" ] ; then + echo "### Unreleased changes ${chart}" + echo + echo "${changes}" + echo + echo Please ensure you bump above charts as well before merging main into the release branch. + echo + echo '```shell' + echo ./release-chart.sh --chart "${chart}" --new-version ……… + echo '```' + fi + done +} + while (("$#")); do case "$1" in --help) @@ -49,10 +67,6 @@ while (("$#")); do chart=$2 shift 2 ;; - --current-version) - current_version=$2 - shift 2 - ;; --new-version) new_version=$2 shift 2 @@ -86,11 +100,6 @@ if [ -z "$chart" ]; then print_error_and_exit 'chart option is missing' fi -if [ -z "$current_version" ]; then - usage - print_error_and_exit 'current-version option is missing' -fi - if [ -z "$new_version" ]; then usage print_error_and_exit 'new-version option is missing' @@ -102,9 +111,12 @@ fi branch_name="bump-${chart}-version" +git fetch --tags git checkout main git pull git checkout --track -B "${branch_name}" main + +current_version="$(grep '^version:' "charts/${chart}/Chart.yaml" | awk '{print $2}')" commits_since_previous_release="$(git log "${chart}-${current_version}..HEAD" --pretty=format:'* %h %s' "charts/${chart}")" "${SED}" -i "s/version: ${current_version}/version: ${new_version}/" "charts/${chart}/Chart.yaml" "${SED}" -i "s/${current_version}/${new_version}/" "charts/${chart}/README.md" @@ -114,9 +126,22 @@ git commit -m "Bump ${chart} Helm Chart version from ${current_version} to ${new -s git push -u origin --force-with-lease +other_charts=() +for chart_dir in charts/*/; do + chart_name=$(basename "$chart_dir") + if [[ "$chart_name" != "$chart" ]]; then + other_charts+=("$chart_name") + fi +done + cat < [!Important] +> Before merging to the release branch, ensure all other changed charts also have their version number bumped. + +$(unreleased_changes_other_charts "${other_charts[@]}") + > [!Note] > **Maintainers** ensure to run following after merging this PR to trigger the release workflow: > From 78bb95ba35865ec71f9d472ccd229e12f7fc245b Mon Sep 17 00:00:00 2001 From: Marco Franssen Date: Thu, 30 Nov 2023 17:39:33 +0100 Subject: [PATCH 21/21] Bump spire Helm Chart version from 0.15.1 to 0.16.0 * b7d8590 Fix missing protocol in JWT Issuer (#120) * 1ef207c Add note about supported version upgrades (#119) * 4281114 Fix missing release name from install documentation (#118) * e030fa1 Allow additional CRs to be managed by the chart (#117) * d936293 Enable agent to kubelet connection to use hostname (#112) * e68f617 Bump test chart dependencies (#116) * d616632 Bump spire version to 1.8.5 (#115) * 95e1eb7 Bump test chart dependencies * 966061c Auto add default CSIDriver labels on OpenShift * c9885de Introduce ReadOnlyRootFilesystem for Tornjak frontend (#110) * 8107095 Fix typo ClusterSPIFFEID for workloadTSelectoremplates (#107) * 5c0ce97 Ordering of SecurityContextConstraint array items (#105) * 889d0af Bump test chart dependencies * f5d1376 Documentation cleanup (#97) Signed-off-by: Marco Franssen Co-authored-by: kfox1111 --- charts/spire/Chart.yaml | 2 +- charts/spire/README.md | 4 ++-- release-chart.sh | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/spire/Chart.yaml b/charts/spire/Chart.yaml index 909785e..98e7895 100644 --- a/charts/spire/Chart.yaml +++ b/charts/spire/Chart.yaml @@ -3,7 +3,7 @@ name: spire description: > A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager. type: application -version: 0.15.1 +version: 0.16.0 appVersion: "1.8.5" keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"] home: https://github.com/spiffe/helm-charts/tree/main/charts/spire diff --git a/charts/spire/README.md b/charts/spire/README.md index f13bc9e..b079db7 100644 --- a/charts/spire/README.md +++ b/charts/spire/README.md @@ -1,6 +1,6 @@ # spire -![Version: 0.15.1](https://img.shields.io/badge/Version-0.15.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.8.5](https://img.shields.io/badge/AppVersion-1.7.2-informational?style=flat-square) +![Version: 0.16.0](https://img.shields.io/badge/Version-0.16.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.8.5](https://img.shields.io/badge/AppVersion-1.8.5-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. @@ -28,7 +28,7 @@ Then: helm install -n spire-server spire --repo https://spiffe.github.io/helm-charts-hardened/ -f your-values.yaml ``` -For production installs, please see [the production example](https://github.com/spiffe/helm-charts-hardened/tree/main/examples/production). +For production installs, please see [the production example](https://github.com/spiffe/helm-charts-hardened/tree/spire-0.16.0/examples/production). ## Upgrade notes diff --git a/release-chart.sh b/release-chart.sh index 9955992..bbb0714 100755 --- a/release-chart.sh +++ b/release-chart.sh @@ -40,9 +40,9 @@ function print_error_and_exit { } function unreleased_changes_other_charts { - for chart in "${1[@]}" ; do - latest_tag="$(git tag --list "${chart}-[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -n 1)" - changes="$(git log "${latest_tag}..HEAD" --pretty=format:'* %h %s' "charts/${chart}")" + for chart in "$@" ; do + latest_tag="$(git --no-pager tag --list "${chart}-[0-9]*.[0-9]*.[0-9]*" | sort -V | tail -n 1)" + changes="$(git --no-pager log "${latest_tag}..HEAD" --pretty=format:'* %h %s' "charts/${chart}")" if [ -n "${changes}" ] ; then echo "### Unreleased changes ${chart}" echo @@ -119,7 +119,7 @@ git checkout --track -B "${branch_name}" main current_version="$(grep '^version:' "charts/${chart}/Chart.yaml" | awk '{print $2}')" commits_since_previous_release="$(git log "${chart}-${current_version}..HEAD" --pretty=format:'* %h %s' "charts/${chart}")" "${SED}" -i "s/version: ${current_version}/version: ${new_version}/" "charts/${chart}/Chart.yaml" -"${SED}" -i "s/${current_version}/${new_version}/" "charts/${chart}/README.md" +"${SED}" -i "s/${current_version}/${new_version}/g" "charts/${chart}/README.md" git add "charts/${chart}/"{Chart.yaml,README.md} git commit -m "Bump ${chart} Helm Chart version from ${current_version} to ${new_version}" \ -m "${commits_since_previous_release}" \