From 3c38b4ad1b8e73a395ac6f2a511199624a90ae88 Mon Sep 17 00:00:00 2001 From: Noah Stride Date: Mon, 9 Sep 2024 11:39:15 +0100 Subject: [PATCH] Machine ID: `tbot` helm chart (#44615) * Start roughly hacking on a chart for tobt * Start templating out the deployment spec * Add image pull secrets * Add more configurability to deployment spec * Pull most config into params rather than config map * Prefer configuring using config file * Add to index * Allow configuration of extraEnv * Fix extraEnv * Update makefile to test/lint new tbot chart * Start adding tests for `tbot` chart * Fix spurious newline in config mpa * Add more tests for volumes/tolerations etc * Appease vale linting * Add docstrings to all values * Add required values * Make services/outputs manually configurable * Use simpler storage technique * Generate docs * Fix linting issues * Simple -> Basic * Add support for fullnameoverride and nameoverride * Add extended timeout seconds to liveness and readiness probe * Add _config.tpl with merging * Tweak readme for latest changes * Allow persistence to be configured and use `secret` by default * Further add validation * Update snapshtos * Fix newlining in templates * Fixes after real testing against cluster * More value docs + derive the default output name * fixup! More value docs + derive the default output name * Update cpsell * Update Chart.yaml * Appease prose linter * Remove unused value --------- Co-authored-by: hugoShaka --- Makefile | 4 +- docs/cspell.json | 1 + .../helm-reference/zz_generated.tbot.mdx | 437 ++++++++++++++++++ examples/chart/Makefile | 16 +- examples/chart/index.html | 11 + examples/chart/tbot/.lint/full.yaml | 100 ++++ examples/chart/tbot/.lint/simple.yaml | 5 + examples/chart/tbot/Chart.yaml | 10 + examples/chart/tbot/README.md | 42 ++ examples/chart/tbot/templates/_config.tpl | 49 ++ examples/chart/tbot/templates/_helpers.tpl | 56 +++ examples/chart/tbot/templates/config.yaml | 14 + examples/chart/tbot/templates/deployment.yaml | 141 ++++++ examples/chart/tbot/templates/role.yaml | 20 + .../chart/tbot/templates/rolebinding.yaml | 23 + .../chart/tbot/templates/serviceaccount.yaml | 15 + .../tests/__snapshot__/config_test.yaml.snap | 78 ++++ .../__snapshot__/deployment_test.yaml.snap | 218 +++++++++ .../tests/__snapshot__/role_test.yaml.snap | 32 ++ .../__snapshot__/rolebinding_test.yaml.snap | 34 ++ .../serviceaccount_test.yaml.snap | 18 + examples/chart/tbot/tests/config_test.yaml | 31 ++ .../chart/tbot/tests/deployment_test.yaml | 17 + examples/chart/tbot/tests/role_test.yaml | 20 + .../chart/tbot/tests/rolebinding_test.yaml | 20 + .../chart/tbot/tests/serviceaccount_test.yaml | 20 + examples/chart/tbot/values.yaml | 229 +++++++++ 27 files changed, 1658 insertions(+), 3 deletions(-) create mode 100644 docs/pages/includes/helm-reference/zz_generated.tbot.mdx create mode 100644 examples/chart/tbot/.lint/full.yaml create mode 100644 examples/chart/tbot/.lint/simple.yaml create mode 100644 examples/chart/tbot/Chart.yaml create mode 100644 examples/chart/tbot/README.md create mode 100644 examples/chart/tbot/templates/_config.tpl create mode 100644 examples/chart/tbot/templates/_helpers.tpl create mode 100644 examples/chart/tbot/templates/config.yaml create mode 100644 examples/chart/tbot/templates/deployment.yaml create mode 100644 examples/chart/tbot/templates/role.yaml create mode 100644 examples/chart/tbot/templates/rolebinding.yaml create mode 100644 examples/chart/tbot/templates/serviceaccount.yaml create mode 100644 examples/chart/tbot/tests/__snapshot__/config_test.yaml.snap create mode 100644 examples/chart/tbot/tests/__snapshot__/deployment_test.yaml.snap create mode 100644 examples/chart/tbot/tests/__snapshot__/role_test.yaml.snap create mode 100644 examples/chart/tbot/tests/__snapshot__/rolebinding_test.yaml.snap create mode 100644 examples/chart/tbot/tests/__snapshot__/serviceaccount_test.yaml.snap create mode 100644 examples/chart/tbot/tests/config_test.yaml create mode 100644 examples/chart/tbot/tests/deployment_test.yaml create mode 100644 examples/chart/tbot/tests/role_test.yaml create mode 100644 examples/chart/tbot/tests/rolebinding_test.yaml create mode 100644 examples/chart/tbot/tests/serviceaccount_test.yaml create mode 100644 examples/chart/tbot/values.yaml diff --git a/Makefile b/Makefile index 34ccbc2390742..e8a67859e021f 100644 --- a/Makefile +++ b/Makefile @@ -863,6 +863,7 @@ test-helm: helmunit/installed helm unittest -3 examples/chart/teleport-cluster/charts/teleport-operator helm unittest -3 examples/chart/access/* helm unittest -3 examples/chart/event-handler + helm unittest -3 examples/chart/tbot .PHONY: test-helm-update-snapshots test-helm-update-snapshots: helmunit/installed @@ -871,6 +872,7 @@ test-helm-update-snapshots: helmunit/installed helm unittest -3 -u examples/chart/teleport-cluster/charts/teleport-operator helm unittest -3 -u examples/chart/access/* helm unittest -3 -u examples/chart/event-handler + helm unittest -3 -u examples/chart/tbot # # Runs all Go tests except integration, called by CI/CD. @@ -1265,7 +1267,7 @@ lint-helm: if [ "$${CI}" = "true" ]; then echo "This is a failure when running in CI." && exit 1; fi; \ exit 0; \ fi; \ - for CHART in ./examples/chart/teleport-cluster ./examples/chart/teleport-kube-agent ./examples/chart/teleport-cluster/charts/teleport-operator; do \ + for CHART in ./examples/chart/teleport-cluster ./examples/chart/teleport-kube-agent ./examples/chart/teleport-cluster/charts/teleport-operator ./examples/chart/tbot; do \ if [ -d $${CHART}/.lint ]; then \ for VALUES in $${CHART}/.lint/*.yaml; do \ export HELM_TEMP=$$(mktemp); \ diff --git a/docs/cspell.json b/docs/cspell.json index daece02d4b15d..d9413d6f1c9fe 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -489,6 +489,7 @@ "fprint", "ftmg", "fullchain", + "fullname", "gacc", "gcloud", "gcpproj", diff --git a/docs/pages/includes/helm-reference/zz_generated.tbot.mdx b/docs/pages/includes/helm-reference/zz_generated.tbot.mdx new file mode 100644 index 0000000000000..036f40f8e6f8e --- /dev/null +++ b/docs/pages/includes/helm-reference/zz_generated.tbot.mdx @@ -0,0 +1,437 @@ + +{/* Generated file. Do not edit.*/} +{/* Generate this file by navigating to examples/chart and running make render-chart-ref*/} +## `image` + +| Type | Default | +|------|---------| +| `string` | `"public.ecr.aws/gravitational/tbot-distroless"` | + +`image` sets the container image used for tbot pods created by this +chart. + +You can override this to use your own tbot image rather than a +Teleport-published image. + +## `clusterName` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`clusterName` should be the name of the Teleport cluster that your +Bot will join. You can retrieve it by running `tctl status`. + +For example: `clusterName: "test.teleport.sh"` + +## `teleportProxyAddress` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`teleportProxyAddress` is the teleport Proxy Service address the bot will connect to. +This must contain the port number, usually 443 or 3080 for Proxy Service. +Connecting to the Proxy Service is the most common and recommended way to connect to Teleport. +This is mandatory to connect to Teleport Enterprise (Cloud) + +This setting is mutually exclusive with teleportProxyAddress and is ignored if `customConfig` is set. + +For example: +```yaml +teleportProxyAddress: "test.teleport.sh:443" +``` + +## `teleportAuthAddress` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`teleportAuthAddress` is the teleport Auth Service address the bot will connect to. +This must contain the port number, usually 3025 for Auth Service. Direct Auth Service connection +should be used when you are deploying the bot in the same Kubernetes cluster than your `teleport-cluster` +Helm release and have direct access to the Auth Service. +Else, you should prefer connecting via the Proxy Service. + +This setting is mutually exclusive with teleportProxyAddress and is ignored if `customConfig` is set. + +For example: +```yaml +teleportAuthAddress: "teleport-auth.teleport-namespace.svc.cluster.local:3025" +``` + +## `defaultOutput` + +`defaultOutput` controls the default output configured for the tbot agent. +Ignored if `customConfig` is set. + +### `defaultOutput.enabled` + +| Type | Default | +|------|---------| +| `bool` | `true` | + +`defaultOutput.enabled` controls whether the default output is enabled. + +## `persistence` + +`persistence` controls how the tbot agent stores its data. + +Options: +- "secret": uses a Kubernetes Secret. +- "disabled": does not persist data. May impact ability to track bot + deployment across its lifetime. + +## `tbotConfig` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`tbotConfig` contains YAML teleport configuration to pass to the +tbot pods. The configuration will be merged with the chart-generated +configuration and will take precedence in case of conflict. Try to prefer to +use the more specific configuration values throughout this chart. + +## `outputs` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`outputs` contains additional outputs to configure for the tbot agent. +These should be in the same format as the `outputs` field in the tbot.yaml. +Ignored if `customConfig` is set. + +## `services` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`services` contains additional services to configure for the tbot agent. +These should be in the same format as the `services` field in the tbot.yaml. +Ignored if `customConfig` is set. + +## `joinMethod` + +| Type | Default | +|------|---------| +| `string` | `"kubernetes"` | + +`joinMethod` describes how tbot joins the Teleport cluster. +See [the join method reference](../../join-methods.mdx) for a list fo supported values and detailed explanations. +Ignored if `customConfig` is set. + +## `token` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`token` is the name of the token used by tbot to join the Teleport cluster. +This value is not sensitive unless the `joinMethod` is set to `"token"`. +Ignored if `customConfig` is set. + +## `teleportVersionOverride` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`teleportVersionOverride` controls the tbot image version deployed by +the chart. + +Normally, the version of tbot matches the version of the chart. If you install +chart version 15.0.0, you'll use tbot version 15.0.0. Upgrading tbot is done +by upgrading the chart. + + +`teleportVersionOverride` is intended for development and MUST NOT be +used to control the Teleport version in a typical deployment. This +chart is designed to run a specific Teleport version. You will face +compatibility issues trying to run a different Teleport version with it. + +If you want to run Teleport version `X.Y.Z`, you should use +`helm install --version X.Y.Z` instead. + + + +## `anonymousTelemetry` + +| Type | Default | +|------|---------| +| `bool` | `false` | + +`anonymousTelemetry` controls whether anonymous telemetry is enabled. + +## `debug` + +| Type | Default | +|------|---------| +| `bool` | `false` | + +`debug` controls whether the tbot agent runs in debug mode. + +## `serviceAccount` + +`serviceAccount` controls the Kubernetes ServiceAccounts deployed and used by +the chart. + +### `serviceAccount.create` + +| Type | Default | +|------|---------| +| `bool` | `true` | + +`serviceAccount.create` controls whether Helm Chart creates the +Kubernetes `ServiceAccount` resources for the agent. +When off, you are responsible for creating the appropriate ServiceAccount +resources. + +### `serviceAccount.name` + +| Type | Default | +|------|---------| +| `string` | `""` | + +`serviceAccount.name` sets the name of the `ServiceAccount` resource +used by the chart. By default, the `ServiceAccount` has the name of the +Helm release. + +## `imagePullPolicy` + +| Type | Default | +|------|---------| +| `string` | `"IfNotPresent"` | + +`imagePullPolicy` sets the pull policy for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/#updating-images) +for more details. + +## `extraLabels` + +`extraLabels` contains additional Kubernetes labels to apply on the resources +created by the chart. +See [the Kubernetes label documentation +](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) +for more information. + +### `extraLabels.role` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.role` are labels to set on the Role. + +### `extraLabels.roleBinding` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.roleBinding` are labels to set on the RoleBinding. + +### `extraLabels.config` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.config` are labels to set on the ConfigMap. + +### `extraLabels.deployment` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.deployment` are labels to set on the Deployment or StatefulSet. + +### `extraLabels.pod` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.pod` are labels to set on the Pods created by the +Deployment or StatefulSet. + +### `extraLabels.serviceAccount` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`extraLabels.serviceAccount` are labels to set on the ServiceAccount. + +## `annotations` + +`annotations` contains annotations to apply to the different Kubernetes +objects created by the chart. See [the Kubernetes annotation +documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) +for more details. + +### `annotations.role` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.role` are annotations to set on the Role. + +### `annotations.roleBinding` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.roleBinding` are annotations to set on the RoleBinding. + +### `annotations.config` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.config` contains the Kubernetes annotations +put on the `ConfigMap` resource created by the chart. + +### `annotations.deployment` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.deployment` contains the Kubernetes annotations +put on the `Deployment` or `StatefulSet` resource created by the chart. + +### `annotations.pod` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.pod` contains the Kubernetes annotations +put on the `Pod` resources created by the chart. + +### `annotations.serviceAccount` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`annotations.serviceAccount` contains the Kubernetes annotations +put on the `ServiceAccount` resource created by the chart. + +## `resources` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`resources` sets the resource requests/limits for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) +for more details. + +## `affinity` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`affinity` sets the affinities for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) +for more details. + +## `tolerations` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`tolerations` sets the tolerations for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) +for more details. + +## `nodeSelector` + +| Type | Default | +|------|---------| +| `object` | `{}` | + +`nodeSelector` sets the node selector for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) +for more details. + +## `imagePullSecrets` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`imagePullSecrets` sets the image pull secrets for any pods created by the chart. +See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod) +for more details. + +## `extraVolumes` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`extraVolumes` contains extra volumes to mount into the Teleport pods. +See [the Kubernetes volume documentation](https://kubernetes.io/docs/concepts/storage/volumes/) +for more details. + +For example: +```yaml +extraVolumes: +- name: myvolume + secret: + secretName: testSecret +``` + +## `extraVolumeMounts` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`extraVolumeMounts` contains extra volumes mounts for the main Teleport container. +See [the Kubernetes volume documentation](https://kubernetes.io/docs/concepts/storage/volumes/) +for more details. + +For example: +```yaml +extraVolumesMounts: +- name: myvolume + mountPath: /path/on/host +``` + +## `extraArgs` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`extraArgs` contains extra arguments to pass to `tbot start` for +the main tbot pod + +## `extraEnv` + +| Type | Default | +|------|---------| +| `list` | `[]` | + +`extraEnv` contains extra environment variables to set in the main +tbot pod. + +For example: +```yaml +extraEnv: + - name: HTTPS_PROXY + value: "http://username:password@my.proxy.host:3128" +``` diff --git a/examples/chart/Makefile b/examples/chart/Makefile index 1e5157d4e5ca0..e48ee95f70a1c 100644 --- a/examples/chart/Makefile +++ b/examples/chart/Makefile @@ -7,7 +7,7 @@ check_access = $(addprefix check-chart-ref-access-,$(access)) render_access = $(addprefix render-chart-ref-access-,$(access)) .PHONY: render-chart-ref -render-chart-ref: render-chart-ref-example render-chart-ref-teleport-operator render-chart-ref-teleport-kube-agent $(render_access) # render-chart-ref-teleport-cluster +render-chart-ref: render-chart-ref-example render-chart-ref-teleport-operator render-chart-ref-teleport-kube-agent render-chart-ref-tbot $(render_access) # render-chart-ref-teleport-cluster .PHONY: render-chart-ref-example render-chart-ref-example: @@ -30,13 +30,18 @@ render-chart-ref-teleport-operator: cd ../../build.assets/tooling && \ go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-cluster/charts/teleport-operator -output ../../docs/pages/includes/helm-reference/zz_generated.teleport-operator.mdx +.PHONY: render-chart-ref-tbot +render-chart-ref-tbot: + cd ../../build.assets/tooling && \ + go run ./cmd/render-helm-ref -chart ../../examples/chart/tbot -output ../../docs/pages/includes/helm-reference/zz_generated.tbot.mdx + .PHONY: render-chart-ref-access-% render-chart-ref-access-%: cd ../../build.assets/tooling && \ go run ./cmd/render-helm-ref -chart ../../examples/chart/access/$* -output ../../docs/pages/includes/helm-reference/zz_generated.access-$*.mdx .PHONY: check-chart-ref -check-chart-ref: check-chart-ref-example check-chart-ref-teleport-operator check-chart-ref-teleport-kube-agent $(check_access) #check-chart-ref-teleport-cluster +check-chart-ref: check-chart-ref-example check-chart-ref-teleport-operator check-chart-ref-teleport-kube-agent check-chart-ref-tbot $(check_access) #check-chart-ref-teleport-cluster .PHONY: check-chart-ref-example check-chart-ref-example: @@ -66,6 +71,13 @@ check-chart-ref-teleport-operator: go run ./cmd/render-helm-ref -chart ../../examples/chart/teleport-cluster/charts/teleport-operator -output - | diff ../../docs/pages/includes/helm-reference/zz_generated.teleport-operator.mdx - || \ ( echo "Chart values.yaml and reference differ, please run 'make -C examples/chart render-chart-ref'" && exit 1 ) +.PHONY: check-chart-ref-tbot +check-chart-ref-tbot: + @echo "Checking tbot reference" + @ cd ../../build.assets/tooling && \ + go run ./cmd/render-helm-ref -chart ../../examples/chart/tbot -output - | diff ../../docs/pages/includes/helm-reference/zz_generated.tbot.mdx - || \ + ( echo "Chart values.yaml and reference differ, please run 'make render-chart-ref'" && exit 1 ) + .PHONY: check-chart-ref-access-% check-chart-ref-access-%: @echo "Checking access/$* reference" diff --git a/examples/chart/index.html b/examples/chart/index.html index 49d4a9a6a6103..39b8d7b9522c4 100644 --- a/examples/chart/index.html +++ b/examples/chart/index.html @@ -55,6 +55,17 @@

See our
+
tbot:
+      # Install the TBot chart to automatically configure a tbot agent to
+      # generate short-lived credentials for consumption by clients.
+      # Click the link above to see the README.
+
+      helm install ${RELEASE_NAME?} teleport/tbot \
+        --create-namespace \
+        --namespace ${NAMESPACE?} \
+        --set teleportProxyAddress="${TELEPORT_ADDR?}" \
+        --set token="${TELEPORT_TOKEN?}"
+

Changelog

See the Teleport Changelog for a list of important changes between Helm chart versions.
diff --git a/examples/chart/tbot/.lint/full.yaml b/examples/chart/tbot/.lint/full.yaml new file mode 100644 index 0000000000000..706b3d207ee5c --- /dev/null +++ b/examples/chart/tbot/.lint/full.yaml @@ -0,0 +1,100 @@ +clusterName: "test.teleport.sh" +teleportAuthAddress: "my-auth:3024" +defaultOutput: + enabled: false +token: "my-token" +joinMethod: "modified-join-method" + +serviceAccount: + name: "modified-sa-name" + +anonymousTelemetry: true +debug: true + +outputs: + - type: "application" + app_name: "foo" + destination: + type: "directory" + path: "/bar" + +services: + - type: "example-service" + param: boo + +imagePullPolicy: "Always" + +persistence: "disabled" + +extraLabels: + role: + test-key: test-label-role + roleBinding: + test-key: test-label-role-binding + config: + test-key: test-label-config + deployment: + test-key: test-label-deployment + pod: + test-key: test-label-pod + serviceAccount: + test-key: test-label-service-account + +annotations: + role: + test-key: test-annotation-role + roleBinding: + test-key: test-annotation-role-binding + config: + test-key: test-annotation-config + deployment: + test-key: test-annotation-deployment + pod: + test-key: test-annotation-pod + serviceAccount: + test-key: test-annotation-service-account + +resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + +tolerations: + - key: "key1" + operator: "Exists" + effect: "NoSchedule" + +nodeSelector: + test-key: test-node-selector + +imagePullSecrets: + - name: test-pull-secret + +extraVolumes: + - name: test-volume + emptyDir: {} + +extraVolumeMounts: + - name: test-volume + mountPath: /test/path + +extraArgs: + - --extra-arg + +extraEnv: + - name: "TEST_ENV" + value: "test-value" diff --git a/examples/chart/tbot/.lint/simple.yaml b/examples/chart/tbot/.lint/simple.yaml new file mode 100644 index 0000000000000..4dd982e168097 --- /dev/null +++ b/examples/chart/tbot/.lint/simple.yaml @@ -0,0 +1,5 @@ +clusterName: "test.teleport.sh" +teleportProxyAddress: "test.teleport.sh:443" +defaultOutput: + secretName: "test-output" +token: "my-token" diff --git a/examples/chart/tbot/Chart.yaml b/examples/chart/tbot/Chart.yaml new file mode 100644 index 0000000000000..5371135557a01 --- /dev/null +++ b/examples/chart/tbot/Chart.yaml @@ -0,0 +1,10 @@ +.version: &version "17.0.0-dev" + +name: tbot +apiVersion: v2 +version: *version +appVersion: *version +description: This chart deploys an instance of the Machine ID agent, TBot, into your Kubernetes cluster. This allows workloads running within Kubernetes to authenticate to your Teleport cluster. +icon: https://goteleport.com/static/teleport-symbol-bimi.svg +keywords: + - Teleport diff --git a/examples/chart/tbot/README.md b/examples/chart/tbot/README.md new file mode 100644 index 0000000000000..c775de6784830 --- /dev/null +++ b/examples/chart/tbot/README.md @@ -0,0 +1,42 @@ +# TBot Chart + +This chart deploys an instance of the Machine ID agent, TBot, into your +Kubernetes cluster. + +To use it, you will need to know: + +- The address of your Teleport Proxy Service or Auth Service +- The name of your Teleport cluster +- The name of a join token configured for Machine ID and your Kubernetes cluster + (https://goteleport.com/docs/enroll-resources/machine-id/deployment/kubernetes/) + +By default, this chart is designed to use the `kubernetes` join method but it +can be customised to use any delegated join method. We do not recommend that +you use the `token` join method with this chart. + +## How To + +### Basic configuration + +This basic configuration will write a Teleport identity file to a secret in +the deployment namespace called `test-output`. + +```yaml +clusterName: "test.teleport.sh" +teleportProxyAddress: "test.teleport.sh:443" +defaultOutput: + secretName: "test-output" +token: "my-token" +``` + +### Customization + +When customizing the configuration of `tbot` using this chart, you can either +choose to leverage the more granular values or use the `tbotConfig` value +to inject custom configuration into any field. We recommend using the granular +values where possible to better benefit from changes we may introduce in future +updates. + +## Contributing to the chart + +Please read [CONTRIBUTING.md](../CONTRIBUTING.md) before raising a pull request to this chart. \ No newline at end of file diff --git a/examples/chart/tbot/templates/_config.tpl b/examples/chart/tbot/templates/_config.tpl new file mode 100644 index 0000000000000..344b25e403fc5 --- /dev/null +++ b/examples/chart/tbot/templates/_config.tpl @@ -0,0 +1,49 @@ +{{ if not (or .Values.teleportAuthAddress .Values.teleportProxyAddress) }} + {{- $_ := required "`teleportAuthAddress` or `teleportProxyAddress` must be provided" "" }} +{{ end }} +{{ if not .Values.clusterName }} + {{- $_ := required "`clusterName` must be provided" "" }} +{{ end }} +{{ if not .Values.token }} + {{- $_ := required "`token` must be provided" "" }} +{{ end }} +{{ if (and .Values.teleportAuthAddress .Values.teleportProxyAddress) }} + {{- $_ := required "`teleportAuthAddress` and `teleportProxyAddress` are mutually exclusive" "" }} +{{ end }} +{{- define "tbot.config" -}} +version: v2 +{{- if .Values.teleportProxyAddress }} +proxy_server: {{ .Values.teleportProxyAddress }} +{{- end }} +{{- if .Values.teleportAuthAddress }} +auth_server: {{ .Values.teleportAuthAddress }} +{{- end }} +onboarding: + join_method: {{ .Values.joinMethod }} + token: {{ .Values.token }} +{{- if eq .Values.persistence "disabled" }} +storage: + type: memory +{{- else if eq .Values.persistence "secret" }} +storage: + type: kubernetes_secret + name: {{ include "tbot.fullname" . }} +{{- else }} + {{- required "'persistence' must be 'secret' or 'disabled'" "" }} +{{- end }} +{{- if or (.Values.defaultOutput.enabled) (.Values.outputs) }} +outputs: +{{- if .Values.defaultOutput.enabled }} + - type: identity + destination: + type: kubernetes_secret + name: {{ include "tbot.defaultOutputName" . }} +{{- end }} +{{- if .Values.outputs }} +{{- toYaml .Values.outputs | nindent 6}} +{{- end }} +{{- end }} +{{- if .Values.services }} +services: {{- toYaml .Values.services | nindent 6}} +{{- end }} +{{- end -}} diff --git a/examples/chart/tbot/templates/_helpers.tpl b/examples/chart/tbot/templates/_helpers.tpl new file mode 100644 index 0000000000000..259245358b2c5 --- /dev/null +++ b/examples/chart/tbot/templates/_helpers.tpl @@ -0,0 +1,56 @@ +{{- define "tbot.serviceAccountName" -}} +{{- coalesce .Values.serviceAccount.name (include "tbot.fullname" .) -}} +{{- end -}} + +{{- define "tbot.selectorLabels" -}} +app.kubernetes.io/name: '{{ include "tbot.name" . }}' +app.kubernetes.io/instance: '{{ .Release.Name }}' +app.kubernetes.io/component: 'tbot' +{{- end -}} + +{{- define "tbot.labels" -}} +{{ include "tbot.selectorLabels" . }} +helm.sh/chart: '{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}' +app.kubernetes.io/managed-by: '{{ .Release.Service }}' +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "tbot.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +This is a modified version of the default fully qualified app name helper. +We diverge by always honouring "nameOverride" when it's set, as opposed to the +default behaviour of shortening if `nameOverride` is included in chart name. +This is done to avoid naming conflicts when including the chart in other charts. +*/}} +{{- define "tbot.fullname" -}} + {{- if .Values.fullnameOverride }} + {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} + {{- else }} + {{- if .Values.nameOverride }} + {{- printf "%s-%s" .Release.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} + {{- else }} + {{- if contains .Chart.Name .Release.Name }} + {{- .Release.Name | trunc 63 | trimSuffix "-" }} + {{- else }} + {{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "tbot.version" -}} +{{- if .Values.teleportVersionOverride -}} + {{- .Values.teleportVersionOverride -}} +{{- else -}} + {{- .Chart.Version -}} +{{- end -}} +{{- end -}} + +{{- define "tbot.defaultOutputName" -}} +{{- include "tbot.fullname" . }}-out +{{- end -}} diff --git a/examples/chart/tbot/templates/config.yaml b/examples/chart/tbot/templates/config.yaml new file mode 100644 index 0000000000000..cc82c8eb4c48a --- /dev/null +++ b/examples/chart/tbot/templates/config.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "tbot.fullname" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.annotations.config }} + annotations: {{- toYaml .Values.annotations.config | nindent 8 }} +{{- end }} +{{- if .Values.extraLabels.config }} + labels: {{- toYaml .Values.extraLabels.config | nindent 8 }} +{{- end }} +data: + tbot.yaml: | + {{- mustMergeOverwrite (include "tbot.config" . | fromYaml) .Values.tbotConfig | toYaml | nindent 4 -}} diff --git a/examples/chart/tbot/templates/deployment.yaml b/examples/chart/tbot/templates/deployment.yaml new file mode 100644 index 0000000000000..8246f62deb566 --- /dev/null +++ b/examples/chart/tbot/templates/deployment.yaml @@ -0,0 +1,141 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "tbot.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ .Release.Name }} + {{- if .Values.extraLabels.deployment }} + {{- toYaml .Values.extraLabels.deployment | nindent 4 }} + {{- end }} + {{- if .Values.annotations.deployment }} + annotations: {{- toYaml .Values.annotations.deployment | nindent 4 }} + {{- end }} +spec: + # Replicas are set to 1 until we establish a locking mechanism for the + # `kubernetes_secret` destination. + replicas: 1 + strategy: + # Recreate strategy until we establish a locking mechanism for the + # `kubernetes_secret` destination. + type: Recreate + selector: + matchLabels: {{- include "tbot.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + # ConfigMap checksum, to recreate the pod on config changes. + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + {{- if .Values.annotations.pod }} + {{- toYaml .Values.annotations.pod | nindent 8 }} + {{- end }} + labels: + {{- include "tbot.labels" . | nindent 8 }} + {{- if .Values.extraLabels.pod }} + {{- toYaml .Values.extraLabels.pod | nindent 8 }} + {{- end }} + spec: + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{- toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- toYaml .Values.affinity | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- toYaml .Values.tolerations | nindent 8 }} + {{- end }} + containers: + - name: tbot + image: {{ .Values.image }}:{{ template "tbot.version" . }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + args: + - start + - -c + - /config/tbot.yaml + {{- if .Values.debug }} + - --debug + {{- end }} + - --log-format + - json + {{- if .Values.extraArgs }} + {{- toYaml .Values.extraArgs | nindent 12 }} + {{- end }} + - --diag-addr + - 0.0.0.0:3001 + env: + # POD_NAMESPACE is required for the kubernetes_secret` destination + # type to work correctly. + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # TELEPORT_NODE_NAME is required for Workload Identity Kubernetes + # Workload Attestation to work correctly. + - name: TELEPORT_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # KUBERNETES_TOKEN_PATH specifies the path to the service account + # JWT to use for joining. + # This path is based on the configuration of the volume and + # volumeMount. + - name: KUBERNETES_TOKEN_PATH + value: /var/run/secrets/tokens/join-sa-token + {{- if .Values.anonymousTelemetry }} + - name: TELEPORT_ANONYMOUS_TELEMETRY + value: "1" + {{- end }} + {{- if .Values.extraEnv }} + {{- toYaml .Values.extraEnv | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /config + name: config + - mountPath: /var/run/secrets/tokens + name: join-sa-token + {{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + ports: + - containerPort: 3001 + name: diagnostics + protocol: TCP + livenessProbe: + httpGet: + path: /livez + port: diagnostics + initialDelaySeconds: 10 # After an initial 10 seconds + periodSeconds: 10 # Check every 10 seconds + failureThreshold: 6 # After 60 (6x10) seconds of failure, kill pod + timeoutSeconds: 5 # Wait 5 seconds for the probe to complete + readinessProbe: + httpGet: + path: /readyz + port: diagnostics + initialDelaySeconds: 5 # After an initial 5 seconds + periodSeconds: 10 # Check every 10 seconds + failureThreshold: 3 # After 30 (3x10) seconds of failure, mark pod unready + timeoutSeconds: 5 # Wait 5 seconds for the probe to complete + serviceAccountName: {{ template "tbot.serviceAccountName" . }} + volumes: + - name: config + configMap: + name: {{ include "tbot.fullname" . }} + - name: join-sa-token + projected: + sources: + - serviceAccountToken: + path: join-sa-token + # 600 seconds is the minimum that Kubernetes supports. We + # recommend this value is used. + expirationSeconds: 600 + audience: {{ .Values.clusterName }} + {{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/examples/chart/tbot/templates/role.yaml b/examples/chart/tbot/templates/role.yaml new file mode 100644 index 0000000000000..1d0e9aa88fb21 --- /dev/null +++ b/examples/chart/tbot/templates/role.yaml @@ -0,0 +1,20 @@ +# This role grants the ability to manage secrets within the namespace - this is +# necessary for the `kubernetes_secret` destination to work correctly. +{{ if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "tbot.fullname" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.extraLabels.role }} + labels: + {{- toYaml .Values.extraLabels.role | nindent 4 }} +{{- end }} +{{- if .Values.annotations.role }} + annotations: {{- toYaml .Values.annotations.role | nindent 4 }} +{{- end}} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["*"] +{{ end }} \ No newline at end of file diff --git a/examples/chart/tbot/templates/rolebinding.yaml b/examples/chart/tbot/templates/rolebinding.yaml new file mode 100644 index 0000000000000..754010ed7d982 --- /dev/null +++ b/examples/chart/tbot/templates/rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.serviceAccount.create -}} +# Bind the role to the service account created for tbot. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "tbot.fullname" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.extraLabels.roleBinding }} + labels: + {{- toYaml .Values.extraLabels.roleBinding | nindent 4 }} +{{- end }} +{{- if .Values.annotations.roleBinding }} + annotations: {{- toYaml .Values.annotations.roleBinding | nindent 4 }} +{{- end}} +subjects: +- kind: ServiceAccount + name: {{ template "tbot.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ include "tbot.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{ end }} \ No newline at end of file diff --git a/examples/chart/tbot/templates/serviceaccount.yaml b/examples/chart/tbot/templates/serviceaccount.yaml new file mode 100644 index 0000000000000..343c5f5f46e70 --- /dev/null +++ b/examples/chart/tbot/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "tbot.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.extraLabels.serviceAccount }} + labels: + {{- toYaml .Values.extraLabels.serviceAccount | nindent 4 }} +{{- end }} +{{- if .Values.annotations.serviceAccount }} + annotations: +{{- toYaml .Values.annotations.serviceAccount | nindent 4 }} +{{- end -}} +{{ end }} diff --git a/examples/chart/tbot/tests/__snapshot__/config_test.yaml.snap b/examples/chart/tbot/tests/__snapshot__/config_test.yaml.snap new file mode 100644 index 0000000000000..a1e58c58b4643 --- /dev/null +++ b/examples/chart/tbot/tests/__snapshot__/config_test.yaml.snap @@ -0,0 +1,78 @@ +it should match the snapshot (custom): + 1: | + apiVersion: v1 + data: + tbot.yaml: |- + onboarding: + join_method: kubernetes + token: foo + outputs: + - destination: + path: /fuzz + type: magic + type: bar + - destination: + path: /buzz + type: magic + type: bar + storage: + name: RELEASE-NAME-tbot + type: kubernetes_secret + version: v2 + xyzzy: foo + yxzyy: 17 + kind: ConfigMap + metadata: + name: RELEASE-NAME-tbot + namespace: NAMESPACE +should match the snapshot (full): + 1: | + apiVersion: v1 + data: + tbot.yaml: |- + auth_server: my-auth:3024 + onboarding: + join_method: modified-join-method + token: my-token + outputs: + - app_name: foo + destination: + path: /bar + type: directory + type: application + services: + - param: boo + type: example-service + storage: + type: memory + version: v2 + kind: ConfigMap + metadata: + annotations: + test-key: test-annotation-config + labels: + test-key: test-label-config + name: RELEASE-NAME-tbot + namespace: NAMESPACE +should match the snapshot (simple): + 1: | + apiVersion: v1 + data: + tbot.yaml: |- + onboarding: + join_method: kubernetes + token: my-token + outputs: + - destination: + name: RELEASE-NAME-tbot-out + type: kubernetes_secret + type: identity + proxy_server: test.teleport.sh:443 + storage: + name: RELEASE-NAME-tbot + type: kubernetes_secret + version: v2 + kind: ConfigMap + metadata: + name: RELEASE-NAME-tbot + namespace: NAMESPACE diff --git a/examples/chart/tbot/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/tbot/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..d615816877e63 --- /dev/null +++ b/examples/chart/tbot/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,218 @@ +should match the snapshot (full): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + annotations: + test-key: test-annotation-deployment + labels: + app.kubernetes.io/name: RELEASE-NAME + test-key: test-label-deployment + name: RELEASE-NAME-tbot + namespace: NAMESPACE + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: tbot + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: tbot + strategy: + type: Recreate + template: + metadata: + annotations: + checksum/config: 094cdbfc4e4fe3824a33426d8eea4e9e8a4b2711823d4fbb4102e11caa7f62c0 + test-key: test-annotation-pod + labels: + app.kubernetes.io/component: tbot + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tbot + helm.sh/chart: tbot-17.0.0-dev + test-key: test-label-pod + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: topology.kubernetes.io/zone + operator: In + values: + - antarctica-east1 + - antarctica-west1 + containers: + - args: + - start + - -c + - /config/tbot.yaml + - --debug + - --log-format + - json + - --extra-arg + - --diag-addr + - 0.0.0.0:3001 + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: TELEPORT_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: KUBERNETES_TOKEN_PATH + value: /var/run/secrets/tokens/join-sa-token + - name: TELEPORT_ANONYMOUS_TELEMETRY + value: "1" + - name: TEST_ENV + value: test-value + image: public.ecr.aws/gravitational/tbot-distroless:17.0.0-dev + imagePullPolicy: Always + livenessProbe: + failureThreshold: 6 + httpGet: + path: /livez + port: diagnostics + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + name: tbot + ports: + - containerPort: 3001 + name: diagnostics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: diagnostics + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 250m + memory: 64Mi + volumeMounts: + - mountPath: /config + name: config + - mountPath: /var/run/secrets/tokens + name: join-sa-token + - mountPath: /test/path + name: test-volume + imagePullSecrets: + - name: test-pull-secret + nodeSelector: + test-key: test-node-selector + serviceAccountName: modified-sa-name + tolerations: + - effect: NoSchedule + key: key1 + operator: Exists + volumes: + - configMap: + name: RELEASE-NAME-tbot + name: config + - name: join-sa-token + projected: + sources: + - serviceAccountToken: + audience: test.teleport.sh + expirationSeconds: 600 + path: join-sa-token + - emptyDir: {} + name: test-volume +should match the snapshot (simple): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/name: RELEASE-NAME + name: RELEASE-NAME-tbot + namespace: NAMESPACE + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: tbot + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: tbot + strategy: + type: Recreate + template: + metadata: + annotations: + checksum/config: 6734638a61b26526de2160a96d6e83a47f6d5c05195d12fa8f354ac90f153d36 + labels: + app.kubernetes.io/component: tbot + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: tbot + helm.sh/chart: tbot-17.0.0-dev + spec: + containers: + - args: + - start + - -c + - /config/tbot.yaml + - --log-format + - json + - --diag-addr + - 0.0.0.0:3001 + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: TELEPORT_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: KUBERNETES_TOKEN_PATH + value: /var/run/secrets/tokens/join-sa-token + image: public.ecr.aws/gravitational/tbot-distroless:17.0.0-dev + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 6 + httpGet: + path: /livez + port: diagnostics + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + name: tbot + ports: + - containerPort: 3001 + name: diagnostics + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + path: /readyz + port: diagnostics + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + volumeMounts: + - mountPath: /config + name: config + - mountPath: /var/run/secrets/tokens + name: join-sa-token + serviceAccountName: RELEASE-NAME-tbot + volumes: + - configMap: + name: RELEASE-NAME-tbot + name: config + - name: join-sa-token + projected: + sources: + - serviceAccountToken: + audience: test.teleport.sh + expirationSeconds: 600 + path: join-sa-token diff --git a/examples/chart/tbot/tests/__snapshot__/role_test.yaml.snap b/examples/chart/tbot/tests/__snapshot__/role_test.yaml.snap new file mode 100644 index 0000000000000..5409810c07569 --- /dev/null +++ b/examples/chart/tbot/tests/__snapshot__/role_test.yaml.snap @@ -0,0 +1,32 @@ +should match the snapshot (full): + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + annotations: + test-key: test-annotation-role + labels: + test-key: test-label-role + name: RELEASE-NAME-tbot + namespace: NAMESPACE + rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - '*' +should match the snapshot (simple): + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: RELEASE-NAME-tbot + namespace: NAMESPACE + rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - '*' diff --git a/examples/chart/tbot/tests/__snapshot__/rolebinding_test.yaml.snap b/examples/chart/tbot/tests/__snapshot__/rolebinding_test.yaml.snap new file mode 100644 index 0000000000000..20fa3affa5468 --- /dev/null +++ b/examples/chart/tbot/tests/__snapshot__/rolebinding_test.yaml.snap @@ -0,0 +1,34 @@ +should match the snapshot (full): + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + annotations: + test-key: test-annotation-role-binding + labels: + test-key: test-label-role-binding + name: RELEASE-NAME-tbot + namespace: NAMESPACE + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: RELEASE-NAME-tbot + subjects: + - kind: ServiceAccount + name: modified-sa-name + namespace: NAMESPACE +should match the snapshot (simple): + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: RELEASE-NAME-tbot + namespace: NAMESPACE + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: RELEASE-NAME-tbot + subjects: + - kind: ServiceAccount + name: RELEASE-NAME-tbot + namespace: NAMESPACE diff --git a/examples/chart/tbot/tests/__snapshot__/serviceaccount_test.yaml.snap b/examples/chart/tbot/tests/__snapshot__/serviceaccount_test.yaml.snap new file mode 100644 index 0000000000000..2129222f9815d --- /dev/null +++ b/examples/chart/tbot/tests/__snapshot__/serviceaccount_test.yaml.snap @@ -0,0 +1,18 @@ +should match the snapshot (full): + 1: | + apiVersion: v1 + kind: ServiceAccount + metadata: + annotations: + test-key: test-annotation-service-account + labels: + test-key: test-label-service-account + name: modified-sa-name + namespace: NAMESPACE +should match the snapshot (simple): + 1: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: RELEASE-NAME-tbot + namespace: NAMESPACE diff --git a/examples/chart/tbot/tests/config_test.yaml b/examples/chart/tbot/tests/config_test.yaml new file mode 100644 index 0000000000000..6db9a736bf1bc --- /dev/null +++ b/examples/chart/tbot/tests/config_test.yaml @@ -0,0 +1,31 @@ +suite: Test ConfigMap +templates: + - config.yaml +tests: + - it: should match the snapshot (simple) + values: + - ../.lint/simple.yaml + asserts: + - matchSnapshot: {} + - it: should match the snapshot (full) + values: + - ../.lint/full.yaml + asserts: + - matchSnapshot: {} + - it: it should match the snapshot (custom) + set: + token: foo + tbotConfig: + xyzzy: foo + yxzyy: 17 + outputs: + - type: bar + destination: + type: magic + path: /fuzz + - type: bar + destination: + type: magic + path: /buzz + asserts: + - matchSnapshot: {} diff --git a/examples/chart/tbot/tests/deployment_test.yaml b/examples/chart/tbot/tests/deployment_test.yaml new file mode 100644 index 0000000000000..fd69bbc640093 --- /dev/null +++ b/examples/chart/tbot/tests/deployment_test.yaml @@ -0,0 +1,17 @@ +suite: Test Deployment +templates: + - deployment.yaml + - config.yaml +tests: + - it: should match the snapshot (simple) + template: deployment.yaml + values: + - ../.lint/simple.yaml + asserts: + - matchSnapshot: {} + - it: should match the snapshot (full) + template: deployment.yaml + values: + - ../.lint/full.yaml + asserts: + - matchSnapshot: {} \ No newline at end of file diff --git a/examples/chart/tbot/tests/role_test.yaml b/examples/chart/tbot/tests/role_test.yaml new file mode 100644 index 0000000000000..63d006e7c957f --- /dev/null +++ b/examples/chart/tbot/tests/role_test.yaml @@ -0,0 +1,20 @@ +suite: Test Role +templates: + - role.yaml +tests: + - it: should match the snapshot (simple) + values: + - ../.lint/simple.yaml + asserts: + - matchSnapshot: {} + - it: should match the snapshot (full) + values: + - ../.lint/full.yaml + asserts: + - matchSnapshot: {} + - it: skips creation when service account disabled + set: + serviceAccount.create: false + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/examples/chart/tbot/tests/rolebinding_test.yaml b/examples/chart/tbot/tests/rolebinding_test.yaml new file mode 100644 index 0000000000000..55591db125afa --- /dev/null +++ b/examples/chart/tbot/tests/rolebinding_test.yaml @@ -0,0 +1,20 @@ +suite: Test RoleBinding +templates: + - rolebinding.yaml +tests: + - it: should match the snapshot (simple) + values: + - ../.lint/simple.yaml + asserts: + - matchSnapshot: {} + - it: should match the snapshot (full) + values: + - ../.lint/full.yaml + asserts: + - matchSnapshot: {} + - it: skips creation when service account disabled + set: + serviceAccount.create: false + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/examples/chart/tbot/tests/serviceaccount_test.yaml b/examples/chart/tbot/tests/serviceaccount_test.yaml new file mode 100644 index 0000000000000..dafcaf6e9a319 --- /dev/null +++ b/examples/chart/tbot/tests/serviceaccount_test.yaml @@ -0,0 +1,20 @@ +suite: Test ServiceAccount +templates: + - serviceaccount.yaml +tests: + - it: should match the snapshot (simple) + values: + - ../.lint/simple.yaml + asserts: + - matchSnapshot: {} + - it: should match the snapshot (full) + values: + - ../.lint/full.yaml + asserts: + - matchSnapshot: {} + - it: skips creation when service account disabled + set: + serviceAccount.create: false + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/examples/chart/tbot/values.yaml b/examples/chart/tbot/values.yaml new file mode 100644 index 0000000000000..680fda9d1a7fb --- /dev/null +++ b/examples/chart/tbot/values.yaml @@ -0,0 +1,229 @@ +# image(string) -- sets the container image used for tbot pods created by this +# chart. +# +# You can override this to use your own tbot image rather than a +# Teleport-published image. +image: public.ecr.aws/gravitational/tbot-distroless +# clusterName(string) -- should be the name of the Teleport cluster that your +# Bot will join. You can retrieve it by running `tctl status`. +# +# For example: `clusterName: "test.teleport.sh"` +clusterName: "" + +nameOverride: "" +fullnameOverride: "" + +# teleportProxyAddress(string) -- is the teleport Proxy Service address the bot will connect to. +# This must contain the port number, usually 443 or 3080 for Proxy Service. +# Connecting to the Proxy Service is the most common and recommended way to connect to Teleport. +# This is mandatory to connect to Teleport Enterprise (Cloud) +# +# This setting is mutually exclusive with teleportProxyAddress and is ignored if `customConfig` is set. +# +# For example: +# ```yaml +# teleportProxyAddress: "test.teleport.sh:443" +# ``` +teleportProxyAddress: "" +# teleportAuthAddress(string) -- is the teleport Auth Service address the bot will connect to. +# This must contain the port number, usually 3025 for Auth Service. Direct Auth Service connection +# should be used when you are deploying the bot in the same Kubernetes cluster than your `teleport-cluster` +# Helm release and have direct access to the Auth Service. +# Else, you should prefer connecting via the Proxy Service. +# +# This setting is mutually exclusive with teleportProxyAddress and is ignored if `customConfig` is set. +# +# For example: +# ```yaml +# teleportAuthAddress: "teleport-auth.teleport-namespace.svc.cluster.local:3025" +# ``` +teleportAuthAddress: "" + +# defaultOutput -- controls the default output configured for the tbot agent. +# Ignored if `customConfig` is set. +defaultOutput: + # defaultOutput.enabled(bool) -- controls whether the default output is enabled. + enabled: true + +# persistence -- controls how the tbot agent stores its data. +# +# Options: +# - "secret": uses a Kubernetes Secret. +# - "disabled": does not persist data. May impact ability to track bot +# deployment across its lifetime. +persistence: "secret" + +# tbotConfig(object) -- contains YAML teleport configuration to pass to the +# tbot pods. The configuration will be merged with the chart-generated +# configuration and will take precedence in case of conflict. Try to prefer to +# use the more specific configuration values throughout this chart. +tbotConfig: {} + +# outputs(list) -- contains additional outputs to configure for the tbot agent. +# These should be in the same format as the `outputs` field in the tbot.yaml. +# Ignored if `customConfig` is set. +outputs: [] + +# services(list) -- contains additional services to configure for the tbot agent. +# These should be in the same format as the `services` field in the tbot.yaml. +# Ignored if `customConfig` is set. +services: [] + +# joinMethod(string) -- describes how tbot joins the Teleport cluster. +# See [the join method reference](../../join-methods.mdx) for a list fo supported values and detailed explanations. +# Ignored if `customConfig` is set. +joinMethod: "kubernetes" + +# token(string) -- is the name of the token used by tbot to join the Teleport cluster. +# This value is not sensitive unless the `joinMethod` is set to `"token"`. +# Ignored if `customConfig` is set. +token: "" + +# teleportVersionOverride(string) -- controls the tbot image version deployed by +# the chart. +# +# Normally, the version of tbot matches the version of the chart. If you install +# chart version 15.0.0, you'll use tbot version 15.0.0. Upgrading tbot is done +# by upgrading the chart. +# +# +# `teleportVersionOverride` is intended for development and MUST NOT be +# used to control the Teleport version in a typical deployment. This +# chart is designed to run a specific Teleport version. You will face +# compatibility issues trying to run a different Teleport version with it. +# +# If you want to run Teleport version `X.Y.Z`, you should use +# `helm install --version X.Y.Z` instead. +# +# +teleportVersionOverride: "" + +# anonymousTelemetry(bool) -- controls whether anonymous telemetry is enabled. +anonymousTelemetry: false +# debug(bool) -- controls whether the tbot agent runs in debug mode. +debug: false + +# serviceAccount -- controls the Kubernetes ServiceAccounts deployed and used by +# the chart. +serviceAccount: + # serviceAccount.create(bool) -- controls whether Helm Chart creates the + # Kubernetes `ServiceAccount` resources for the agent. + # When off, you are responsible for creating the appropriate ServiceAccount + # resources. + create: true + # serviceAccount.name(string) -- sets the name of the `ServiceAccount` resource + # used by the chart. By default, the `ServiceAccount` has the name of the + # Helm release. + name: "" + +# imagePullPolicy(string) -- sets the pull policy for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/#updating-images) +# for more details. +imagePullPolicy: IfNotPresent + +# extraLabels -- contains additional Kubernetes labels to apply on the resources +# created by the chart. +# See [the Kubernetes label documentation +# ](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) +# for more information. +extraLabels: + # extraLabels.role(object) -- are labels to set on the Role. + role: {} + # extraLabels.roleBinding(object) -- are labels to set on the RoleBinding. + roleBinding: {} + # extraLabels.config(object) -- are labels to set on the ConfigMap. + config: {} + # extraLabels.deployment(object) -- are labels to set on the Deployment or StatefulSet. + deployment: {} + # extraLabels.pod(object) -- are labels to set on the Pods created by the + # Deployment or StatefulSet. + pod: {} + # extraLabels.serviceAccount(object) -- are labels to set on the ServiceAccount. + serviceAccount: {} + +# annotations -- contains annotations to apply to the different Kubernetes +# objects created by the chart. See [the Kubernetes annotation +# documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) +# for more details. +annotations: + # annotations.role(object) -- are annotations to set on the Role. + role: {} + # annotations.roleBinding(object) -- are annotations to set on the RoleBinding. + roleBinding: {} + # annotations.config(object) -- contains the Kubernetes annotations + # put on the `ConfigMap` resource created by the chart. + config: {} + # annotations.deployment(object) -- contains the Kubernetes annotations + # put on the `Deployment` or `StatefulSet` resource created by the chart. + deployment: {} + # annotations.pod(object) -- contains the Kubernetes annotations + # put on the `Pod` resources created by the chart. + pod: {} + # annotations.serviceAccount(object) -- contains the Kubernetes annotations + # put on the `ServiceAccount` resource created by the chart. + serviceAccount: {} + +# resources(object) -- sets the resource requests/limits for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) +# for more details. +resources: {} + +# affinity(object) -- sets the affinities for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) +# for more details. +affinity: {} + +# tolerations(list) -- sets the tolerations for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) +# for more details. +tolerations: [] + +# nodeSelector(object) -- sets the node selector for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) +# for more details. +nodeSelector: {} + +# imagePullSecrets(list) -- sets the image pull secrets for any pods created by the chart. +# See [the Kubernetes documentation](https://kubernetes.io/docs/concepts/containers/images/#referring-to-an-imagepullsecrets-on-a-pod) +# for more details. +imagePullSecrets: [] + +# extraVolumes(list) -- contains extra volumes to mount into the Teleport pods. +# See [the Kubernetes volume documentation](https://kubernetes.io/docs/concepts/storage/volumes/) +# for more details. +# +# For example: +# ```yaml +# extraVolumes: +# - name: myvolume +# secret: +# secretName: testSecret +# ``` +extraVolumes: [] + +# extraVolumeMounts(list) -- contains extra volumes mounts for the main Teleport container. +# See [the Kubernetes volume documentation](https://kubernetes.io/docs/concepts/storage/volumes/) +# for more details. +# +# For example: +# ```yaml +# extraVolumesMounts: +# - name: myvolume +# mountPath: /path/on/host +# ``` +extraVolumeMounts: [] + +# extraArgs(list) -- contains extra arguments to pass to `tbot start` for +# the main tbot pod +extraArgs: [] + +# extraEnv(list) -- contains extra environment variables to set in the main +# tbot pod. +# +# For example: +# ```yaml +# extraEnv: +# - name: HTTPS_PROXY +# value: "http://username:password@my.proxy.host:3128" +# ``` +extraEnv: [] \ No newline at end of file