From 53e627678f16e8f5f1e9479959ecbf4581227f50 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Fri, 12 May 2023 22:39:36 +0100 Subject: [PATCH] Fix Helm chart Join token secret creation (#26055) * Fix Helm chart Join token secret creation Since #20763 was merged, we lost the ability of the chart reusing the externally created secrets for join token. This PR changes the logic and allows to control the secret creation using the `joinTokenSecret.create` boolean and the secret name with `joinTokenSecret.name`. Fixes #20763 * Add changelog --- CHANGELOG.md | 35 +++++++++++++ .../helm-reference/teleport-kube-agent.mdx | 51 ++++++++++++------- .../templates/deployment.yaml | 2 +- .../teleport-kube-agent/templates/secret.yaml | 4 +- .../templates/statefulset.yaml | 2 +- .../tests/__snapshot__/secret_test.yaml.snap | 11 ++++ .../tests/secret_test.yaml | 26 ++++++++++ .../chart/teleport-kube-agent/values.yaml | 13 ++++- 8 files changed, 122 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4252c9f7b47ae..c1850f2bc3421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,40 @@ # Changelog +## 13.0.1 (05/xx/23) + +* Helm Charts + * Fixed issue with invite token being incorrectly overridden when it was manually created. [#26055](https://github.com/gravitational/teleport/pull/26055) + +### Breaking Changes + +Please familiarize yourself with the following potentially disruptive changes in +Teleport 13 before upgrading. + +#### Teleport Kubernetes Agent helm chart + +When upgrading to Teleport 13, users of the Teleport Kubernetes Agent Helm chart +that manually create their own Teleport token secret (`secretName=` and no auth token provided) +will need to set the following values: + +```yaml +# Manages the join token secret creation and its name. +joinTokenSecret: + # create controls whether the Helm chart should create and manage the join token + # secret. + # If false, the chart assumes that the secret with the configured name already exists at the + # installation namespace. + create: false + # Name of the Secret to store the teleport join token. + name: +``` + +The Helm chart parameter `secretName` was deprecated in Teleport 13 in favor of +`joinTokenSecret.name`. `joinTokenSecret.create` indicates whether the Helm +chart should create and manage the join token secret. If `create` is set to +`false`, the chart assumes that the secret with the configured name already +exists at the installation namespace. + + ## 13.0.0 (05/08/23) Teleport 13 brings the following marquee features and improvements: diff --git a/docs/pages/reference/helm-reference/teleport-kube-agent.mdx b/docs/pages/reference/helm-reference/teleport-kube-agent.mdx index 6856fd3b1a009..f6ac27fb46d92 100644 --- a/docs/pages/reference/helm-reference/teleport-kube-agent.mdx +++ b/docs/pages/reference/helm-reference/teleport-kube-agent.mdx @@ -5,7 +5,7 @@ description: Values that can be set using the teleport-kube-agent Helm chart The `teleport-kube-agent` Helm chart is used to configure a Teleport agent that runs in a remote Kubernetes cluster to provide access to resources in your -infrastructure. +infrastructure. You can [browse the source on GitHub](https://github.com/gravitational/teleport/tree/branch/v(=teleport.major_version=)/examples/chart/teleport-kube-agent). @@ -30,11 +30,11 @@ The `teleport-kube-agent` chart can run any or all of three Teleport services: Releases of this chart installed before version 11 are considered legacy releases, which launch the Teleport pod as a `Deployment` if no storage was -configured. +configured. In version 11 and above, the chart launches the Teleport pod as a `StatefulSet` even when the chart is configured not to use external storage, and the Teleport pod -reads its state from a Kubernetes `Secret`. +reads its state from a Kubernetes `Secret`. While the Teleport pod does not require external storage, you can still use the [`storage.enabled`](#storageenabled) field to configure the way the Teleport pod @@ -51,7 +51,7 @@ The `teleport-kube-agent` chart deploys the following Kubernetes resources: | Kind | Default Name | Description | When Deployed | |-----------------------|------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------| | `StatefulSet` | The release name | Running a user-configured Teleport pod. | Always. | -| `Secret` | `secretName` (default: `teleport-kube-agent-join-token`) | Used for managing the state of the Teleport pod. | `authToken` or `joinParams.tokenName` is provided. | +| `Secret` | `joinTokenSecret.name` (default: `teleport-kube-agent-join-token`) | Used for managing the state of the Teleport pod. | `joinTokenSecret.secret` is `true`. | | `Deployment` | The release name | Runs a user-configured Teleport pod. | `storage.enabled` is `false` and the chart is being upgraded. Fresh installs will deploy a `StatefulSet` instead. | | `Role` | The `roleName` option, if given, or the release name. | Used to manage the state of the Teleport pod via Kubernetes secrets. | Always. | | `ClusterRole` | `clusterRoleName`, if given, or the release name. | Allows impersonating users, groups, and service accounts, getting pods, and creating [`SelfSubjectAccessReview`s](https://www.pulumi.com/registry/packages/kubernetes/api-docs/authorization/v1/selfsubjectaccessreview/) so the Teleport pod can manage access to resources in its Kubernetes cluster. | Always. | @@ -141,7 +141,7 @@ You can enable this when: You must not enable this if: - you are a Teleport Cloud customer not enrolled in automatic updates. -- you are a self-hosted Teleport user and have not set up your Teleport cluster to +- you are a self-hosted Teleport user and have not set up your Teleport cluster to support automatic updates. ### `updater.versionServer` @@ -195,7 +195,7 @@ than a Teleport-published image. `roleBindingName` provides a custom name for the `RoleBinding` resource that the `teleport-kube-agent` chart creates for the Teleport pod. By default, the -`RoleBinding` has the name of the Helm release. +`RoleBinding` has the name of the Helm release. You should set this value if there is a `RoleBinding` resource in the namespace of your `teleport-kube-agent` resources with the same name as your @@ -215,7 +215,7 @@ of your `teleport-kube-agent` resources with the same name as your `roleName` provides a custom name for the `Role` resource that the `teleport-kube-agent` chart creates for the Teleport pod. By default, the `Role` -has the name of the Helm release. +has the name of the Helm release. You should set this value if there is a `Role` resource in the namespace of your `teleport-kube-agent` resources with the same name as your `teleport-kube-agent` @@ -224,7 +224,7 @@ release. `values.yaml` example: ```yaml - roleName: myrole + roleName: myrole ``` ## `serviceAccountName` @@ -244,7 +244,7 @@ The value `joinParams` supports more methods to join the Teleport cluster and ta and `joinParams` are set. A token must be specified for the agent to join the Teleport cluster, either though `authToken`, -[`joinParams`](#joinparams), or [an existing Kubernetes Secret](#secretname). +[`joinParams`](#joinparams), or [an existing Kubernetes Secret](#joinTokenSecret). | Services | Service Name | `tctl tokens add` example | `teleport.yaml` static token example | |-----------------------------------|---------------|--------------------------------------|---------------------------------------------| @@ -289,7 +289,7 @@ Possible values are `token`, `iam` and `ec2`. - For `ec2`, see [Joining Nodes Via AWS IAM Role](../../management/join-services-to-your-cluster/aws-ec2.mdx). - For `token` (default value), the token must be provided through `joinParams.tokenName` or - [through an existing Kubernetes Secret](#secretName). + [through an existing Kubernetes Secret](#joinTokenSecret). Using the IAM joining method requires either the pods to have access to [instance @@ -321,7 +321,7 @@ the value is sensitive and is automatically stored in a Kubernetes Secret instea agent's configuration. If method is `token`, `joinParams.tokenName` can be empty if the token is provided through an existing Kubernetes -Secret, see [`secretName`](#secretName) for more details and instructions. +Secret, see [`joinTokenSecret`](#joinTokenSecret) for more details and instructions. `values.yaml` example: @@ -868,7 +868,7 @@ hook](https://helm.sh/docs/topics/charts_hooks/), and the upgrade finishes. If `storage.enabled` is `true`, then during the upgrade, the `teleport-kube-agent` chart will use the existing `StatefulSet` resource to run the Teleport pod. The chart will import the pod's identify from the previously -configured external storage into a Kubernetes `Secret`. +configured external storage into a Kubernetes `Secret`. #### New chart installations @@ -1141,7 +1141,7 @@ When off, the `serviceAccount.name` parameter should be set to the existing `Ser `serviceAccount.name` provides a custom name for the `ServiceAccount` resource that the `teleport-kube-agent` chart creates for the Teleport pod. By default, -the `ServiceAccount` has the name of the Helm release. +the `ServiceAccount` has the name of the Helm release. You should set this value if there is a `ServiceAccount` resource in the namespace of your `teleport-kube-agent` resources with the same name as your @@ -1154,16 +1154,28 @@ namespace of your `teleport-kube-agent` resources with the same name as your name: kubernetes-serviceaccount ``` -## `secretName` +## `joinTokenSecret` + +### `joinTokenSecret.create` + +| Type | Default value | +|----------|----------------------------------| +| `bool` | `true` | + + +Boolean value to control whether Helm Chart should create the `Secret`. +When off, the `joinTokenSecret.name` parameter should be set to the existing `Secret` name. + +### `joinTokenSecret.name` | Type | Default value | |----------|----------------------------------| | `string` | `teleport-kube-agent-join-token` | -`secretName` is the name of the Kubernetes Secret containing the Teleport join token used by the chart. +`name` is the name of the Kubernetes Secret containing the Teleport join token used by the chart. -If `joinParams.method` is `token` and you set both `authToken` and `joinParams.tokenName` to a blank value, the chart -will not attempt to create the secret itself. Instead, it will read the value from an existing secret. `secretName` +If `joinTokenSecret.create` is `false`, the chart will not attempt to create the secret itself. +Instead, it will read the value from an existing secret. `joinTokenSecret.name` configures the name of this secret. This allows you to configure this secret externally and avoid having a plaintext join token stored in your Teleport chart values. @@ -1180,7 +1192,10 @@ $ kubectl --namespace teleport create secret generic teleport-kube-agent-join-to `values.yaml` example: ```yaml - secretName: "secret-i-created-before" + joinTokenSecret: + create: false + name: "secret-i-created-before" + joinParams: method: "token" tokenName: "" diff --git a/examples/chart/teleport-kube-agent/templates/deployment.yaml b/examples/chart/teleport-kube-agent/templates/deployment.yaml index 004555bd889ad..35423e0ac0698 100644 --- a/examples/chart/teleport-kube-agent/templates/deployment.yaml +++ b/examples/chart/teleport-kube-agent/templates/deployment.yaml @@ -193,7 +193,7 @@ spec: name: {{ .Release.Name }} - name: "auth-token" secret: - secretName: {{ .Values.secretName }} + secretName: {{ coalesce .Values.secretName .Values.joinTokenSecret.name }} {{- if not .Values.existingDataVolume }} - name: "data" emptyDir: {} diff --git a/examples/chart/teleport-kube-agent/templates/secret.yaml b/examples/chart/teleport-kube-agent/templates/secret.yaml index 929b3f104fde8..1d3d3aabecad0 100644 --- a/examples/chart/teleport-kube-agent/templates/secret.yaml +++ b/examples/chart/teleport-kube-agent/templates/secret.yaml @@ -1,7 +1,8 @@ +{{- if .Values.joinTokenSecret.create }} apiVersion: v1 kind: Secret metadata: - name: {{ .Values.secretName }} + name: {{ coalesce .Values.secretName .Values.joinTokenSecret.name }} namespace: {{ .Release.Namespace }} {{- if .Values.extraLabels.secret }} labels: @@ -11,3 +12,4 @@ type: Opaque stringData: auth-token: | {{ coalesce .Values.joinParams.tokenName .Values.authToken }} +{{- end}} diff --git a/examples/chart/teleport-kube-agent/templates/statefulset.yaml b/examples/chart/teleport-kube-agent/templates/statefulset.yaml index e531e853e641d..dbec1d2ade4c9 100644 --- a/examples/chart/teleport-kube-agent/templates/statefulset.yaml +++ b/examples/chart/teleport-kube-agent/templates/statefulset.yaml @@ -210,7 +210,7 @@ spec: name: {{ .Release.Name }} - name: "auth-token" secret: - secretName: {{ .Values.secretName }} + secretName: {{ coalesce .Values.secretName .Values.joinTokenSecret.name }} {{- if not .Values.storage.enabled }} - name: "data" emptyDir: {} diff --git a/examples/chart/teleport-kube-agent/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/teleport-kube-agent/tests/__snapshot__/secret_test.yaml.snap index 2559bafa80ac8..4476e14a12f82 100644 --- a/examples/chart/teleport-kube-agent/tests/__snapshot__/secret_test.yaml.snap +++ b/examples/chart/teleport-kube-agent/tests/__snapshot__/secret_test.yaml.snap @@ -30,6 +30,17 @@ generates a secret when joinParams.tokenName is provided: auth-token: | sample-auth-token-dont-use-this type: Opaque +generates a secret with a custom name when authToken and joinTokenSecret.name are provided: + 1: | + apiVersion: v1 + kind: Secret + metadata: + name: some-other-secret-name + namespace: NAMESPACE + stringData: + auth-token: | + sample-auth-token-dont-use-this + type: Opaque generates a secret with a custom name when authToken and secretName are provided: 1: | apiVersion: v1 diff --git a/examples/chart/teleport-kube-agent/tests/secret_test.yaml b/examples/chart/teleport-kube-agent/tests/secret_test.yaml index ca236f43e72e7..0069f35682e9e 100644 --- a/examples/chart/teleport-kube-agent/tests/secret_test.yaml +++ b/examples/chart/teleport-kube-agent/tests/secret_test.yaml @@ -50,6 +50,32 @@ tests: value: some-other-secret-name - matchSnapshot: {} + - it: generates a secret with a custom name when authToken and joinTokenSecret.name are provided + set: + authToken: sample-auth-token-dont-use-this + joinTokenSecret: + name: some-other-secret-name + create: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Secret + - equal: + path: metadata.name + value: some-other-secret-name + - matchSnapshot: {} + + - it: does not create a secret when joinTokenSecret.create is false + set: + authToken: sample-auth-token-dont-use-this + joinTokenSecret: + name: some-other-secret-name + create: false + asserts: + - hasDocuments: + count: 0 + - it: sets Secret labels when specified values: - ../.lint/extra-labels.yaml diff --git a/examples/chart/teleport-kube-agent/values.yaml b/examples/chart/teleport-kube-agent/values.yaml index 3f5efa7d68bb1..52bc63a53973e 100644 --- a/examples/chart/teleport-kube-agent/values.yaml +++ b/examples/chart/teleport-kube-agent/values.yaml @@ -250,7 +250,18 @@ rbac: create: true # Name of the Secret to store the teleport join token. -secretName: teleport-kube-agent-join-token +# DEPRECATED Use joinTokenSecret.name instead +secretName: "" + +# Manages the join token secret creation and its name. +joinTokenSecret: + # create controls whether the Helm chart should create and manage the join token + # secret. + # If false, the chart assumes that the secret with the configured name already exists at the + # installation namespace. + create: true + # Name of the Secret to store the teleport join token. + name: teleport-kube-agent-join-token # Teleport logging configuration log: