diff --git a/Makefile b/Makefile index 6be5526804489..b05c3c89ec497 100644 --- a/Makefile +++ b/Makefile @@ -703,12 +703,16 @@ test-helm: helmunit/installed helm unittest -3 --with-subchart=false examples/chart/teleport-cluster helm unittest -3 examples/chart/teleport-kube-agent helm unittest -3 examples/chart/teleport-cluster/charts/teleport-operator + helm unittest -3 examples/chart/access/* + helm unittest -3 examples/chart/event-handler .PHONY: test-helm-update-snapshots test-helm-update-snapshots: helmunit/installed helm unittest -3 -u --with-subchart=false examples/chart/teleport-cluster helm unittest -3 -u examples/chart/teleport-kube-agent 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 # # Runs all Go tests except integration, called by CI/CD. diff --git a/examples/chart/access/discord/.helmignore b/examples/chart/access/discord/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/discord/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/discord/Chart.yaml b/examples/chart/access/discord/Chart.yaml new file mode 100644 index 0000000000000..3a8b4d9eb8d82 --- /dev/null +++ b/examples/chart/access/discord/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-discord +description: A Helm chart for the Teleport Discord Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/discord/README.md b/examples/chart/access/discord/README.md new file mode 100644 index 0000000000000..e8db8d0bb2996 --- /dev/null +++ b/examples/chart/access/discord/README.md @@ -0,0 +1,101 @@ +# Teleport Access Request Discord Plugin + +This chart sets up and configures a Deployment for the Access Request Discord plugin. + +## Installation + +See the [Access Requests with Discord guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-discord/) +which covers how to create the Discord bot and how to deploy the access plugin. + +## Settings + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"yes
discord.tokenDiscord API tokenstring""yes
discord.tokenFromSecretKubernetes secret to read the token from instead of discord.tokenstring""no
discord.tokenSecretPathThe path of the token in the secret described by discord.tokenFromSecretstring"discordToken"no
roleToRecipients + Mapping of roles to a list of Discord channel IDs.
+ Example: +
+"dev" = ["0987654321", "1234567890"]
+"*" = ["1234567890"]
+
map{}yes
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/discord.log" + string"stdout"no
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"no
diff --git a/examples/chart/access/discord/templates/_helpers.tpl b/examples/chart/access/discord/templates/_helpers.tpl new file mode 100644 index 0000000000000..7410b7167af27 --- /dev/null +++ b/examples/chart/access/discord/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "discord.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "discord.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "discord.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "discord.labels" -}} +helm.sh/chart: {{ include "discord.chart" . }} +{{ include "discord.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "discord.selectorLabels" -}} +app.kubernetes.io/name: {{ include "discord.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "discord.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "discord.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/discord/templates/configmap.yaml b/examples/chart/access/discord/templates/configmap.yaml new file mode 100644 index 0000000000000..9ca304c329688 --- /dev/null +++ b/examples/chart/access/discord/templates/configmap.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "discord.fullname" . }} + labels: + {{- include "discord.labels" . | nindent 4 }} +data: + teleport-discord.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/discord/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [discord] + token = "/var/lib/teleport/plugins/discord/discord-token" + + [role_to_recipients] + {{- range $role, $recipients := .Values.roleToRecipients }} + {{ $role | toJson }} = {{ $recipients | toJson }} + {{- end }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/discord/templates/deployment.yaml b/examples/chart/access/discord/templates/deployment.yaml new file mode 100644 index 0000000000000..953489e881754 --- /dev/null +++ b/examples/chart/access/discord/templates/deployment.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "discord.fullname" . }} + labels: + {{- include "discord.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "discord.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "discord.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-discord.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-discord.toml + subPath: teleport-discord.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/discord/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: /var/lib/teleport/plugins/discord/discord-token + subPath: {{ .Values.discord.tokenSecretPath }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "discord.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.discord.tokenFromSecret (printf "%s-secret" (include "discord.fullname" .)) }}" + defaultMode: 0600 diff --git a/examples/chart/access/discord/templates/secret.yaml b/examples/chart/access/discord/templates/secret.yaml new file mode 100644 index 0000000000000..8078aaed254cc --- /dev/null +++ b/examples/chart/access/discord/templates/secret.yaml @@ -0,0 +1,9 @@ +{{- if not .Values.discord.tokenFromSecret -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "discord.fullname" . }}-secret +data: + discordToken: {{ .Values.discord.token | b64enc }} +{{- end }} diff --git a/examples/chart/access/discord/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/discord/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..2994aa6b0c2aa --- /dev/null +++ b/examples/chart/access/discord/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,29 @@ +should match the snapshot: + 1: | + apiVersion: v1 + data: + teleport-discord.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/discord/teleport-identity/auth_id" + refresh_identity = true + + [discord] + token = "/var/lib/teleport/plugins/discord/discord-token" + + [role_to_recipients] + "*" = ["dev-access-requests"] + "dev" = ["dev-access-requests","example-user@example.com"] + + [log] + output = "/var/log/teleport-discord.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-discord + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-discord-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-discord diff --git a/examples/chart/access/discord/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/discord/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..eb5d3f238e097 --- /dev/null +++ b/examples/chart/access/discord/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,64 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-discord + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-discord-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-discord + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-discord + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-discord + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-discord-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-discord.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-discord + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-discord.toml + name: config + subPath: teleport-discord.toml + - mountPath: /var/lib/teleport/plugins/discord/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/discord/discord-token + name: password-file + subPath: discordToken + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-discord + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-discord-secret diff --git a/examples/chart/access/discord/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/discord/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..db5d15e095af3 --- /dev/null +++ b/examples/chart/access/discord/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should contain the api key: + 1: | + apiVersion: v1 + data: + discordToken: bXlkaXNjb3JkdG9rZW4= + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-discord-secret + type: Opaque diff --git a/examples/chart/access/discord/tests/configmap_test.yaml b/examples/chart/access/discord/tests/configmap_test.yaml new file mode 100644 index 0000000000000..cf8343ba004b8 --- /dev/null +++ b/examples/chart/access/discord/tests/configmap_test.yaml @@ -0,0 +1,21 @@ +suite: Test deployment +templates: + - configmap.yaml +tests: + - it: should match the snapshot + set: + teleport: + address: teleport.example.com:1234 + slack: + token: test-api-key + roleToRecipients: + dev: + - dev-access-requests + - example-user@example.com + "*": + - dev-access-requests + log: + output: /var/log/teleport-discord.log + severity: DEBUG + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/discord/tests/deployment_test.yaml b/examples/chart/access/discord/tests/deployment_test.yaml new file mode 100644 index 0000000000000..d5255e7c56e4c --- /dev/null +++ b/examples/chart/access/discord/tests/deployment_test.yaml @@ -0,0 +1,11 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/discord/tests/secret_test.yaml b/examples/chart/access/discord/tests/secret_test.yaml new file mode 100644 index 0000000000000..a93d3266cf68f --- /dev/null +++ b/examples/chart/access/discord/tests/secret_test.yaml @@ -0,0 +1,18 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should contain the api key + set: + discord: + token: mydiscordtoken + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + discord: + tokenFromSecret: my-discord-secret + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/discord/values.schema.json b/examples/chart/access/discord/values.schema.json new file mode 100644 index 0000000000000..ff771f1b36db1 --- /dev/null +++ b/examples/chart/access/discord/values.schema.json @@ -0,0 +1,399 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "discord", + "roleToRecipients", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-discord", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-discord", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-discord" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-discord-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "discord": { + "$id": "#/properties/discord", + "type": "object", + "default": {}, + "examples": [ + { + "token": "example-api-token" + } + ], + "required": [ + "token", + "tokenFromSecret", + "tokenSecretPath" + ], + "properties": { + "token": { + "$id": "#/properties/discord/properties/token", + "type": "string", + "default": "", + "examples": [ + "example-api-token" + ] + }, + "tokenFromSecret": { + "$id": "#/properties/discord/properties/tokenFromSecret", + "type": "string", + "default": "", + "examples": [ + "discord-token" + ] + }, + "tokenSecretPath": { + "$id": "#/properties/discord/properties/tokenSecretPath", + "type": "string", + "default": "discordToken", + "examples": [ + "token" + ] + } + }, + "additionalProperties": true + }, + "roleToRecipients": { + "$id": "#/properties/roleToRecipients", + "type": "object", + "default": {}, + "examples": [ + { + "dev": [ + "1234567890", + "0987654321" + ], + "*": [ + "1234567890" + ] + } + ], + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "examples": [ + "example-discord-channel", + "user@example.com" + ] + }, + "minItems": 1 + } + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/discord/values.yaml b/examples/chart/access/discord/values.yaml new file mode 100644 index 0000000000000..b5a18cdd474ab --- /dev/null +++ b/examples/chart/access/discord/values.yaml @@ -0,0 +1,64 @@ +# Default values for discord. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +discord: + token: "" + tokenFromSecret: "" + tokenSecretPath: "discordToken" + +roleToRecipients: {} + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-discord + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/chart/access/email/.helmignore b/examples/chart/access/email/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/email/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/email/Chart.yaml b/examples/chart/access/email/Chart.yaml new file mode 100644 index 0000000000000..983a44286c49f --- /dev/null +++ b/examples/chart/access/email/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-email +description: A Helm chart for the Teleport Email Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/email/README.md b/examples/chart/access/email/README.md new file mode 100644 index 0000000000000..5818a9e8b10fc --- /dev/null +++ b/examples/chart/access/email/README.md @@ -0,0 +1,192 @@ +# Teleport Access Request Email Plugin + +This chart sets up and configures a Deployment for the Access Request Email plugin. + +## Installation + +See the [Access Requests with Email guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-email/). + +## Values + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"no
mailgun.enabled + Specifies if the Mailgun integration should be enabled. Mutually exclusive with smtp.enabled. + In the case of both values are set to true, mailgun.enabled will take precedence. + booleanfalseno
mailgun.domainDomain name of the Mailgun instancestring""no
mailgun.privateKeyPrivate key for accessing the Mailgun instancestring""no
mailgun.privateKeyFromSecretKubernetes secret to read the private key from instead of using mailgun.privateKeystring""no
mailgun.privateKeySecretPathThe path of the private key in the secret described by mailgun.privateKeyFromSecretstring"mailgunPrivateKey"no
smtp.enabled + Specifies if the MailSMTPgun integration should be enabled. Mutually exclusive with mailgun.enabled. + In the case of both values are set to true, mailgun.enabled will take precedence. + booleanfalseno
smtp.hostSMTP host.string""no
smtp.portPort of the SMTP server.integer587no
smtp.usernameUsername to be used with the SMTP server.string""no
smtp.passwordPassword to be used with the SMTP server. Mutually exclusive with smtp.passwordFile.string""no
smtp.passwordFromSecretKubernetes secret to read the SMTP password from instead of using smtp.passwordstring""no
smtp.passwordSecretPathThe path of the SMTP password in the secret described by smtp.passwordFromSecretstring"smtpPassword"no
smtp.starttlsPolicyWhich policy to use for secure communications: mandatory, opportunistic or disabled.string"mandatory"no
delivery.senderEmail address to be used in the From field of the emails.string""yes
delivery.recipientsArray of the recipients the plugin should send emails.array[]no
roleToRecipients + Mapping of roles to a list of emails.
+ Example: +
+"dev" = ["developers@example.com", "user@example.com"]
+"*" = ["access-requests"]
+
map{}yes
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/email.log" + string"stdout"no
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"no
diff --git a/examples/chart/access/email/templates/_helpers.tpl b/examples/chart/access/email/templates/_helpers.tpl new file mode 100644 index 0000000000000..9742d31eb80c8 --- /dev/null +++ b/examples/chart/access/email/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "email.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "email.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "email.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "email.labels" -}} +helm.sh/chart: {{ include "email.chart" . }} +{{ include "email.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "email.selectorLabels" -}} +app.kubernetes.io/name: {{ include "email.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "email.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "email.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/email/templates/configmap.yaml b/examples/chart/access/email/templates/configmap.yaml new file mode 100644 index 0000000000000..6e5c6d51cfeb7 --- /dev/null +++ b/examples/chart/access/email/templates/configmap.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "email.fullname" . }} + labels: + {{- include "email.labels" . | nindent 4 }} +data: + teleport-email.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/email/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + {{ if .Values.mailgun.enabled -}} + [mailgun] + domain = "{{ .Values.mailgun.domain }}" + private_key_file = "/var/lib/teleport/plugins/email/mailgun_private_key" + {{ else if .Values.smtp.enabled -}} + [smtp] + host = "{{ .Values.smtp.host }}" + port = {{ .Values.smtp.port }} + username = "{{ .Values.smtp.username }}" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "{{ .Values.smtp.starttlsPolicy }}" + {{- end }} + + [delivery] + sender = "{{ .Values.delivery.sender }}" + {{- if (not .Values.roleToRecipients) }} + recipients = {{ .Values.delivery.recipients | toJson }} + {{- else }} + + [role_to_recipients] + {{- range $role, $recipients := .Values.roleToRecipients }} + {{ $role | toJson }} = {{ $recipients | toJson }} + {{- end }} + {{- end }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/email/templates/deployment.yaml b/examples/chart/access/email/templates/deployment.yaml new file mode 100644 index 0000000000000..b19a583a0dbae --- /dev/null +++ b/examples/chart/access/email/templates/deployment.yaml @@ -0,0 +1,104 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "email.fullname" . }} + labels: + {{- include "email.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "email.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "email.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-email.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-email.toml + subPath: teleport-email.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/email/teleport-identity + {{- if or .Values.mailgun.enabled .Values.smtp.enabled }} + - name: {{ .Values.secretVolumeName }} + {{- if .Values.mailgun.enabled }} + mountPath: "/var/lib/teleport/plugins/email/mailgun_private_key" + subPath: "{{ .Values.mailgun.privateKeySecretPath }}" + {{- end }} + {{- if .Values.smtp.enabled }} + mountPath: "/var/lib/teleport/plugins/email/smtp_password" + subPath: "{{ .Values.smtp.passwordSecretPath }}" + {{- end }} + {{- end }} + {{- with .Values.volumeMounts -}} + {{- toYaml . | nindent 12 }} + {{- end}} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "email.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + {{- if or .Values.smtp.enabled .Values.mailgun.enabled }} + {{- if .Values.smtp.enabled }} + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.smtp.passwordFromSecret (printf "%s-secret" (include "email.fullname" .)) }}" + defaultMode: 0600 + {{- end }} + {{- if .Values.mailgun.enabled }} + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.mailgun.privateKeyFromSecret (printf "%s-secret" (include "email.fullname" .)) }}" + defaultMode: 0600 + {{- end }} + {{- end }} + {{- with .Values.volumes -}} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/examples/chart/access/email/templates/secret.yaml b/examples/chart/access/email/templates/secret.yaml new file mode 100644 index 0000000000000..c543437e1cb4d --- /dev/null +++ b/examples/chart/access/email/templates/secret.yaml @@ -0,0 +1,15 @@ +{{- if or (and .Values.mailgun.enabled (not .Values.mailgun.privateKeyFromSecret)) + (and .Values.smtp.enabled (not .Values.smtp.passwordFromSecret)) -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "email.fullname" . }}-secret +data: + {{- if .Values.mailgun.enabled }} + mailgunPrivateKey: {{ .Values.mailgun.privateKey | b64enc }} + {{- end }} + {{- if .Values.smtp.enabled }} + smtpPassword: {{ b64enc .Values.smtp.password }} + {{- end }} +{{- end }} diff --git a/examples/chart/access/email/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/email/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..6163b39a09ab6 --- /dev/null +++ b/examples/chart/access/email/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,199 @@ +should match the snapshot (mailgun on): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [mailgun] + domain = "mymailgunsubdomain.mailgun.org" + private_key_file = "/var/lib/teleport/plugins/email/mailgun_private_key" + + + [delivery] + sender = "" + recipients = [] + + [log] + output = "stdout" + severity = "INFO" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email +should match the snapshot (smtp on): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [smtp] + host = "smtp.example.com" + port = 1234 + username = "mysmtpuser" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "mandatory" + + [delivery] + sender = "teleport@example.com" + recipients = ["security@mycompany.com"] + + [log] + output = "/var/log/teleport-email.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email +should match the snapshot (smtp on, no starttls): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [smtp] + host = "smtp.example.com" + port = 1234 + username = "mysmtpuser" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "mandatory" + + [delivery] + sender = "" + recipients = [] + + [log] + output = "stdout" + severity = "INFO" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email +should match the snapshot (smtp on, password file): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [smtp] + host = "smtp.example.com" + port = 1234 + username = "mysmtpuser" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "mandatory" + + [delivery] + sender = "" + recipients = [] + + [log] + output = "stdout" + severity = "INFO" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email +should match the snapshot (smtp on, roleToRecipients set): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [smtp] + host = "smtp.example.com" + port = 1234 + username = "mysmtpuser" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "mandatory" + + [delivery] + sender = "teleport@example.com" + + [role_to_recipients] + "*" = ["security@mycompany.com"] + "dev" = ["developers@mycompany.com"] + + [log] + output = "/var/log/teleport-email.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email +should match the snapshot (smtp on, starttls disabled): + 1: | + apiVersion: v1 + data: + teleport-email.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/email/teleport-identity/auth_id" + refresh_identity = true + + [smtp] + host = "smtp.example.com" + port = 1234 + username = "mysmtpuser" + password_file = "/var/lib/teleport/plugins/email/smtp_password" + starttls_policy = "disabled" + + [delivery] + sender = "" + recipients = [] + + [log] + output = "stdout" + severity = "INFO" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email diff --git a/examples/chart/access/email/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/email/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..abfb6bf76d99f --- /dev/null +++ b/examples/chart/access/email/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,401 @@ +should be possible to override volume name (smtp on): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-email:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/email/smtp_password + name: secret-volume + subPath: smtpPassword + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: secret-volume + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-email-secret +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" +should match the snapshot (mailgun on): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-email:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/email/mailgun_private_key + name: password-file + subPath: mailgunPrivateKey + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-email-secret +should match the snapshot (smtp on): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-email:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/email/smtp_password + name: password-file + subPath: smtpPassword + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-email-secret +should mount external secret (mailgun on): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-email:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/email/mailgun_private_key + name: password-file + subPath: my-path-in-secret + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: my-secret-name +should mount external secret (smtp on): + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-email + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-email + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-email + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-email-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-email.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-email:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-email + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-email.toml + name: config + subPath: teleport-email.toml + - mountPath: /var/lib/teleport/plugins/email/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/email/smtp_password + name: password-file + subPath: my-path-in-secret + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-email + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: my-secret-name diff --git a/examples/chart/access/email/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/email/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..8d32ac3e8e41f --- /dev/null +++ b/examples/chart/access/email/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,18 @@ +should match the snapshot (mailgun on): + 1: | + apiVersion: v1 + data: + mailgunPrivateKey: LS0tIFRFU1QgUFJJVkFURSBLRVkgLS0t + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-email-secret + type: Opaque +should match the snapshot (smtp on): + 1: | + apiVersion: v1 + data: + smtpPassword: bXlzbXRwcGFzc3dk + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-email-secret + type: Opaque diff --git a/examples/chart/access/email/tests/configmap_test.yaml b/examples/chart/access/email/tests/configmap_test.yaml new file mode 100644 index 0000000000000..d8c4ef9c4e584 --- /dev/null +++ b/examples/chart/access/email/tests/configmap_test.yaml @@ -0,0 +1,106 @@ +suite: Test configmap +templates: + - configmap.yaml +tests: + - it: should match the snapshot (smtp on) + set: + teleport: + address: teleport.example.com:1234 + mailgun.enabled: false + smtp: + enabled: true + host: smtp.example.com + port: 1234 + username: mysmtpuser + password: mysmtppasswd + starttlsPolicy: mandatory + delivery: + sender: teleport@example.com + recipients: + - security@mycompany.com + log: + output: /var/log/teleport-email.log + severity: DEBUG + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (smtp on, roleToRecipients set) + set: + teleport: + address: teleport.example.com:1234 + mailgun.enabled: false + smtp: + enabled: true + host: smtp.example.com + port: 1234 + username: mysmtpuser + password: mysmtppasswd + starttlsPolicy: mandatory + delivery: + sender: teleport@example.com + roleToRecipients: + '*': + - security@mycompany.com + 'dev': + - 'developers@mycompany.com' + log: + output: /var/log/teleport-email.log + severity: DEBUG + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (smtp on, password file) + set: + teleport: + address: teleport.example.com:1234 + mailgun.enabled: false + smtp: + enabled: true + host: smtp.example.com + port: 1234 + username: mysmtpuser + passwordFile: /etc/teleport/supersecretemailpw + starttlsPolicy: mandatory + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (smtp on, starttls disabled) + set: + teleport: + address: teleport.example.com:1234 + mailgun.enabled: false + smtp: + enabled: true + host: smtp.example.com + port: 1234 + username: mysmtpuser + passwordFile: /etc/teleport/supersecretemailpw + starttlsPolicy: disabled + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (smtp on, no starttls) + set: + teleport: + address: teleport.example.com:1234 + mailgun.enabled: false + smtp: + enabled: true + host: smtp.example.com + port: 1234 + username: mysmtpuser + passwordFile: /etc/teleport/supersecretemailpw + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (mailgun on) + set: + teleport: + address: teleport.example.com:1234 + smtp.enabled: false + mailgun: + enabled: true + domain: mymailgunsubdomain.mailgun.org + privateKey: xoxb-fakekey62b0eac53565a38c8cc0316f6 + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/email/tests/deployment_test.yaml b/examples/chart/access/email/tests/deployment_test.yaml new file mode 100644 index 0000000000000..a3c20b5d71709 --- /dev/null +++ b/examples/chart/access/email/tests/deployment_test.yaml @@ -0,0 +1,51 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (mailgun on) + set: + mailgun: + enabled: true + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (smtp on) + set: + smtp: + enabled: true + asserts: + - matchSnapshot: {} + + - it: should be possible to override volume name (smtp on) + set: + smtp: + enabled: true + secretVolumeName: "secret-volume" + asserts: + - matchSnapshot: {} + + - it: should mount external secret (mailgun on) + set: + mailgun: + enabled: true + privateKeyFromSecret: my-secret-name + privateKeySecretPath: my-path-in-secret + asserts: + - matchSnapshot: {} + + - it: should mount external secret (smtp on) + set: + smtp: + enabled: true + passwordFromSecret: my-secret-name + passwordSecretPath: my-path-in-secret + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/email/tests/secret_test.yaml b/examples/chart/access/email/tests/secret_test.yaml new file mode 100644 index 0000000000000..cf3653483b622 --- /dev/null +++ b/examples/chart/access/email/tests/secret_test.yaml @@ -0,0 +1,43 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should match the snapshot (smtp on) + set: + mailgun.enabled: false + smtp: + enabled: true + password: mysmtppasswd + asserts: + - matchSnapshot: {} + + - it: should match the snapshot (mailgun on) + set: + mailgun: + enabled: true + privateKey: "--- TEST PRIVATE KEY ---" + asserts: + - matchSnapshot: {} + + - it: should not exist (both off) + asserts: + - hasDocuments: + count: 0 + + - it: should not exist (smtp.passwordFromSecret used) + set: + smtp: + enabled: true + passwordFromSecret: teleport-email-plugin-smtp + asserts: + - hasDocuments: + count: 0 + + - it: should not exist (mailgun.privateKeyFromSecret used) + set: + mailgun: + enabled: true + privateKeyFromSecret: teleport-email-plugin-mailgun + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/email/values.schema.json b/examples/chart/access/email/values.schema.json new file mode 100644 index 0000000000000..e761b89b0d4b2 --- /dev/null +++ b/examples/chart/access/email/values.schema.json @@ -0,0 +1,566 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "mailgun", + "smtp", + "delivery", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-email", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-email", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-email" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "volumes": { + "$id": "#/properties/volumes", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumes/items", + "type": "object", + "additionalItems": true + } + }, + "volumeMounts": { + "$id": "#/properties/volumeMounts", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumeMounts/items", + "type": "object", + "additionalItems": true + } + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-email-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "mailgun": { + "$id": "#/properties/mailgun", + "type": "object", + "default": {}, + "examples": [ + { + "enabled": false, + "domain": "yourdomain.mailgun.org", + "privateKey": "xoxb-fakekey62b0eac53565a38c8cc0316f6" + } + ], + "required": [ + "enabled", + "domain", + "privateKey" + ], + "properties": { + "enabled": { + "$id": "#/properties/mailgun/properties/enabled", + "type": "boolean", + "default": false, + "examples": [ + false + ] + }, + "domain": { + "$id": "#/properties/mailgun/properties/domain", + "type": "string", + "default": "", + "examples": [ + "yourdomain.mailgun.org" + ] + }, + "privateKey": { + "$id": "#/properties/mailgun/properties/privateKey", + "type": "string", + "default": "", + "examples": [ + "xoxb-11xx" + ] + }, + "privateKeyFromSecret": { + "$id": "#/properties/mailgun/properties/privateKeyFromSecret", + "type": "string", + "default": "", + "examples": [ + "my-secret-name" + ] + }, + "privateKeySecretPath": { + "$id": "#/properties/mailgun/properties/privateKeySecretPath", + "type": "string", + "default": "mailgunPrivateKey", + "examples": [ + "my-path-in-secret" + ] + } + }, + "additionalProperties": true + }, + "smtp": { + "$id": "#/properties/smtp", + "type": "object", + "default": {}, + "examples": [ + { + "enabled": true, + "host": "smtp.example.com", + "port": 587, + "username": "username@example.com", + "password": "", + "starttlsPolicy": "mandatory" + } + ], + "required": [ + "enabled", + "host", + "port", + "username" + ], + "properties": { + "enabled": { + "$id": "#/properties/smtp/properties/enabled", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "host": { + "$id": "#/properties/smtp/properties/host", + "type": "string", + "default": "smtp.example.com", + "examples": [ + "smtp.example.com" + ] + }, + "port": { + "$id": "#/properties/smtp/properties/port", + "type": "integer", + "default": 587, + "examples": [ + 587 + ] + }, + "username": { + "$id": "#/properties/smtp/properties/username", + "type": "string", + "default": "username@example.com", + "examples": [ + "username@example.com" + ] + }, + "password": { + "$id": "#/properties/smtp/properties/password", + "type": "string", + "default": "" + }, + "passwordFromSecret": { + "$id": "#/properties/smtp/properties/passwordFromSecret", + "type": "string", + "default": "" + }, + "passwordSecretPath": { + "$id": "#/properties/smtp/properties/passwordSecretPath", + "type": "string", + "default": "smtpPassword" + }, + "starttlsPolicy": { + "$id": "#/properties/smtp/properties/starttlsPolicy", + "type": "string", + "default": "mandatory" + } + }, + "additionalProperties": true + }, + "delivery": { + "$id": "#/properties/delivery", + "type": "object", + "default": {}, + "examples": [ + { + "sender": "noreply@example.com", + "recipients": [ + "all@example.com" + ] + } + ], + "required": [ + "sender", + "recipients" + ], + "properties": { + "sender": { + "$id": "#/properties/delivery/properties/sender", + "type": "string", + "default": "noreply@example.com", + "examples": [ + "noreply@example.com" + ] + }, + "recipients": { + "$id": "#/properties/delivery/properties/recipients", + "type": "array", + "default": [], + "examples": [ + [ + "all@example.com" + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/delivery/properties/recipients/items", + "anyOf": [ + { + "$id": "#/properties/delivery/properties/recipients/items/anyOf/0", + "type": "string", + "default": "", + "examples": [ + "all@example.com" + ] + } + ] + } + } + }, + "additionalProperties": true + }, + "roleToRecipients": { + "$id": "#/properties/roleToRecipients", + "type": "object", + "default": {}, + "examples": [ + { + "dev": [ + "devs-slack-channel" + ], + "*": [ + "admin@email.com", + "admin-slack-channel" + ] + } + ], + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "examples": [ + "example-slack-channel", + "user@example.com" + ] + }, + "minItems": 1 + } + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/email/values.yaml b/examples/chart/access/email/values.yaml new file mode 100644 index 0000000000000..1b31b64a58a5a --- /dev/null +++ b/examples/chart/access/email/values.yaml @@ -0,0 +1,71 @@ +# Default values for email. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +mailgun: + enabled: false + domain: "" + privateKey: "" + privateKeyFromSecret: "" + privateKeySecretPath: "mailgunPrivateKey" + +smtp: + enabled: false + host: "" + port: 587 + username: "" + password: "" + passwordFromSecret: "" + passwordSecretPath: "smtpPassword" + starttlsPolicy: "mandatory" + +delivery: + sender: "" + recipients: [] + +roleToRecipients: {} + +secretVolumeName: "password-file" + +log: + output: stdout + severity: INFO + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-email + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +volumes: [] + +volumeMounts: [] diff --git a/examples/chart/access/jira/.helmignore b/examples/chart/access/jira/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/jira/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/jira/Chart.yaml b/examples/chart/access/jira/Chart.yaml new file mode 100644 index 0000000000000..ec22a40043378 --- /dev/null +++ b/examples/chart/access/jira/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-jira +description: A Helm chart for the Teleport Jira Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/jira/README.md b/examples/chart/access/jira/README.md new file mode 100644 index 0000000000000..c58b02966f6b8 --- /dev/null +++ b/examples/chart/access/jira/README.md @@ -0,0 +1,154 @@ +# Teleport Access Request Jira Plugin + +This chart sets up and configures a Deployment for the Access Request Jira plugin. + +## Installation + +See the [Access Requests with JIRA guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-jira/). + +## Values + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
chartMode + When set to "aws", it'll add the proper annotations to the created service + to ensure the AWS LoadBalancer is set up properly. Additional annotations can be added + using serviceAnnotations. + string""no
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"yes
jira.urlURL of the Jira serverstring""yes
jira.usernameUsername of the bot user in Jira to use for creating issues.string""yes
jira.apiTokenAPI token of the bot user.string""yes
jira.projectShort code of the project in Jira in which issues will be createdstring""yes
jira.issueTypeType of the issues to be created on access requests (eg. Bug, Task)string"Task"no
http.publicAddressThe domain name which will be assigned to the servicestring""yes
http.tlsFromSecretName of the Kubernetes secret where the TLS key and certificate will be mountedstring""yes
http.tlsKeySecretPathPath of the TLS key in the secret specified by http.tlsFromSecretstring""no
http.tlsCertSecretPathPath of the TLS certificate in the secret specified by http.tlsFromSecretstring""no
http.basicAuth.usernameUsername for the basic authentication. The plugin will require a m atching `Authorization` header in case both the username and the password are specified.string""no
http.basicAuth.passwordPassword for the basic authentication. The plugin will require a m atching `Authorization` header in case both the username and the password are specified.string""no
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/jira.log" + string"stdout"
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"
diff --git a/examples/chart/access/jira/templates/_helpers.tpl b/examples/chart/access/jira/templates/_helpers.tpl new file mode 100644 index 0000000000000..689e783e2c03e --- /dev/null +++ b/examples/chart/access/jira/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "jira.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "jira.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "jira.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "jira.labels" -}} +helm.sh/chart: {{ include "jira.chart" . }} +{{ include "jira.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "jira.selectorLabels" -}} +app.kubernetes.io/name: {{ include "jira.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jira.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "jira.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/jira/templates/configmap.yaml b/examples/chart/access/jira/templates/configmap.yaml new file mode 100644 index 0000000000000..737c5e9bcf85a --- /dev/null +++ b/examples/chart/access/jira/templates/configmap.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "jira.fullname" . }} + labels: + {{- include "jira.labels" . | nindent 4 }} +data: + teleport-jira.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/jira/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [jira] + url = "{{ .Values.jira.url }}" + username = "{{ .Values.jira.username }}" + api_token = "/var/lib/teleport/plugins/jira/jira_api_token" + project = "{{ .Values.jira.project }}" + {{- if .Values.jira.issueType }} + issue_type = "{{ .Values.jira.issueType }}" + {{- end }} + + [http] + listen_addr = ":8443" + public_addr = "{{ .Values.http.publicAddress }}" + https_key_file = "/var/lib/teleport/plugins/jira/tls/tls.key" + https_cert_file = "/var/lib/teleport/plugins/jira/tls/tls.crt" + + {{ if .Values.http.basicAuth.enabled -}} + [http.basic_auth] + user = {{ .Values.http.basicAuth.user }} + password = {{ .Values.http.basicAuth.password }} + {{- end }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/jira/templates/deployment.yaml b/examples/chart/access/jira/templates/deployment.yaml new file mode 100644 index 0000000000000..d06a95764900b --- /dev/null +++ b/examples/chart/access/jira/templates/deployment.yaml @@ -0,0 +1,96 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "jira.fullname" . }} + labels: + {{- include "jira.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "jira.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "jira.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-jira.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + ports: + - name: http + containerPort: 8443 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-jira.toml + subPath: teleport-jira.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/jira/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: "/var/lib/teleport/plugins/jira/jira_api_token" + subPath: {{ .Values.jira.apiTokenSecretPath }} + - name: {{ .Values.tlsSecretVolumeName }} + mountPath: "/var/lib/teleport/plugins/jira/tls/tls.key" + subPath: {{ .Values.http.tlsKeySecretPath }} + - name: {{ .Values.tlsSecretVolumeName }} + mountPath: "/var/lib/teleport/plugins/jira/tls/tls.crt" + subPath: {{ .Values.http.tlsCertSecretPath }} + {{- with .Values.volumeMounts -}} + {{- toYaml . | nindent 12 }} + {{- end}} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "jira.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identityFromSecret }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.jira.apiTokenFromSecret (printf "%s-secret" (include "jira.fullname" .)) }}" + defaultMode: 0600 + - name: {{ .Values.tlsSecretVolumeName }} + secret: + secretName: "{{ .Values.http.tlsFromSecret }}" + defaultMode: 0600 + {{- with .Values.volumes -}} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/examples/chart/access/jira/templates/secret.yaml b/examples/chart/access/jira/templates/secret.yaml new file mode 100644 index 0000000000000..ab53b4e192ff4 --- /dev/null +++ b/examples/chart/access/jira/templates/secret.yaml @@ -0,0 +1,9 @@ +{{- if not .Values.jira.apiTokenFromSecret -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "jira.fullname" . }}-secret +data: + jiraApiToken: {{ .Values.jira.apiToken | b64enc }} +type: Opaque +{{- end }} diff --git a/examples/chart/access/jira/templates/service.yaml b/examples/chart/access/jira/templates/service.yaml new file mode 100644 index 0000000000000..71c2f8a441958 --- /dev/null +++ b/examples/chart/access/jira/templates/service.yaml @@ -0,0 +1,23 @@ +kind: Service +apiVersion: v1 +metadata: + name: {{ include "jira.fullname" . }} + {{- if (or (eq .Values.chartMode "aws") .Values.serviceAnnotations) }} + annotations: + {{- if eq .Values.chartMode "aws" }} + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + service.beta.kubernetes.io/aws-load-balancer-type: nlb + {{- end }} + {{- if .Values.serviceAnnotations }} + {{- toYaml .Values.serviceAnnotations | nindent 4 }} + {{- end }} + {{- end }} +spec: + selector: + {{- include "jira.selectorLabels" . | nindent 4 }} + type: {{ .Values.serviceType }} + ports: + - name: https + port: 443 + targetPort: 8443 diff --git a/examples/chart/access/jira/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/jira/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..b71127cd7a439 --- /dev/null +++ b/examples/chart/access/jira/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,37 @@ +should match the snapshot (smtp on): + 1: | + apiVersion: v1 + data: + teleport-jira.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/jira/teleport-identity/auth_id" + refresh_identity = true + + [jira] + url = "https://jira.example.com" + username = "user@example.com" + api_token = "/var/lib/teleport/plugins/jira/jira_api_token" + project = "ACC" + issue_type = "Task" + + [http] + listen_addr = ":8443" + public_addr = "jira-plugin.example.com" + https_key_file = "/var/lib/teleport/plugins/jira/tls/tls.key" + https_cert_file = "/var/lib/teleport/plugins/jira/tls/tls.crt" + + + + [log] + output = "/var/log/teleport-jira.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-jira + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-jira-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-jira diff --git a/examples/chart/access/jira/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/jira/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..a6a2e53c1f098 --- /dev/null +++ b/examples/chart/access/jira/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,78 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-jira + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-jira-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-jira + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-jira + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-jira + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-jira-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-jira.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-jira + ports: + - containerPort: 8443 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-jira.toml + name: config + subPath: teleport-jira.toml + - mountPath: /var/lib/teleport/plugins/jira/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/jira/jira_api_token + name: password-file + subPath: jiraApiToken + - mountPath: /var/lib/teleport/plugins/jira/tls/tls.key + name: tls + subPath: server.key + - mountPath: /var/lib/teleport/plugins/jira/tls/tls.crt + name: tls + subPath: server.crt + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-jira + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-jira-secret + - name: tls + secret: + defaultMode: 384 + secretName: jira-tls-secret diff --git a/examples/chart/access/jira/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/jira/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..a841f589d02a6 --- /dev/null +++ b/examples/chart/access/jira/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should match snapshot: + 1: | + apiVersion: v1 + data: + jiraApiToken: amlyYWFwaXRva2Vu + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-jira-secret + type: Opaque diff --git a/examples/chart/access/jira/tests/__snapshot__/service_test.yaml.snap b/examples/chart/access/jira/tests/__snapshot__/service_test.yaml.snap new file mode 100644 index 0000000000000..0d55aefdf721d --- /dev/null +++ b/examples/chart/access/jira/tests/__snapshot__/service_test.yaml.snap @@ -0,0 +1,17 @@ +should be possible to add custom annotations: + 1: | + apiVersion: v1 + kind: Service + metadata: + annotations: + my-custom-annotation: my-custom-value + name: RELEASE-NAME-teleport-plugin-jira + spec: + ports: + - name: https + port: 443 + targetPort: 8443 + selector: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-jira + type: LoadBalancer diff --git a/examples/chart/access/jira/tests/configmap_test.yaml b/examples/chart/access/jira/tests/configmap_test.yaml new file mode 100644 index 0000000000000..fe058547ed694 --- /dev/null +++ b/examples/chart/access/jira/tests/configmap_test.yaml @@ -0,0 +1,27 @@ +suite: Test configmap +templates: + - configmap.yaml +tests: + - it: should match the snapshot (smtp on) + set: + teleport: + address: teleport.example.com:1234 + jira: + url: https://jira.example.com + username: user@example.com + apiToken: examplejiratoken + project: ACC + Task: Bug + http: + listenAddress: ":1234" + publicAddress: "jira-plugin.example.com" + tlsFromSecret: "jira-tls-secret" + + basicAuth: + user: "testuser" + password: "testpassword" + log: + output: /var/log/teleport-jira.log + severity: DEBUG + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/jira/tests/deployment_test.yaml b/examples/chart/access/jira/tests/deployment_test.yaml new file mode 100644 index 0000000000000..6a929eea126d0 --- /dev/null +++ b/examples/chart/access/jira/tests/deployment_test.yaml @@ -0,0 +1,15 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + http: + tlsFromSecret: "jira-tls-secret" + tlsKeySecretPath: "server.key" + tlsCertSecretPath: "server.crt" + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/jira/tests/secret_test.yaml b/examples/chart/access/jira/tests/secret_test.yaml new file mode 100644 index 0000000000000..a283fd944f463 --- /dev/null +++ b/examples/chart/access/jira/tests/secret_test.yaml @@ -0,0 +1,18 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should match snapshot + set: + jira: + apiToken: jiraapitoken + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + jira: + apiTokenFromSecret: my-jira-secret + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/jira/tests/service_test.yaml b/examples/chart/access/jira/tests/service_test.yaml new file mode 100644 index 0000000000000..e629a203750c1 --- /dev/null +++ b/examples/chart/access/jira/tests/service_test.yaml @@ -0,0 +1,30 @@ +suite: Test service +templates: + - service.yaml +tests: + - it: should be possible to add custom annotations + set: + serviceAnnotations: + my-custom-annotation: my-custom-value + asserts: + - matchSnapshot: {} + + - it: should set annotations for AWS compatibility when chartMode is set to aws + set: + chartMode: "aws" + asserts: + - equal: + path: metadata.annotations + value: + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + service.beta.kubernetes.io/aws-load-balancer-type: nlb + + - it: should be possible to change service type + set: + serviceType: "ClusterIP" + asserts: + - equal: + path: spec.type + value: + ClusterIP diff --git a/examples/chart/access/jira/values.schema.json b/examples/chart/access/jira/values.schema.json new file mode 100644 index 0000000000000..77ab552899d3a --- /dev/null +++ b/examples/chart/access/jira/values.schema.json @@ -0,0 +1,509 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "serviceType", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "jira", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/teleport/access-plugin-email", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/teleport/access-plugin-email", + "examples": [ + "public.ecr.aws/teleport/access-plugin-email" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "serviceType": { + "$id": "#/properties/serviceType", + "type": "string", + "default": "LoadBalancer" + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "volumes": { + "$id": "#/properties/volumes", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumes/items", + "type": "object", + "additionalItems": true + } + }, + "volumeMounts": { + "$id": "#/properties/volumeMounts", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumeMounts/items", + "type": "object", + "additionalItems": true + } + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identityFromSecret": "teleport-plugin-email-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identityFromSecret", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identityFromSecret": { + "$id": "#/properties/teleport/properties/identityFromSecret", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "jira": { + "$id": "#/properties/jira", + "type": "object", + "default": {}, + "examples": [ + { + "url": "https://jira.example.net/", + "username": "user@example.com", + "apiToken": "secretapitoken", + "project": "EXAM", + "issueType": "Task" + } + ], + "required": [ + "url", + "username", + "apiToken", + "project", + "issueType" + ], + "properties": { + "url": { + "$id": "#/properties/teleport/properties/url", + "type": "string", + "default": "", + "examples": [ + "https://jira.example.net/" + ] + }, + "username": { + "$id": "#/properties/teleport/properties/username", + "type": "string", + "default": "", + "examples": [ + "user@example.com" + ] + }, + "apiToken": { + "$id": "#/properties/teleport/properties/apiToken", + "type": "string", + "default": "", + "examples": [ + "secretapitoken" + ] + }, + "project": { + "$id": "#/properties/teleport/properties/project", + "type": "string", + "default": "", + "examples": [ + "EXAM" + ] + }, + "issueType": { + "$id": "#/properties/teleport/properties/issueType", + "type": "string", + "default": "Task", + "examples": [ + "Bug", + "Task" + ] + } + }, + "additionalProperties": true + }, + "http": { + "$id": "#/properties/http", + "type": "object", + "default": { + "publicAddress": "", + "tlsFromSecret": "", + "tlsKeySecretPath": "tls.key", + "tlsCertSecretPath": "tls.crt", + + "basicAuth":{ + "user": "", + "password": "" + } + }, + "examples": [ + { + "publicAddress": "jira-plugin.teleport.example.com", + "tlsFromSecret": "teleport-jira-plugin-tls", + "tlsKeySecretPath": "tls.key", + "tlsCertSecretPath": "tls.crt", + + "basicAuth":{ + "user": "exampleuser", + "password": "examplepassword" + } + } + ], + "required": [ + "publicAddress", + "tlsFromSecret" + ], + "properties": { + "publicAddress": { + "$id": "#/properties/teleport/properties/publicAddress", + "type": "string", + "default": "", + "examples": [ + "jira-plugin.teleport.example.com" + ] + }, + "tlsFromSecret": { + "$id": "#/properties/teleport/properties/tlsFromSecret", + "type": "string", + "default": "", + "examples": [ + "my-tls-secret" + ] + }, + "tlsKeySecretPath": { + "$id": "#/properties/teleport/properties/tlsKeySecretPath", + "type": "string", + "default": "tls.key", + "examples": [ + "tls.key" + ] + }, + "tlsCertSecretPath": { + "$id": "#/properties/teleport/properties/tlsCertSecretPath", + "type": "string", + "default": "tls.crt", + "examples": [ + "tls.crt" + ] + }, + "basicAuth": { + "$id": "#/properties/basicAuth", + "type": "object", + "default": { + "user": "", + "password": "" + }, + "examples": [ + { + "user": "exampleuser", + "password": "examplepassword" + } + ], + "user": { + "$id": "#/properties/teleport/properties/user", + "type": "string", + "default": "", + "examples": [ + "exampleuser" + ] + }, + "password": { + "$id": "#/properties/teleport/properties/password", + "type": "string", + "default": "", + "examples": [ + "examplepassword" + ] + } + } + }, + "additionalProperties": true + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/jira/values.yaml b/examples/chart/access/jira/values.yaml new file mode 100644 index 0000000000000..ace4dfd9a691d --- /dev/null +++ b/examples/chart/access/jira/values.yaml @@ -0,0 +1,70 @@ +# Default values for teleport-plugin-jira. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identityFromSecret: "" + identitySecretPath: "auth_id" + +jira: + url: "" + username: "" + apiToken: "" + apiTokenFromSecret: "" + apiTokenSecretPath: "jiraApiToken" + project: "" + issueType: "Task" + +http: + publicAddress: "" + tlsFromSecret: "" + tlsKeySecretPath: "tls.key" + tlsCertSecretPath: "tls.crt" + + basicAuth: + user: "" + password: "" + +chartMode: "" + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" +tlsSecretVolumeName: "tls" + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-jira + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +serviceAnnotations: {} + +serviceType: LoadBalancer diff --git a/examples/chart/access/mattermost/.helmignore b/examples/chart/access/mattermost/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/mattermost/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/mattermost/Chart.yaml b/examples/chart/access/mattermost/Chart.yaml new file mode 100644 index 0000000000000..63a1d3cd32d7e --- /dev/null +++ b/examples/chart/access/mattermost/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-mattermost +description: A Helm chart for the Teleport Mattermost Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/mattermost/README.md b/examples/chart/access/mattermost/README.md new file mode 100644 index 0000000000000..f18c02893fe19 --- /dev/null +++ b/examples/chart/access/mattermost/README.md @@ -0,0 +1,100 @@ +# Teleport Access Request Mattermost Plugin + +This chart sets up and configures a Deployment for the Access Request Mattermost plugin. + +## Installation + +See the [Access Requests with Mattermost guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-mattermost/). + +## Settings + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"yes
mattermost.urlURL of the Mattermost serverstring""yes
mattermost.tokenToken to be used to authenticate with Mattermoststring""yes
mattermost.tokenFromSecretKubernetes secret to read the token from instead of mattermost.tokenstring""no
mattermost.tokenSecretPathThe path of the token in the secret described by mattermost.tokenFromSecretstring"mattermostToken"no
mattermost.recipientsArray of the recipients the plugin should send access requests to.array[]yes
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/mattermost.log" + string"stdout"no
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"no
diff --git a/examples/chart/access/mattermost/templates/_helpers.tpl b/examples/chart/access/mattermost/templates/_helpers.tpl new file mode 100644 index 0000000000000..dca7e6f2b2a9a --- /dev/null +++ b/examples/chart/access/mattermost/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "mattermost.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "mattermost.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "mattermost.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "mattermost.labels" -}} +helm.sh/chart: {{ include "mattermost.chart" . }} +{{ include "mattermost.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "mattermost.selectorLabels" -}} +app.kubernetes.io/name: {{ include "mattermost.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "mattermost.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "mattermost.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/mattermost/templates/configmap.yaml b/examples/chart/access/mattermost/templates/configmap.yaml new file mode 100644 index 0000000000000..d5d39e3ad6b88 --- /dev/null +++ b/examples/chart/access/mattermost/templates/configmap.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mattermost.fullname" . }} + labels: + {{- include "mattermost.labels" . | nindent 4 }} +data: + teleport-mattermost.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/mattermost/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [mattermost] + url = "{{ .Values.mattermost.url }}" + token = "/var/lib/teleport/plugins/mattermost/mattermost_token" + recipients = {{ .Values.mattermost.recipients | toJson }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/mattermost/templates/deployment.yaml b/examples/chart/access/mattermost/templates/deployment.yaml new file mode 100644 index 0000000000000..dc8364eb72be5 --- /dev/null +++ b/examples/chart/access/mattermost/templates/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mattermost.fullname" . }} + labels: + {{- include "mattermost.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "mattermost.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "mattermost.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-mattermost.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-mattermost.toml + subPath: teleport-mattermost.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/mattermost/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: /var/lib/teleport/plugins/mattermost/mattermost_token + subPath: {{ .Values.mattermost.tokenSecretPath }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "mattermost.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.mattermost.tokenFromSecret (printf "%s-secret" (include "mattermost.fullname" .)) }}" + defaultMode: 0600 diff --git a/examples/chart/access/mattermost/templates/secret.yaml b/examples/chart/access/mattermost/templates/secret.yaml new file mode 100644 index 0000000000000..a8424bf5be015 --- /dev/null +++ b/examples/chart/access/mattermost/templates/secret.yaml @@ -0,0 +1,9 @@ +{{- if not .Values.mattermost.tokenFromSecret -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "mattermost.fullname" . }}-secret +data: + mattermostToken: {{ .Values.mattermost.token | b64enc }} +{{- end }} diff --git a/examples/chart/access/mattermost/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/mattermost/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..6ab917801373c --- /dev/null +++ b/examples/chart/access/mattermost/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,27 @@ +should match the snapshot: + 1: | + apiVersion: v1 + data: + teleport-mattermost.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/mattermost/teleport-identity/auth_id" + refresh_identity = true + + [mattermost] + url = "https://my.mattermost.com" + token = "/var/lib/teleport/plugins/mattermost/mattermost_token" + recipients = ["security@example.com"] + + [log] + output = "/var/log/teleport-mattermost.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-mattermost diff --git a/examples/chart/access/mattermost/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/mattermost/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..be17428e74acb --- /dev/null +++ b/examples/chart/access/mattermost/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,204 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-mattermost + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-mattermost + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-mattermost.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-mattermost + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-mattermost.toml + name: config + subPath: teleport-mattermost.toml + - mountPath: /var/lib/teleport/plugins/mattermost/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/mattermost/mattermost_token + name: password-file + subPath: mattermostToken + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-mattermost + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-mattermost-secret +should mount external secret: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-mattermost + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-mattermost + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-mattermost.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-mattermost:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-mattermost + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-mattermost.toml + name: config + subPath: teleport-mattermost.toml + - mountPath: /var/lib/teleport/plugins/mattermost/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/mattermost/mattermost_token + name: password-file + subPath: my-token-in-secret + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-mattermost + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: my-mattermost-secret +should override volume name: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-mattermost + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-mattermost + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-mattermost + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-mattermost-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-mattermost.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: public.ecr.aws/gravitational/teleport-plugin-mattermost:16.0.0-dev + imagePullPolicy: IfNotPresent + name: teleport-plugin-mattermost + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-mattermost.toml + name: config + subPath: teleport-mattermost.toml + - mountPath: /var/lib/teleport/plugins/mattermost/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/mattermost/mattermost_token + name: my-secret-volume + subPath: mattermostToken + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-mattermost + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: my-secret-volume + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-mattermost-secret diff --git a/examples/chart/access/mattermost/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/mattermost/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..34417cb24b661 --- /dev/null +++ b/examples/chart/access/mattermost/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should contain the token: + 1: | + apiVersion: v1 + data: + mattermostToken: bXltYXR0ZXJtb3N0dG9rZW4= + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-mattermost-secret + type: Opaque diff --git a/examples/chart/access/mattermost/tests/configmap_test.yaml b/examples/chart/access/mattermost/tests/configmap_test.yaml new file mode 100644 index 0000000000000..fc1b7234458cb --- /dev/null +++ b/examples/chart/access/mattermost/tests/configmap_test.yaml @@ -0,0 +1,18 @@ +suite: Test deployment +templates: + - configmap.yaml +tests: + - it: should match the snapshot + set: + teleport: + address: teleport.example.com:1234 + mattermost: + url: https://my.mattermost.com + token: test-mattermost-token + recipients: + - security@example.com + log: + output: /var/log/teleport-mattermost.log + severity: DEBUG + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/mattermost/tests/deployment_test.yaml b/examples/chart/access/mattermost/tests/deployment_test.yaml new file mode 100644 index 0000000000000..c0e8b376ba857 --- /dev/null +++ b/examples/chart/access/mattermost/tests/deployment_test.yaml @@ -0,0 +1,25 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} + + - it: should mount external secret + set: + mattermost: + tokenFromSecret: my-mattermost-secret + tokenSecretPath: my-token-in-secret + asserts: + - matchSnapshot: {} + + - it: should override volume name + set: + secretVolumeName: my-secret-volume + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/mattermost/tests/secret_test.yaml b/examples/chart/access/mattermost/tests/secret_test.yaml new file mode 100644 index 0000000000000..845c8ed88d6c2 --- /dev/null +++ b/examples/chart/access/mattermost/tests/secret_test.yaml @@ -0,0 +1,18 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should contain the token + set: + mattermost: + token: mymattermosttoken + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + mattermost: + tokenFromSecret: my-mattermost-secret + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/mattermost/values.schema.json b/examples/chart/access/mattermost/values.schema.json new file mode 100644 index 0000000000000..15a8cc8974fdd --- /dev/null +++ b/examples/chart/access/mattermost/values.schema.json @@ -0,0 +1,407 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "mattermost", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-mattermost", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-mattermost", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-mattermost" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-mattermost-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "mattermost": { + "$id": "#/properties/mattermost", + "type": "object", + "default": {}, + "examples": [ + { + "url": "https://my.mattermost.com/", + "token": "example-token", + "recipients": [ + "mattermost-user@example.com" + ] + } + ], + "required": [ + "url", + "token", + "recipients" + ], + "properties": { + "url": { + "$id": "#/properties/mattermost/properties/url", + "type": "string", + "default": "", + "examples": [ + "https://my.mattermost.com/" + ] + }, + "token": { + "$id": "#/properties/mattermost/properties/token", + "type": "string", + "default": "", + "examples": [ + "example-token" + ] + }, + "tokenFromSecret": { + "$id": "#/properties/mattermost/properties/tokenFromSecret", + "type": "string", + "default": "", + "examples": [ + "my-mattermost-secret" + ] + }, + "tokenSecretPath": { + "$id": "#/properties/mattermost/properties/tokenSecretPath", + "type": "string", + "default": "pagerdutyApiKey", + "examples": [ + "pagerdutyApiKey" + ] + }, + "recipients": { + "$id": "#/properties/mattermost/properties/recipients", + "type": "array", + "default": [], + "examples": [ + [ + "mattermost-user@example.com" + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/mattermost/properties/recipients/items", + "anyOf": [ + { + "$id": "#/properties/mattermost/properties/recipients/items/anyOf/0", + "type": "string", + "default": "", + "examples": [ + "mattermost-user@example.com" + ] + } + ] + } + } + }, + "additionalProperties": true + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/mattermost/values.yaml b/examples/chart/access/mattermost/values.yaml new file mode 100644 index 0000000000000..2911bb7d71aac --- /dev/null +++ b/examples/chart/access/mattermost/values.yaml @@ -0,0 +1,61 @@ +# Default values for mattermost. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +mattermost: + url: "" + token: "" + tokenFromSecret: "" + tokenSecretPath: "mattermostToken" + recipients: [] + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" + +image: + repository: public.ecr.aws/gravitational/teleport-plugin-mattermost + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/chart/access/msteams/.helmignore b/examples/chart/access/msteams/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/msteams/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/msteams/Chart.yaml b/examples/chart/access/msteams/Chart.yaml new file mode 100644 index 0000000000000..74b1368b56669 --- /dev/null +++ b/examples/chart/access/msteams/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-msteams +description: A Helm chart for the Teleport MsTeams Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/msteams/README.md b/examples/chart/access/msteams/README.md new file mode 100644 index 0000000000000..a427a6fdf5f3d --- /dev/null +++ b/examples/chart/access/msteams/README.md @@ -0,0 +1,7 @@ +# Teleport Access Request MsTeams Plugin + +This chart sets up and configures a Deployment for the Access Request MsTeams plugin. + +## Installation + +See the [Access Requests with Microsoft Teams guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-msteams/). \ No newline at end of file diff --git a/examples/chart/access/msteams/templates/_helpers.tpl b/examples/chart/access/msteams/templates/_helpers.tpl new file mode 100644 index 0000000000000..788a5556d6580 --- /dev/null +++ b/examples/chart/access/msteams/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "msteams.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "msteams.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "msteams.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "msteams.labels" -}} +helm.sh/chart: {{ include "msteams.chart" . }} +{{ include "msteams.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "msteams.selectorLabels" -}} +app.kubernetes.io/name: {{ include "msteams.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "msteams.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "msteams.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/msteams/templates/configmap.yaml b/examples/chart/access/msteams/templates/configmap.yaml new file mode 100644 index 0000000000000..1b4a50848b1ca --- /dev/null +++ b/examples/chart/access/msteams/templates/configmap.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "msteams.fullname" . }} + labels: + {{- include "msteams.labels" . | nindent 4 }} +data: + teleport-msteams.toml: | + preload = true + + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/msteams/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [msapi] + app_id = "{{ .Values.msTeams.appID }}" + tenant_id = "{{ .Values.msTeams.tenantID }}" + teams_app_id = "{{ .Values.msTeams.teamsAppID }}" + app_secret = "/var/lib/teleport/plugins/msteams/appSecret" + + [role_to_recipients] + {{- range $role, $recipients := .Values.roleToRecipients }} + {{ $role | toJson }} = {{ $recipients | toJson }} + {{- end }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/msteams/templates/deployment.yaml b/examples/chart/access/msteams/templates/deployment.yaml new file mode 100644 index 0000000000000..9920429b5f607 --- /dev/null +++ b/examples/chart/access/msteams/templates/deployment.yaml @@ -0,0 +1,76 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "msteams.fullname" . }} + labels: + {{- include "msteams.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "msteams.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "msteams.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-msteams.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-msteams.toml + subPath: teleport-msteams.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/msteams/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: /var/lib/teleport/plugins/msteams/appSecret + subPath: {{ .Values.msTeams.appSecretFromSecretKey }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "msteams.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.msTeams.appSecretFromSecret (printf "%s-secret" (include "msteams.fullname" .)) }}" + defaultMode: 0600 diff --git a/examples/chart/access/msteams/templates/secret.yaml b/examples/chart/access/msteams/templates/secret.yaml new file mode 100644 index 0000000000000..a9f3a445fa30a --- /dev/null +++ b/examples/chart/access/msteams/templates/secret.yaml @@ -0,0 +1,9 @@ +{{- if not .Values.msTeams.appSecretFromSecret -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "msteams.fullname" . }}-secret +data: + {{ .Values.msTeams.appSecretFromSecretKey | quote }}: {{ .Values.msTeams.appSecret | b64enc }} +{{- end }} diff --git a/examples/chart/access/msteams/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/msteams/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..b4dac111e84d0 --- /dev/null +++ b/examples/chart/access/msteams/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,34 @@ +should match the snapshot: + 1: | + apiVersion: v1 + data: + teleport-msteams.toml: | + preload = true + + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/msteams/teleport-identity/auth_id" + refresh_identity = true + + [msapi] + app_id = "my-app-id" + tenant_id = "my-tenant-id" + teams_app_id = "my-teams-app-id" + app_secret = "/var/lib/teleport/plugins/msteams/appSecret" + + [role_to_recipients] + "*" = ["dev-access-requests"] + "dev" = ["dev-access-requests","example-user@example.com"] + + [log] + output = "/var/log/teleport-msteams.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-msteams + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-msteams-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-msteams diff --git a/examples/chart/access/msteams/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/msteams/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..02e308382269b --- /dev/null +++ b/examples/chart/access/msteams/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,64 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-msteams + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-msteams-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-msteams + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-msteams + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-msteams + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-msteams-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-msteams.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-msteams + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-msteams.toml + name: config + subPath: teleport-msteams.toml + - mountPath: /var/lib/teleport/plugins/msteams/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/msteams/appSecret + name: password-file + subPath: appSecret + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-msteams + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-msteams-secret diff --git a/examples/chart/access/msteams/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/msteams/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..bc95c9fb6c4ef --- /dev/null +++ b/examples/chart/access/msteams/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should contain the api key: + 1: | + apiVersion: v1 + data: + appSecret: bXktYXBwLXNlY3JldA== + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-msteams-secret + type: Opaque diff --git a/examples/chart/access/msteams/tests/configmap_test.yaml b/examples/chart/access/msteams/tests/configmap_test.yaml new file mode 100644 index 0000000000000..ebb5c561d63ff --- /dev/null +++ b/examples/chart/access/msteams/tests/configmap_test.yaml @@ -0,0 +1,24 @@ +suite: Test deployment +templates: + - configmap.yaml +tests: + - it: should match the snapshot + set: + teleport: + address: teleport.example.com:1234 + msTeams: + appSecret: test-appSecret + appID: my-app-id + teamsAppID: my-teams-app-id + tenantID: my-tenant-id + roleToRecipients: + dev: + - dev-access-requests + - example-user@example.com + "*": + - dev-access-requests + log: + output: /var/log/teleport-msteams.log + severity: DEBUG + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/msteams/tests/deployment_test.yaml b/examples/chart/access/msteams/tests/deployment_test.yaml new file mode 100644 index 0000000000000..d5255e7c56e4c --- /dev/null +++ b/examples/chart/access/msteams/tests/deployment_test.yaml @@ -0,0 +1,11 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/msteams/tests/secret_test.yaml b/examples/chart/access/msteams/tests/secret_test.yaml new file mode 100644 index 0000000000000..2ff48f56eb7e7 --- /dev/null +++ b/examples/chart/access/msteams/tests/secret_test.yaml @@ -0,0 +1,18 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should contain the api key + set: + msTeams: + appSecret: my-app-secret + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + msTeams: + appSecretFromSecret: my-msteams-secret + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/msteams/values.schema.json b/examples/chart/access/msteams/values.schema.json new file mode 100644 index 0000000000000..5de30187520b7 --- /dev/null +++ b/examples/chart/access/msteams/values.schema.json @@ -0,0 +1,429 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "msTeams", + "teleport", + "roleToRecipients", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-msteams", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-msteams", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-msteams" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-msteams-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "msTeams": { + "$id": "#/properties/msTeams", + "type": "object", + "default": {}, + "examples": [ + { + "appID": "00112233-4455-6677-c899-aabbccddeeff", + "appSecret": "example-azure-secret", + "tenantID": "00112233-4455-6677-c899-aabbccddeeff", + "teamsAppID": "00112233-4455-6677-c899-aabbccddeeff" + } + ], + "required": [ + "appID", + "tenantID", + "teamsAppID", + "appSecret", + "appSecretFromSecret", + "appSecretFromSecretKey" + ], + "properties": { + "appID": { + "$id": "#/properties/msTeams/properties/appID", + "type": "string", + "default": "", + "examples": [ + "00112233-4455-6677-c899-aabbccddeeff" + ] + }, + "appSecret": { + "$id": "#/properties/msTeams/properties/appSecret", + "type": "string", + "default": "", + "examples": [ + "example-azure-secret" + ] + }, + "tenantID": { + "$id": "#/properties/msTeams/properties/tenantID", + "type": "string", + "default": "", + "examples": [ + "00112233-4455-6677-c899-aabbccddeeff" + ] + }, + "teamsAppID": { + "$id": "#/properties/msTeams/properties/teamsAppID", + "type": "string", + "default": "", + "examples": [ + "00112233-4455-6677-c899-aabbccddeeff" + ] + }, + "appSecretFromSecret": { + "$id": "#/properties/msTeams/properties/appSecretFromSecret", + "type": "string", + "default": "", + "examples": [ + "my-kubernetes-secret-name" + ] + }, + "appSecretFromSecretKey": { + "$id": "#/properties/msTeams/properties/appSecretFromSecretKey", + "type": "string", + "default": "appSecret", + "examples": [ + "appSecret" + ] + } + }, + "additionalProperties": false + }, + "roleToRecipients": { + "$id": "#/properties/roleToRecipients", + "type": "object", + "default": {}, + "examples": [ + { + "dev": [ + "devs-teams-channel" + ], + "*": [ + "admin@email.com", + "admin-teams-channel" + ] + } + ], + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "examples": [ + "example-teams-channel", + "user@example.com" + ] + }, + "minItems": 1 + } + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/msteams/values.yaml b/examples/chart/access/msteams/values.yaml new file mode 100644 index 0000000000000..58f050435bc3e --- /dev/null +++ b/examples/chart/access/msteams/values.yaml @@ -0,0 +1,69 @@ +# Default values for slack. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +msTeams: + appID: "" + tenantID: "" + teamsAppID: "" + # Use this value if you're passing the appSecret in the chart's values + appSecret: "" + # Use this value if you're passing the appSecret through an existing Kubernetes secret + appSecretFromSecret: "" + appSecretFromSecretKey: "appSecret" + +roleToRecipients: {} + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-msteams + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/chart/access/pagerduty/.helmignore b/examples/chart/access/pagerduty/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/pagerduty/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/pagerduty/Chart.yaml b/examples/chart/access/pagerduty/Chart.yaml new file mode 100644 index 0000000000000..51803aa17f42b --- /dev/null +++ b/examples/chart/access/pagerduty/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-pagerduty +description: A Helm chart for the Teleport Pagerduty Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/pagerduty/README.md b/examples/chart/access/pagerduty/README.md new file mode 100644 index 0000000000000..a02ad36e429b2 --- /dev/null +++ b/examples/chart/access/pagerduty/README.md @@ -0,0 +1,93 @@ +# Teleport Access Request PagerDuty Plugin + +This chart sets up and configures a Deployment for the Access Request PagerDuty plugin. + +## Installation + +See the [Access Requests with PagerDuty guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-pagerduty/). + +## Values + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"yes
pagerduty.apiKeyPagerDuty API Keystringyes
pagerduty.apiKeyFromSecretKubernetes secret to read the api key from instead of pagerduty.apiKeystring""no
pagerduty.apiKeySecretPathThe path of the api key in the secret described by pagerduty.apiKeyFromSecretstring"pagerdutyApiKey"no
pagerduty.userEmailPagerDuty bot user emailstring""yes
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/pagerduty.log" + string"stdout"no
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"no
diff --git a/examples/chart/access/pagerduty/templates/_helpers.tpl b/examples/chart/access/pagerduty/templates/_helpers.tpl new file mode 100644 index 0000000000000..ee4d235b04488 --- /dev/null +++ b/examples/chart/access/pagerduty/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "pagerduty.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "pagerduty.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "pagerduty.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "pagerduty.labels" -}} +helm.sh/chart: {{ include "pagerduty.chart" . }} +{{ include "pagerduty.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "pagerduty.selectorLabels" -}} +app.kubernetes.io/name: {{ include "pagerduty.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "pagerduty.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "pagerduty.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/pagerduty/templates/configmap.yaml b/examples/chart/access/pagerduty/templates/configmap.yaml new file mode 100644 index 0000000000000..40cf15fafa619 --- /dev/null +++ b/examples/chart/access/pagerduty/templates/configmap.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "pagerduty.fullname" . }} + labels: + {{- include "pagerduty.labels" . | nindent 4 }} +data: + teleport-pagerduty.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/pagerduty/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [pagerduty] + api_key = "/var/lib/teleport/plugins/pagerduty/pagerduty_api_key" + user_email = "{{ .Values.pagerduty.userEmail }}" + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/pagerduty/templates/deployment.yaml b/examples/chart/access/pagerduty/templates/deployment.yaml new file mode 100644 index 0000000000000..415b17d3db0e2 --- /dev/null +++ b/examples/chart/access/pagerduty/templates/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "pagerduty.fullname" . }} + labels: + {{- include "pagerduty.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "pagerduty.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "pagerduty.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-pagerduty.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-pagerduty.toml + subPath: teleport-pagerduty.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/pagerduty/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: /var/lib/teleport/plugins/pagerduty/pagerduty_api_key + subPath: {{ .Values.pagerduty.apiKeySecretPath }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "pagerduty.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.pagerduty.apiKeyFromSecret (printf "%s-secret" (include "pagerduty.fullname" .)) }}" + defaultMode: 0600 diff --git a/examples/chart/access/pagerduty/templates/secret.yaml b/examples/chart/access/pagerduty/templates/secret.yaml new file mode 100644 index 0000000000000..64bb4fa4aa292 --- /dev/null +++ b/examples/chart/access/pagerduty/templates/secret.yaml @@ -0,0 +1,9 @@ +{{- if not .Values.pagerduty.apiKeyFromSecret -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "pagerduty.fullname" . }}-secret +data: + pagerdutyApiKey: {{ .Values.pagerduty.apiKey | b64enc }} +{{- end }} diff --git a/examples/chart/access/pagerduty/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/pagerduty/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..3bedd4638ad2b --- /dev/null +++ b/examples/chart/access/pagerduty/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,26 @@ +should match the snapshot (smtp on): + 1: | + apiVersion: v1 + data: + teleport-pagerduty.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/pagerduty/teleport-identity/auth_id" + refresh_identity = true + + [pagerduty] + api_key = "/var/lib/teleport/plugins/pagerduty/pagerduty_api_key" + user_email = "example-user@example.com" + + [log] + output = "/var/log/teleport-pagerduty.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-pagerduty + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-pagerduty-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-pagerduty diff --git a/examples/chart/access/pagerduty/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/pagerduty/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..f67badbbcd0f6 --- /dev/null +++ b/examples/chart/access/pagerduty/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,68 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-pagerduty + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-pagerduty-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-pagerduty + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-pagerduty + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-pagerduty + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-pagerduty-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-pagerduty.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-pagerduty + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-pagerduty.toml + name: config + subPath: teleport-pagerduty.toml + - mountPath: /var/lib/teleport/plugins/pagerduty/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/pagerduty/pagerduty_api_key + name: password-file + subPath: pagerdutyApiKey + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-pagerduty + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-pagerduty-secret diff --git a/examples/chart/access/pagerduty/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/pagerduty/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..62d4a7d9e6434 --- /dev/null +++ b/examples/chart/access/pagerduty/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should contain the api key: + 1: | + apiVersion: v1 + data: + pagerdutyApiKey: bXlwYWdlcmR1dHlhcGlrZXk= + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-pagerduty-secret + type: Opaque diff --git a/examples/chart/access/pagerduty/tests/configmap_test.yaml b/examples/chart/access/pagerduty/tests/configmap_test.yaml new file mode 100644 index 0000000000000..3c5ca7ed75082 --- /dev/null +++ b/examples/chart/access/pagerduty/tests/configmap_test.yaml @@ -0,0 +1,16 @@ +suite: Test deployment +templates: + - configmap.yaml +tests: + - it: should match the snapshot (smtp on) + set: + teleport: + address: teleport.example.com:1234 + pagerduty: + apiKey: test-api-key + userEmail: example-user@example.com + log: + output: /var/log/teleport-pagerduty.log + severity: DEBUG + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/pagerduty/tests/deployment_test.yaml b/examples/chart/access/pagerduty/tests/deployment_test.yaml new file mode 100644 index 0000000000000..d5255e7c56e4c --- /dev/null +++ b/examples/chart/access/pagerduty/tests/deployment_test.yaml @@ -0,0 +1,11 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} diff --git a/examples/chart/access/pagerduty/tests/secret_test.yaml b/examples/chart/access/pagerduty/tests/secret_test.yaml new file mode 100644 index 0000000000000..789a06bcd0a12 --- /dev/null +++ b/examples/chart/access/pagerduty/tests/secret_test.yaml @@ -0,0 +1,18 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should contain the api key + set: + pagerduty: + apiKey: mypagerdutyapikey + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + pagerduty: + apiKeyFromSecret: my-pagerduty-secret + asserts: + - hasDocuments: + count: 0 diff --git a/examples/chart/access/pagerduty/values.schema.json b/examples/chart/access/pagerduty/values.schema.json new file mode 100644 index 0000000000000..b12bd3e2a17e0 --- /dev/null +++ b/examples/chart/access/pagerduty/values.schema.json @@ -0,0 +1,379 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "pagerduty", + "log" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-pagerduty", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-pagerduty", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-pagerduty" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-pagerduty-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "pagerduty": { + "$id": "#/properties/pagerduty", + "type": "object", + "default": {}, + "examples": [ + { + "apiKey": "example-api-key", + "userEmail": "pagerduty-bot-user@example.com" + } + ], + "required": [ + "apiKey", + "userEmail" + ], + "properties": { + "apiKey": { + "$id": "#/properties/pagerduty/properties/apiKey", + "type": "string", + "default": "", + "examples": [ + "example-api-key" + ] + }, + "apiKeyFromSecret": { + "$id": "#/properties/pagerduty/properties/apiKeyFromSecret", + "type": "string", + "default": "", + "examples": [ + "my-pagerduty-secret" + ] + }, + "apiKeySecretPath": { + "$id": "#/properties/pagerduty/properties/apiKeySecretPath", + "type": "string", + "default": "pagerdutyApiKey", + "examples": [ + "apikey" + ] + }, + "userEmail": { + "$id": "#/properties/pagerduty/properties/userEmail", + "type": "string", + "default": "", + "examples": [ + "pagerduty-bot-user@example.com" + ] + } + }, + "additionalProperties": true + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/pagerduty/values.yaml b/examples/chart/access/pagerduty/values.yaml new file mode 100644 index 0000000000000..5523d19f93f63 --- /dev/null +++ b/examples/chart/access/pagerduty/values.yaml @@ -0,0 +1,63 @@ +# Default values for pagerduty. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +pagerduty: + apiKey: "" + apiKeyFromSecret: "" + apiKeySecretPath: "pagerdutyApiKey" + userEmail: "" + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-pagerduty + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/chart/access/slack/.helmignore b/examples/chart/access/slack/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/access/slack/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/access/slack/Chart.yaml b/examples/chart/access/slack/Chart.yaml new file mode 100644 index 0000000000000..08931a6297d63 --- /dev/null +++ b/examples/chart/access/slack/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-slack +description: A Helm chart for the Teleport Slack Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/access/slack/README.md b/examples/chart/access/slack/README.md new file mode 100644 index 0000000000000..634f3c23d60d4 --- /dev/null +++ b/examples/chart/access/slack/README.md @@ -0,0 +1,137 @@ +# Teleport Access Request Slack Plugin + +This chart sets up and configures a Deployment for the Access Request Slack plugin. + +## Installation + +See the [Access Requests with Slack guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-slack/). + +## Values + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"yes
slack.tokenSlack API tokenstring""yes
slack.tokenFromSecretKubernetes secret to read the token from instead of slack.tokenstring""no
slack.tokenSecretPathThe path of the token in the secret described by slack.tokenFromSecretstring"slackToken"no
roleToRecipients + Mapping of roles to a list of channels and Slack emails.
+ Example: +
+"dev" = ["dev-access-requests", "user@example.com"]
+"*" = ["access-requests"]
+
map{}yes
log.output + Logger output. Could be "stdout", "stderr" or a file name, + eg. "/var/lib/teleport/slack.log" + string"stdout"no
log.severity + Logger severity. Possible values are "INFO", "ERROR", + "DEBUG" or "WARN". + string"INFO"no
annotations.config + Annotations to add to the configmap. + map{}no
annotations.deployment + Annotations to add to the deployment. + map{}no
annotations.pod + Annotations to add to every pod created by the deployment. + map{}no
annotations.secret + Annotations to add to the secret. + map{}no
diff --git a/examples/chart/access/slack/templates/_helpers.tpl b/examples/chart/access/slack/templates/_helpers.tpl new file mode 100644 index 0000000000000..0bdb4df89fa95 --- /dev/null +++ b/examples/chart/access/slack/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "slack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "slack.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "slack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "slack.labels" -}} +helm.sh/chart: {{ include "slack.chart" . }} +{{ include "slack.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "slack.selectorLabels" -}} +app.kubernetes.io/name: {{ include "slack.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "slack.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "slack.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/access/slack/templates/configmap.yaml b/examples/chart/access/slack/templates/configmap.yaml new file mode 100644 index 0000000000000..3291b05da7a92 --- /dev/null +++ b/examples/chart/access/slack/templates/configmap.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "slack.fullname" . }} + {{- with .Values.annotations.config }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "slack.labels" . | nindent 4 }} +data: + teleport-slack.toml: | + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/slack/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh_identity = true + + [slack] + token = "/var/lib/teleport/plugins/slack/slack-token" + + [role_to_recipients] + {{- range $role, $recipients := .Values.roleToRecipients }} + {{ $role | toJson }} = {{ $recipients | toJson }} + {{- end }} + + [log] + output = "{{ .Values.log.output }}" + severity = "{{ .Values.log.severity }}" diff --git a/examples/chart/access/slack/templates/deployment.yaml b/examples/chart/access/slack/templates/deployment.yaml new file mode 100644 index 0000000000000..ccf714cfea6af --- /dev/null +++ b/examples/chart/access/slack/templates/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "slack.fullname" . }} + {{- with .Values.annotations.deployment }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "slack.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "slack.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with or .Values.annotations.pod .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "slack.labels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-plugin + - start + - "--config" + - "/etc/teleport-slack.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-slack.toml + subPath: teleport-slack.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/slack/teleport-identity + - name: {{ .Values.secretVolumeName }} + mountPath: /var/lib/teleport/plugins/slack/slack-token + subPath: {{ .Values.slack.tokenSecretPath }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "slack.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: {{ .Values.secretVolumeName }} + secret: + secretName: "{{ coalesce .Values.slack.tokenFromSecret (printf "%s-secret" (include "slack.fullname" .)) }}" + defaultMode: 0600 diff --git a/examples/chart/access/slack/templates/secret.yaml b/examples/chart/access/slack/templates/secret.yaml new file mode 100644 index 0000000000000..c21021a0e40ce --- /dev/null +++ b/examples/chart/access/slack/templates/secret.yaml @@ -0,0 +1,13 @@ +{{- if not .Values.slack.tokenFromSecret -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ include "slack.fullname" . }}-secret + {{- with .Values.annotations.secret }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + slackToken: {{ .Values.slack.token | b64enc }} +{{- end }} diff --git a/examples/chart/access/slack/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/access/slack/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..8a90d9bb860c5 --- /dev/null +++ b/examples/chart/access/slack/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,29 @@ +should match the snapshot: + 1: | + apiVersion: v1 + data: + teleport-slack.toml: | + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/slack/teleport-identity/auth_id" + refresh_identity = true + + [slack] + token = "/var/lib/teleport/plugins/slack/slack-token" + + [role_to_recipients] + "*" = ["dev-access-requests"] + "dev" = ["dev-access-requests","example-user@example.com"] + + [log] + output = "/var/log/teleport-slack.log" + severity = "DEBUG" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-slack + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-slack-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-slack diff --git a/examples/chart/access/slack/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/access/slack/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..6c41deaaaf230 --- /dev/null +++ b/examples/chart/access/slack/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,64 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-slack + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-slack-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-slack + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-slack + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-slack + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-slack-16.0.0-dev + spec: + containers: + - command: + - /usr/local/bin/teleport-plugin + - start + - --config + - /etc/teleport-slack.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-slack + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-slack.toml + name: config + subPath: teleport-slack.toml + - mountPath: /var/lib/teleport/plugins/slack/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/slack/slack-token + name: password-file + subPath: slackToken + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-slack + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: password-file + secret: + defaultMode: 384 + secretName: RELEASE-NAME-teleport-plugin-slack-secret diff --git a/examples/chart/access/slack/tests/__snapshot__/secret_test.yaml.snap b/examples/chart/access/slack/tests/__snapshot__/secret_test.yaml.snap new file mode 100644 index 0000000000000..2702fe141ab70 --- /dev/null +++ b/examples/chart/access/slack/tests/__snapshot__/secret_test.yaml.snap @@ -0,0 +1,9 @@ +should contain the api key: + 1: | + apiVersion: v1 + data: + slackToken: bXlzbGFja3Rva2Vu + kind: Secret + metadata: + name: RELEASE-NAME-teleport-plugin-slack-secret + type: Opaque diff --git a/examples/chart/access/slack/tests/configmap_test.yaml b/examples/chart/access/slack/tests/configmap_test.yaml new file mode 100644 index 0000000000000..509479f784c44 --- /dev/null +++ b/examples/chart/access/slack/tests/configmap_test.yaml @@ -0,0 +1,39 @@ +suite: Test configmap +templates: + - configmap.yaml +tests: + - it: should match the snapshot + set: + teleport: + address: teleport.example.com:1234 + slack: + token: test-api-key + roleToRecipients: + dev: + - dev-access-requests + - example-user@example.com + "*": + - dev-access-requests + log: + output: /var/log/teleport-slack.log + severity: DEBUG + asserts: + - matchSnapshot: {} + + - it: should not contain annotations when not defined + asserts: + - isNull: + path: metadata.annotations + + - it: should contain annotations when defined + set: + annotations: + config: + keyA: valA + keyB: valB + asserts: + - equal: + path: metadata.annotations + value: + keyA: valA + keyB: valB diff --git a/examples/chart/access/slack/tests/deployment_test.yaml b/examples/chart/access/slack/tests/deployment_test.yaml new file mode 100644 index 0000000000000..8f2cde402536e --- /dev/null +++ b/examples/chart/access/slack/tests/deployment_test.yaml @@ -0,0 +1,69 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} + + - it: should not contain deployment or pod annotations when not defined + asserts: + - isNull: + path: metadata.annotations + - isNull: + path: spec.template.metadata.annotations + + - it: should contain deployment annotations when defined + set: + annotations: + deployment: + keyA: valA + keyB: valB + asserts: + - equal: + path: metadata.annotations + value: + keyA: valA + keyB: valB + - isNull: + path: spec.template.metadata.annotations + + - it: should contain pod annotations when defined + set: + annotations: + pod: + keyA: valA + keyB: valB + asserts: + - equal: + path: spec.template.metadata.annotations + value: + keyA: valA + keyB: valB + - isNull: + path: metadata.annotations + + - it: should contain both annotations when defined + set: + annotations: + deployment: + keyA: valA + keyB: valB + pod: + keyA: valA' + keyC: valC + asserts: + - equal: + path: metadata.annotations + value: + keyA: valA + keyB: valB + - equal: + path: spec.template.metadata.annotations + value: + keyA: valA' + keyC: valC diff --git a/examples/chart/access/slack/tests/secret_test.yaml b/examples/chart/access/slack/tests/secret_test.yaml new file mode 100644 index 0000000000000..c23a3ed907f14 --- /dev/null +++ b/examples/chart/access/slack/tests/secret_test.yaml @@ -0,0 +1,36 @@ +suite: Test secret +templates: + - secret.yaml +tests: + - it: should contain the api key + set: + slack: + token: myslacktoken + asserts: + - matchSnapshot: {} + + - it: should not exist when using external secret + set: + slack: + tokenFromSecret: my-slack-secret + asserts: + - hasDocuments: + count: 0 + + - it: should not contain annotations when not defined + asserts: + - isNull: + path: metadata.annotations + + - it: should contain annotations when defined + set: + annotations: + secret: + keyA: valA + keyB: valB + asserts: + - equal: + path: metadata.annotations + value: + keyA: valA + keyB: valB diff --git a/examples/chart/access/slack/values.schema.json b/examples/chart/access/slack/values.schema.json new file mode 100644 index 0000000000000..c868541d840d2 --- /dev/null +++ b/examples/chart/access/slack/values.schema.json @@ -0,0 +1,432 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "slack", + "roleToRecipients", + "log", + "annotations" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-slack", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-slack", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-slack" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-slack-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "slack": { + "$id": "#/properties/slack", + "type": "object", + "default": {}, + "examples": [ + { + "token": "example-api-token" + } + ], + "required": [ + "token", + "tokenFromSecret", + "tokenSecretPath" + ], + "properties": { + "token": { + "$id": "#/properties/slack/properties/token", + "type": "string", + "default": "", + "examples": [ + "example-api-token" + ] + }, + "tokenFromSecret": { + "$id": "#/properties/slack/properties/tokenFromSecret", + "type": "string", + "default": "", + "examples": [ + "slack-token" + ] + }, + "tokenSecretPath": { + "$id": "#/properties/slack/properties/tokenSecretPath", + "type": "string", + "default": "slackToken", + "examples": [ + "token" + ] + } + }, + "additionalProperties": true + }, + "roleToRecipients": { + "$id": "#/properties/roleToRecipients", + "type": "object", + "default": {}, + "examples": [ + { + "dev": [ + "devs-slack-channel" + ], + "*": [ + "admin@email.com", + "admin-slack-channel" + ] + } + ], + "additionalProperties": { + "type": "array", + "items": { + "type": "string", + "examples": [ + "example-slack-channel", + "user@example.com" + ] + }, + "minItems": 1 + } + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "default": {}, + "examples": [ + { + "output": "stdout", + "severity": "INFO" + } + ], + "required": [ + "output", + "severity" + ], + "properties": { + "output": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": "stdout", + "examples": [ + "stdout" + ] + }, + "severity": { + "$id": "#/properties/log/properties/severity", + "type": "string", + "default": "INFO", + "examples": [ + "INFO" + ] + } + }, + "additionalProperties": true + }, + "secretVolumeName": { + "$id": "#/properties/secretVolumeName", + "type": "string", + "default": "password-file", + "examples": [ + "my-secret-volume" + ] + }, + "annotations": { + "$id": "#/properties/annotations", + "type": "object", + "required": [ + "config", + "deployment", + "pod", + "secret" + ], + "properties": { + "config": { + "$id": "#/properties/annotations/properties/config", + "type": "object", + "default": {} + }, + "deployment": { + "$id": "#/properties/annotations/properties/deployment", + "type": "object", + "default": {} + }, + "pod": { + "$id": "#/properties/annotations/properties/pod", + "type": "object", + "default": {} + }, + "secret": { + "$id": "#/properties/annotations/properties/secret", + "type": "object", + "default": {} + } + } + } + }, + "additionalProperties": true +} diff --git a/examples/chart/access/slack/values.yaml b/examples/chart/access/slack/values.yaml new file mode 100644 index 0000000000000..c892625eec38c --- /dev/null +++ b/examples/chart/access/slack/values.yaml @@ -0,0 +1,77 @@ +# Default values for slack. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +slack: + token: "" + tokenFromSecret: "" + tokenSecretPath: "slackToken" + +roleToRecipients: {} + +log: + output: stdout + severity: INFO + +secretVolumeName: "password-file" + +# Kubernetes annotations to apply +# https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +annotations: + # Annotations for the ConfigMap + config: {} + # Annotations for the Deployment + deployment: {} + # Annotations for each Pod in the Deployment + pod: {} + # Annotations for the Secret + secret: {} + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-slack + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +# Deprecated way to set pod annotations. `annotations.pod` should be preferred. +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/examples/chart/event-handler/.helmignore b/examples/chart/event-handler/.helmignore new file mode 100644 index 0000000000000..0e8a0eb36f4ca --- /dev/null +++ b/examples/chart/event-handler/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/examples/chart/event-handler/Chart.yaml b/examples/chart/event-handler/Chart.yaml new file mode 100644 index 0000000000000..fa0449c8524d5 --- /dev/null +++ b/examples/chart/event-handler/Chart.yaml @@ -0,0 +1,8 @@ +.version: &version "16.0.0-dev" + +apiVersion: v2 +name: teleport-plugin-event-handler +description: A Helm chart for Teleport Event Handler Plugin +type: application +version: *version +appVersion: *version diff --git a/examples/chart/event-handler/README.md b/examples/chart/event-handler/README.md new file mode 100644 index 0000000000000..8b38b5c5eef2b --- /dev/null +++ b/examples/chart/event-handler/README.md @@ -0,0 +1,150 @@ +# Teleport Event Handler Plugin + +This chart sets up and configures a Deployment for the Event Handler plugin. + +## Installation + +See the [Access Requests with Slack guide](https://goteleport.com/docs/access-controls/access-request-plugins/ssh-approval-slack/). + +## Settings + +The following values can be set for the Helm chart: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameDescriptionTypeDefaultRequired
teleport.addressHost/port combination of the teleport auth serverstring""yes
teleport.identitySecretNameName of the Kubernetes secret that contains the credentials for the connectionstring""yes
teleport.identitySecretPathKey of the field in the secret specified by teleport.identitySecretNamestring"auth_id"no
eventHandler.storagePathPath to the directory where event-handler's state is storedstring"/var/lib/teleport/plugins/event-handler/storage"no
eventHandler.timeoutMaximum time to wait for incoming events before sending them to fluentd.string"10s"no
eventHandler.batchMaximum number of events fetched from Teleport in one requeststring20no
fluentd.urlURL of fluentd where the event logs will be sent to.string""yes
fluentd.sessionUrlURL of fluentd where the session logs will be sent to.string""yes
fluentd.secretName + Name of the secret where credentials for the connection is stored. + It must contain the client's private key, certificate and fluentd's + CA certificate. See the default paths below. + string""yes
fluentd.caPathPath of the CA certificate in the secret described by fluentd.secretName.string"ca.crt"
fluentd.certPathPath of the client's certificate in the secret described by fluentd.secretName.string"client.crt"no
fluentd.keyPathPath of the client private key in the secret described by fluentd.secretName.string"client.key"no
persistentVolumeClaim.enabled + Instructs the Helm chart to include a PersistentVolumeClaim for the storage. This storage + will be mounted to the path specified by eventHandler.storagePath. + booleanfalseno
persistentVolumeClaim.sizeSets the size of the created PersistentVolumeClaim. Don't forget to append the proper suffix!string"1Gi"no
persistentVolumeClaim.storageClassName + Sets the storage class name of the created PersistentVolumeClaim. Kubernetes will use the default + one when omitted. + string""no
persistentVolumeClaim.existingClaim + Specifies an already existing PersistentVolumeClaim which should be mounted to the path specified + by eventHandler.storagePath. persistentVolumeClaim.enabled must be set to false for this + option to take precedence. Ignored when persistentVolumeClaim.enabled is true. + string""no
diff --git a/examples/chart/event-handler/templates/_helpers.tpl b/examples/chart/event-handler/templates/_helpers.tpl new file mode 100644 index 0000000000000..450f1572d9973 --- /dev/null +++ b/examples/chart/event-handler/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "event-handler.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "event-handler.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "event-handler.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "event-handler.labels" -}} +helm.sh/chart: {{ include "event-handler.chart" . }} +{{ include "event-handler.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "event-handler.selectorLabels" -}} +app.kubernetes.io/name: {{ include "event-handler.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "event-handler.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "event-handler.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/examples/chart/event-handler/templates/configmap.yaml b/examples/chart/event-handler/templates/configmap.yaml new file mode 100644 index 0000000000000..3b25b17fc65b6 --- /dev/null +++ b/examples/chart/event-handler/templates/configmap.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "event-handler.fullname" . }} + labels: + {{- include "event-handler.labels" . | nindent 4 }} +data: + teleport-event-handler.toml: | + storage = {{ .Values.eventHandler.storagePath | toJson }} + timeout = {{ .Values.eventHandler.timeout | toJson }} + batch = {{ .Values.eventHandler.batch }} + + [teleport] + addr = "{{ .Values.teleport.address }}" + identity = "/var/lib/teleport/plugins/event-handler/teleport-identity/{{ .Values.teleport.identitySecretPath }}" + refresh.enabled = true + + [forward.fluentd] + url = "{{ .Values.fluentd.url }}" + session-url = "{{ .Values.fluentd.sessionUrl }}" + ca = "/var/lib/teleport/plugins/event-handler/ca.crt" + cert = "/var/lib/teleport/plugins/event-handler/client.crt" + key = "/var/lib/teleport/plugins/event-handler/client.key" diff --git a/examples/chart/event-handler/templates/deployment.yaml b/examples/chart/event-handler/templates/deployment.yaml new file mode 100644 index 0000000000000..fa21b4195e4f9 --- /dev/null +++ b/examples/chart/event-handler/templates/deployment.yaml @@ -0,0 +1,107 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "event-handler.fullname" . }} + labels: + {{- include "event-handler.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "event-handler.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "event-handler.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - /usr/local/bin/teleport-event-handler + - start + - "--config" + - "/etc/teleport-event-handler.toml" + env: + - name: "TELEPORT_PLUGIN_FAIL_FAST" + value: "true" + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /etc/teleport-event-handler.toml + subPath: teleport-event-handler.toml + - name: teleport-identity + mountPath: /var/lib/teleport/plugins/event-handler/teleport-identity + - name: certificate + mountPath: /var/lib/teleport/plugins/event-handler/ca.crt + subPath: {{ .Values.fluentd.certificate.caPath }} + - name: certificate + mountPath: /var/lib/teleport/plugins/event-handler/client.crt + subPath: {{ .Values.fluentd.certificate.certPath }} + - name: certificate + mountPath: /var/lib/teleport/plugins/event-handler/client.key + subPath: {{ .Values.fluentd.certificate.keyPath }} + {{- if or .Values.persistentVolumeClaim.enabled .Values.persistentVolumeClaim.existingClaim }} + - name: "{{ .Values.persistentVolumeClaim.volumeName }}" + mountPath: "{{ .Values.eventHandler.storagePath }}" + {{- end }} + {{- with .Values.volumeMounts -}} + {{- toYaml . | nindent 12 }} + {{- end}} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "event-handler.fullname" . }} + defaultMode: 0600 + - name: teleport-identity + secret: + secretName: "{{ .Values.teleport.identitySecretName }}" + defaultMode: 0600 + - name: certificate + secret: + secretName: "{{ .Values.fluentd.certificate.secretName }}" + defaultMode: 0600 + {{- if .Values.persistentVolumeClaim.enabled }} + - name: "{{ .Values.persistentVolumeClaim.volumeName }}" + persistentVolumeClaim: + claimName: {{ include "event-handler.fullname" . }} + {{- else }} + {{- if .Values.persistentVolumeClaim.existingClaim }} + - name: "{{ .Values.persistentVolumeClaim.volumeName }}" + persistentVolumeClaim: + claimName: {{ .Values.persistentVolumeClaim.existingClaim }} + {{- end }} + {{- end }} + {{- with .Values.volumes -}} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/examples/chart/event-handler/templates/pvc.yaml b/examples/chart/event-handler/templates/pvc.yaml new file mode 100644 index 0000000000000..8dc8265519b39 --- /dev/null +++ b/examples/chart/event-handler/templates/pvc.yaml @@ -0,0 +1,17 @@ +{{- if .Values.persistentVolumeClaim.enabled -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "event-handler.fullname" . }} + labels: + {{- include "event-handler.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + {{- if .Values.persistentVolumeClaim.storageClassName }} + storageClassName: "{{ .Values.persistentVolumeClaim.storageClassName }}" + {{- end }} + resources: + requests: + storage: {{ .Values.persistentVolumeClaim.size }} +{{- end -}} diff --git a/examples/chart/event-handler/tests/__snapshot__/configmap_test.yaml.snap b/examples/chart/event-handler/tests/__snapshot__/configmap_test.yaml.snap new file mode 100644 index 0000000000000..d8a7601b0aa36 --- /dev/null +++ b/examples/chart/event-handler/tests/__snapshot__/configmap_test.yaml.snap @@ -0,0 +1,29 @@ +should match the snapshot: + 1: | + apiVersion: v1 + data: + teleport-event-handler.toml: | + storage = "/var/lib/teleport/plugins/event-handler/storage" + timeout = "10s" + batch = 20 + + [teleport] + addr = "teleport.example.com:1234" + identity = "/var/lib/teleport/plugins/event-handler/teleport-identity/auth_id" + refresh.enabled = true + + [forward.fluentd] + url = "https://fluentd:8888/test.log" + session-url = "https://fluentd:8888/session" + ca = "/var/lib/teleport/plugins/event-handler/ca.crt" + cert = "/var/lib/teleport/plugins/event-handler/client.crt" + key = "/var/lib/teleport/plugins/event-handler/client.key" + kind: ConfigMap + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-event-handler + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-event-handler-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-event-handler diff --git a/examples/chart/event-handler/tests/__snapshot__/deployment_test.yaml.snap b/examples/chart/event-handler/tests/__snapshot__/deployment_test.yaml.snap new file mode 100644 index 0000000000000..d8892687bf2a7 --- /dev/null +++ b/examples/chart/event-handler/tests/__snapshot__/deployment_test.yaml.snap @@ -0,0 +1,71 @@ +should match the snapshot: + 1: | + apiVersion: apps/v1 + kind: Deployment + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: teleport-plugin-event-handler + app.kubernetes.io/version: 16.0.0-dev + helm.sh/chart: teleport-plugin-event-handler-16.0.0-dev + name: RELEASE-NAME-teleport-plugin-event-handler + spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-event-handler + template: + metadata: + labels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: teleport-plugin-event-handler + spec: + containers: + - command: + - /usr/local/bin/teleport-event-handler + - start + - --config + - /etc/teleport-event-handler.toml + env: + - name: TELEPORT_PLUGIN_FAIL_FAST + value: "true" + image: gcr.io/overridden/repository:v98.76.54 + imagePullPolicy: IfNotPresent + name: teleport-plugin-event-handler + ports: + - containerPort: 80 + name: http + protocol: TCP + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /etc/teleport-event-handler.toml + name: config + subPath: teleport-event-handler.toml + - mountPath: /var/lib/teleport/plugins/event-handler/teleport-identity + name: teleport-identity + - mountPath: /var/lib/teleport/plugins/event-handler/ca.crt + name: certificate + subPath: ca.crt + - mountPath: /var/lib/teleport/plugins/event-handler/client.crt + name: certificate + subPath: client.crt + - mountPath: /var/lib/teleport/plugins/event-handler/client.key + name: certificate + subPath: client.key + securityContext: {} + volumes: + - configMap: + defaultMode: 384 + name: RELEASE-NAME-teleport-plugin-event-handler + name: config + - name: teleport-identity + secret: + defaultMode: 384 + secretName: "" + - name: certificate + secret: + defaultMode: 384 + secretName: "" diff --git a/examples/chart/event-handler/tests/configmap_test.yaml b/examples/chart/event-handler/tests/configmap_test.yaml new file mode 100644 index 0000000000000..2142f7f2cc6f1 --- /dev/null +++ b/examples/chart/event-handler/tests/configmap_test.yaml @@ -0,0 +1,18 @@ +suite: Test deployment +templates: + - configmap.yaml +tests: + - it: should match the snapshot + set: + teleport: + address: teleport.example.com:1234 + fluentd: + url: https://fluentd:8888/test.log + sessionUrl: https://fluentd:8888/session + certificate: + secretName: event-handler-fluentd-credentials + caPath: myca.crt + certPath: myclient.crt + keyPath: myclient.key + asserts: + - matchSnapshot: {} diff --git a/examples/chart/event-handler/tests/deployment_test.yaml b/examples/chart/event-handler/tests/deployment_test.yaml new file mode 100644 index 0000000000000..d5255e7c56e4c --- /dev/null +++ b/examples/chart/event-handler/tests/deployment_test.yaml @@ -0,0 +1,11 @@ +suite: Test deployment +templates: + - deployment.yaml +tests: + - it: should match the snapshot + set: + image: + repository: gcr.io/overridden/repository + tag: v98.76.54 + asserts: + - matchSnapshot: {} diff --git a/examples/chart/event-handler/values.schema.json b/examples/chart/event-handler/values.schema.json new file mode 100644 index 0000000000000..fe79488c73087 --- /dev/null +++ b/examples/chart/event-handler/values.schema.json @@ -0,0 +1,503 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://example.com/example.json", + "default": {}, + "required": [ + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "podAnnotations", + "podSecurityContext", + "securityContext", + "nodeSelector", + "tolerations", + "affinity", + "teleport", + "fluentd" + ], + "properties": { + "image": { + "$id": "#/properties/image", + "type": "object", + "default": {}, + "examples": [ + { + "repository": "public.ecr.aws/gravitational/teleport-plugin-event-handler", + "pullPolicy": "IfNotPresent", + "tag": "" + } + ], + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "$id": "#/properties/image/properties/repository", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-plugin-event-handler", + "examples": [ + "public.ecr.aws/gravitational/teleport-plugin-event-handler" + ] + }, + "pullPolicy": { + "$id": "#/properties/image/properties/pullPolicy", + "type": "string", + "default": "IfNotPresent", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "$id": "#/properties/image/properties/tag", + "type": "string", + "default": "" + } + }, + "additionalProperties": true + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [], + "examples": [ + [ + { + "name": "image-pull-secrets" + } + ] + ], + "additionalItems": true, + "items": { + "$id": "#/properties/imagePullSecrets/items" + } + }, + "nameOverride": { + "$id": "#/properties/nameOverride", + "type": "string", + "default": "" + }, + "fullnameOverride": { + "$id": "#/properties/fullnameOverride", + "type": "string", + "default": "" + }, + "podAnnotations": { + "$id": "#/properties/podAnnotations", + "type": "object", + "additionalProperties": true + }, + "podSecurityContext": { + "$id": "#/properties/podSecurityContext", + "type": "object", + "required": [], + "additionalProperties": true + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "properties": { + "capabilities": { + "$id": "#/properties/securityContext/properties/capabilities", + "type": "object", + "additionalProperties": true + }, + "readOnlyRootFilesystem": { + "$id": "#/properties/securityContext/properties/readOnlyRootFilesystem", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsNonRoot": { + "$id": "#/properties/securityContext/properties/runAsNonRoot", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "runAsUser": { + "$id": "#/properties/securityContext/properties/runAsUser", + "type": "integer", + "default": 0, + "examples": [ + 1000 + ] + } + }, + "additionalProperties": true + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "properties": { + "limits": { + "$id": "#/properties/resources/properties/limits", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/limits/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/limits/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + }, + "requests": { + "$id": "#/properties/resources/properties/requests", + "type": "object", + "default": {}, + "examples": [ + { + "cpu": "100m", + "memory": "128Mi" + } + ], + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "$id": "#/properties/resources/properties/requests/properties/cpu", + "type": "string", + "default": "", + "examples": [ + "100m" + ] + }, + "memory": { + "$id": "#/properties/resources/properties/requests/properties/memory", + "type": "string", + "default": "", + "examples": [ + "128Mi" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [], + "additionalItems": true, + "items": { + "$id": "#/properties/tolerations/items" + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {}, + "additionalProperties": true + }, + "volumes": { + "$id": "#/properties/volumes", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumes/items", + "type": "object", + "additionalItems": true + } + }, + "volumeMounts": { + "$id": "#/properties/volumeMounts", + "type": "array", + "default": [], + "items": { + "$id": "#/properties/volumeMounts/items", + "type": "object", + "additionalItems": true + } + }, + "teleport": { + "$id": "#/properties/teleport", + "type": "object", + "default": {}, + "examples": [ + { + "address": "auth.example.com:3025", + "identitySecretName": "teleport-plugin-event-handler-auth-id", + "identitySecretPath": "auth_id" + } + ], + "required": [ + "address", + "identitySecretName", + "identitySecretPath" + ], + "properties": { + "address": { + "$id": "#/properties/teleport/properties/address", + "type": "string", + "default": "", + "examples": [ + "auth.example.com:3025" + ] + }, + "identitySecretName": { + "$id": "#/properties/teleport/properties/identitySecretName", + "type": "string", + "default": "" + }, + "identitySecretPath": { + "$id": "#/properties/teleport/properties/identitySecretPath", + "type": "string", + "default": "auth_id", + "examples": [ + "auth_id" + ] + } + }, + "additionalProperties": true + }, + "eventHandler": { + "$id": "#/properties/eventHandler", + "type": "object", + "default": { + "storagePath": "/var/lib/teleport/plugins/event-handler/storage", + "timeout": "10s", + "batch": 20 + }, + "examples": [ + { + "storagePath": "/var/lib/teleport/plugins/event-handler/storage", + "timeout": "10s", + "batch": 20 + } + ], + "required": [ + "storagePath", + "timeout" + ], + "properties": { + "storagePath": { + "$id": "#/properties/eventHandler/properties/storagePath", + "type": "string", + "default": "/var/lib/teleport/plugins/event-handler/storage", + "examples": [ + "/var/lib/teleport/plugins/event-handler/storage", + "/storage" + ] + }, + "timeout": { + "$id": "#/properties/eventHandler/properties/timeout", + "type": "string", + "default": "10s" + }, + "batch": { + "$id": "#/properties/eventHandler/properties/batch", + "type": "number", + "default": 20 + } + }, + "additionalProperties": true + }, + "fluentd": { + "$id": "#/properties/fluentd", + "type": "object", + "default": {}, + "examples": [ + { + "url": "https://fluentd:8888/test.log", + "sessionUrl": "https://fluentd:8888/session", + "certificate": { + "secretName": "", + "caPath": "ca.crt", + "certPath": "client.crt", + "keyPath": "client.key" + } + } + ], + "required": [ + "url", + "sessionUrl", + "certificate" + ], + "properties": { + "url": { + "$id": "#/properties/fluentd/properties/url", + "type": "string", + "default": "", + "examples": [ + "https://fluentd:8888/test.log" + ] + }, + "sessionUrl": { + "$id": "#/properties/fluentd/properties/sessionUrl", + "type": "string", + "default": "", + "examples": [ + "https://fluentd:8888/session" + ] + }, + "certificate": { + "$id": "#/properties/fluentd/properties/certificate", + "type": "object", + "default": { + "secretName": "", + "caPath": "ca.crt", + "certPath": "client.crt", + "keyPath": "client.key" + }, + "examples": [ + { + "secretName": "event-handler-fluentd-credentials", + "caPath": "ca.crt", + "certPath": "client.crt", + "keyPath": "client.key" + } + ], + "required": [ + "secretName", + "caPath", + "certPath", + "keyPath" + ], + "properties": { + "secretName": { + "$id": "#/properties/fluentd/properties/credentials/properties/secretName", + "type": "string", + "default": "" + }, + "caPath": { + "$id": "#/properties/fluentd/properties/credentials/properties/caPath", + "type": "string", + "default": "ca.crt" + }, + "certPath": { + "$id": "#/properties/fluentd/properties/credentials/properties/certPath", + "type": "string", + "default": "client.crt" + }, + "keyPath": { + "$id": "#/properties/fluentd/properties/credentials/properties/keyPath", + "type": "string", + "default": "client.key" + } + } + } + }, + "additionalProperties": true + }, + "persistentVolumeClaim": { + "$id": "#/properties/persistentVolumeClaim", + "type": "object", + "default": { + "enabled": true, + "size": "1Gi", + "storageClassName": "", + "existingClaim": "" + }, + "examples": [ + { + "enabled": true, + "size": "1Gi", + "storageClassName": "", + "existingClaim": "" + } + ], + "required": [ + "enabled", + "size", + "storageClassName", + "existingClaim" + ], + "properties": { + "enabled": { + "$id": "#/properties/persistentVolumeClaim/properties/enabled", + "type": "boolean", + "default": false, + "examples": [ + true + ] + }, + "size": { + "$id": "#/properties/persistentVolumeClaim/properties/size", + "type": "string", + "default": "1Gi", + "examples": [ + "1Gi", + "1Ti" + ] + }, + "storageClassName": { + "$id": "#/properties/persistentVolumeClaim/properties/storageClassName", + "type": "string", + "default": "", + "examples": [ + "gp2" + ] + }, + "existingClaim": { + "$id": "#/properties/persistentVolumeClaim/properties/existingClaim", + "type": "string", + "default": "", + "examples": [ + "teleport-plugin-event-handler-pvc" + ] + }, + "volumeName": { + "$id": "#/properties/persistentVolumeClaim/properties/volumeName", + "type": "string", + "default": "storage", + "examples": [ + "storage" + ] + } + }, + "additionalProperties": true + } + }, + "additionalProperties": true +} diff --git a/examples/chart/event-handler/values.yaml b/examples/chart/event-handler/values.yaml new file mode 100644 index 0000000000000..647aed989d023 --- /dev/null +++ b/examples/chart/event-handler/values.yaml @@ -0,0 +1,68 @@ +# Default values for event-handler. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# +# Plugin specific options +# +teleport: + address: "" + identitySecretName: "" + identitySecretPath: "auth_id" + +eventHandler: + storagePath: "/var/lib/teleport/plugins/event-handler/storage" + timeout: "10s" + batch: 20 + +fluentd: + url: "" + sessionUrl: "" + certificate: + secretName: "" + caPath: "ca.crt" + certPath: "client.crt" + keyPath: "client.key" + +persistentVolumeClaim: + enabled: false + size: 1Gi + storageClassName: "" + existingClaim: "" + volumeName: "storage" + +# +# Deployment +# +image: + repository: public.ecr.aws/gravitational/teleport-plugin-event-handler + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podAnnotations: {} + +podSecurityContext: {} + +securityContext: {} + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +volumes: [] + # - name: storage + # persistentVolumeClaim: + # claimName: teleport-plugin-event-handler + +volumeMounts: [] + # - name: storage + # mountPath: "/var/lib/teleport/plugins/event-handler/storage" diff --git a/version.mk b/version.mk index 1073a4308f8e1..45670bbbeb155 100644 --- a/version.mk +++ b/version.mk @@ -28,7 +28,7 @@ setver: validate-semver helm-version tsh-version # The weird -i usage is to make the sed commands work the same on both Linux and Mac. Test on both platforms if you change it. .PHONY:helm-version helm-version: - for CHART in teleport-cluster teleport-kube-agent teleport-cluster/charts/teleport-operator; do \ + for CHART in teleport-cluster teleport-kube-agent teleport-cluster/charts/teleport-operator event-handler access/discord access/email access/jira access/mattermost access/msteams access/pagerduty access/slack; do \ sed -i'.bak' -e "s_^\\.version:\ .*_.version: \\&version \"$${VERSION}\"_g" examples/chart/$${CHART}/Chart.yaml || exit 1; \ rm -f examples/chart/$${CHART}/Chart.yaml.bak; \ done