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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ yes |
+
+
+
+ discord.token |
+ Discord API token |
+ string |
+ "" |
+ yes |
+
+
+ discord.tokenFromSecret |
+ Kubernetes secret to read the token from instead of discord.token |
+ string |
+ "" |
+ no |
+
+
+ discord.tokenSecretPath |
+ The path of the token in the secret described by discord.tokenFromSecret |
+ string |
+ "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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "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.
+ |
+ boolean |
+ false |
+ no |
+
+
+ mailgun.domain |
+ Domain name of the Mailgun instance |
+ string |
+ "" |
+ no |
+
+
+ mailgun.privateKey |
+ Private key for accessing the Mailgun instance |
+ string |
+ "" |
+ no |
+
+
+ mailgun.privateKeyFromSecret |
+ Kubernetes secret to read the private key from instead of using mailgun.privateKey |
+ string |
+ "" |
+ no |
+
+
+ mailgun.privateKeySecretPath |
+ The path of the private key in the secret described by mailgun.privateKeyFromSecret |
+ string |
+ "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.
+ |
+ boolean |
+ false |
+ no |
+
+
+ smtp.host |
+ SMTP host. |
+ string |
+ "" |
+ no |
+
+
+ smtp.port |
+ Port of the SMTP server. |
+ integer |
+ 587 |
+ no |
+
+
+ smtp.username |
+ Username to be used with the SMTP server. |
+ string |
+ "" |
+ no |
+
+
+ smtp.password |
+ Password to be used with the SMTP server. Mutually exclusive with smtp.passwordFile. |
+ string |
+ "" |
+ no |
+
+
+ smtp.passwordFromSecret |
+ Kubernetes secret to read the SMTP password from instead of using smtp.password |
+ string |
+ "" |
+ no |
+
+
+ smtp.passwordSecretPath |
+ The path of the SMTP password in the secret described by smtp.passwordFromSecret |
+ string |
+ "smtpPassword" |
+ no |
+
+
+ smtp.starttlsPolicy |
+ Which policy to use for secure communications: mandatory, opportunistic or disabled. |
+ string |
+ "mandatory" |
+ no |
+
+
+
+ delivery.sender |
+ Email address to be used in the From field of the emails. |
+ string |
+ "" |
+ yes |
+
+
+ delivery.recipients |
+ Array 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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ 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.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ yes |
+
+
+
+ jira.url |
+ URL of the Jira server |
+ string |
+ "" |
+ yes |
+
+
+ jira.username |
+ Username of the bot user in Jira to use for creating issues. |
+ string |
+ "" |
+ yes |
+
+
+ jira.apiToken |
+ API token of the bot user. |
+ string |
+ "" |
+ yes |
+
+
+ jira.project |
+ Short code of the project in Jira in which issues will be created |
+ string |
+ "" |
+ yes |
+
+
+ jira.issueType |
+ Type of the issues to be created on access requests (eg. Bug, Task) |
+ string |
+ "Task" |
+ no |
+
+
+
+ http.publicAddress |
+ The domain name which will be assigned to the service |
+ string |
+ "" |
+ yes |
+
+
+ http.tlsFromSecret |
+ Name of the Kubernetes secret where the TLS key and certificate will be mounted |
+ string |
+ "" |
+ yes |
+
+
+ http.tlsKeySecretPath |
+ Path of the TLS key in the secret specified by http.tlsFromSecret |
+ string |
+ "" |
+ no |
+
+
+ http.tlsCertSecretPath |
+ Path of the TLS certificate in the secret specified by http.tlsFromSecret |
+ string |
+ "" |
+ no |
+
+
+
+ http.basicAuth.username |
+ Username 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.password |
+ Password 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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ yes |
+
+
+
+ mattermost.url |
+ URL of the Mattermost server |
+ string |
+ "" |
+ yes |
+
+
+ mattermost.token |
+ Token to be used to authenticate with Mattermost |
+ string |
+ "" |
+ yes |
+
+
+ mattermost.tokenFromSecret |
+ Kubernetes secret to read the token from instead of mattermost.token |
+ string |
+ "" |
+ no |
+
+
+ mattermost.tokenSecretPath |
+ The path of the token in the secret described by mattermost.tokenFromSecret |
+ string |
+ "mattermostToken" |
+ no |
+
+
+ mattermost.recipients |
+ Array 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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ yes |
+
+
+
+ pagerduty.apiKey |
+ PagerDuty API Key |
+ string |
+ |
+ yes |
+
+
+ pagerduty.apiKeyFromSecret |
+ Kubernetes secret to read the api key from instead of pagerduty.apiKey |
+ string |
+ "" |
+ no |
+
+
+ pagerduty.apiKeySecretPath |
+ The path of the api key in the secret described by pagerduty.apiKeyFromSecret |
+ string |
+ "pagerdutyApiKey" |
+ no |
+
+
+ pagerduty.userEmail |
+ PagerDuty bot user email |
+ string |
+ "" |
+ 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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ yes |
+
+
+
+ slack.token |
+ Slack API token |
+ string |
+ "" |
+ yes |
+
+
+ slack.tokenFromSecret |
+ Kubernetes secret to read the token from instead of slack.token |
+ string |
+ "" |
+ no |
+
+
+ slack.tokenSecretPath |
+ The path of the token in the secret described by slack.tokenFromSecret |
+ string |
+ "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:
+
+
+
+ | Name |
+ Description |
+ Type |
+ Default |
+ Required |
+
+
+
+ teleport.address |
+ Host/port combination of the teleport auth server |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretName |
+ Name of the Kubernetes secret that contains the credentials for the connection |
+ string |
+ "" |
+ yes |
+
+
+ teleport.identitySecretPath |
+ Key of the field in the secret specified by teleport.identitySecretName |
+ string |
+ "auth_id" |
+ no |
+
+
+
+ eventHandler.storagePath |
+ Path to the directory where event-handler's state is stored |
+ string |
+ "/var/lib/teleport/plugins/event-handler/storage" |
+ no |
+
+
+ eventHandler.timeout |
+ Maximum time to wait for incoming events before sending them to fluentd. |
+ string |
+ "10s" |
+ no |
+
+
+ eventHandler.batch |
+ Maximum number of events fetched from Teleport in one request |
+ string |
+ 20 |
+ no |
+
+
+
+ fluentd.url |
+ URL of fluentd where the event logs will be sent to. |
+ string |
+ "" |
+ yes |
+
+
+ fluentd.sessionUrl |
+ URL 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.caPath |
+ Path of the CA certificate in the secret described by fluentd.secretName. |
+ string |
+ "ca.crt" |
+
+
+ fluentd.certPath |
+ Path of the client's certificate in the secret described by fluentd.secretName. |
+ string |
+ "client.crt" |
+ no |
+
+
+ fluentd.keyPath |
+ Path 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.
+ |
+ boolean |
+ false |
+ no |
+
+
+ persistentVolumeClaim.size |
+ Sets 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