From 5d647f42ed8eab5a2c26952a2a59317dc4c008cd Mon Sep 17 00:00:00 2001 From: Aaron Roydhouse Date: Fri, 16 Feb 2018 12:09:41 -0500 Subject: [PATCH] Add helm charts for 'dex' and 'dex-k8s-authenticator', add README, get Docker to ignore the charts folder --- .dockerignore | 3 +- .gitignore | 2 + charts/README.md | 32 +++ charts/dex-k8s-authenticator/.helmignore | 21 ++ charts/dex-k8s-authenticator/Chart.yaml | 5 + charts/dex-k8s-authenticator/README.md | 76 ++++++ .../dex-k8s-authenticator/templates/NOTES.txt | 19 ++ .../templates/_helpers.tpl | 32 +++ .../templates/configmap.yaml | 26 ++ .../templates/deployment.yaml | 63 +++++ .../templates/ingress.yaml | 40 ++++ .../templates/service.yaml | 20 ++ charts/dex-k8s-authenticator/values.yaml | 64 +++++ charts/dex/.helmignore | 21 ++ charts/dex/Chart.yaml | 5 + charts/dex/README.md | 225 ++++++++++++++++++ charts/dex/templates/NOTES.txt | 19 ++ charts/dex/templates/_helpers.tpl | 39 +++ charts/dex/templates/configmap.yaml | 13 + charts/dex/templates/deployment.yaml | 77 ++++++ charts/dex/templates/ingress.yaml | 40 ++++ charts/dex/templates/rbac.yaml | 63 +++++ charts/dex/templates/secret.yaml | 14 ++ charts/dex/templates/service.yaml | 20 ++ charts/dex/templates/serviceaccount.yaml | 16 ++ charts/dex/values.yaml | 210 ++++++++++++++++ 26 files changed, 1164 insertions(+), 1 deletion(-) create mode 100644 charts/README.md create mode 100644 charts/dex-k8s-authenticator/.helmignore create mode 100644 charts/dex-k8s-authenticator/Chart.yaml create mode 100644 charts/dex-k8s-authenticator/README.md create mode 100644 charts/dex-k8s-authenticator/templates/NOTES.txt create mode 100644 charts/dex-k8s-authenticator/templates/_helpers.tpl create mode 100644 charts/dex-k8s-authenticator/templates/configmap.yaml create mode 100644 charts/dex-k8s-authenticator/templates/deployment.yaml create mode 100644 charts/dex-k8s-authenticator/templates/ingress.yaml create mode 100644 charts/dex-k8s-authenticator/templates/service.yaml create mode 100644 charts/dex-k8s-authenticator/values.yaml create mode 100644 charts/dex/.helmignore create mode 100644 charts/dex/Chart.yaml create mode 100644 charts/dex/README.md create mode 100644 charts/dex/templates/NOTES.txt create mode 100644 charts/dex/templates/_helpers.tpl create mode 100644 charts/dex/templates/configmap.yaml create mode 100644 charts/dex/templates/deployment.yaml create mode 100644 charts/dex/templates/ingress.yaml create mode 100644 charts/dex/templates/rbac.yaml create mode 100644 charts/dex/templates/secret.yaml create mode 100644 charts/dex/templates/service.yaml create mode 100644 charts/dex/templates/serviceaccount.yaml create mode 100644 charts/dex/values.yaml diff --git a/.dockerignore b/.dockerignore index b25c15b..0255c6d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ -*~ +charts +examples diff --git a/.gitignore b/.gitignore index b25c15b..396e006 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ *~ +bin +vendor diff --git a/charts/README.md b/charts/README.md new file mode 100644 index 0000000..b36f7a6 --- /dev/null +++ b/charts/README.md @@ -0,0 +1,32 @@ +# Helm charts for installing `dex` with `dex-k8s-authenticator` + +The charts in this folder install [`dex`](https://github.com/coreos/dex) +with [`dex-k8s-authenticator`](https://github.com/mintel/dex-k8s-authenticator) + +`dex-k8s-authenticator` is a helper application for `dex`. `dex` lets you use external +Identify Providers (like Google, Microsoft, GitHUb, LDAP) to authenticate access to Kubernetes cluster +(e.g. for `kubectl`). This helper makes it easy to provide a web UI for one or more clusters. +It give uses the information and commands to configure `kubectl` to work with the credentials `dex` provides. + +Each install of `dex` and/or `dex-k8s-authenticator` can support multiple Kubernetes clusters. +So you can install one of each for all your clusters, one in each cluster, or any combination. + +``` +git clone git@github.com:mintel/dex-k8s-authenticator.git +helm inspect values charts/dex > dex.yaml +helm inspect values charts/dex-k8s-authenticator > dex-k8s-authenticator.yaml +``` +Edit the values files for your environment and requirements (`dex.yaml` and `dex-k8s-authenticator.yaml`). + +Create the DNS names for your `dex` (e.g. 'dex.example.com') and `dex-k8s-authenticator` (e.g. 'login.example.com') +pointed at the ingress controller you are using. Be sure to enable HTTPS. You can install +[`cert-manager`](https://github.com/jetstack/cert-manager) to automatically issue Lets Encrypt certificates. + +You also need to configure each Kubernetes cluster to use `dex` at e.g. 'dex.example.com' by [setting the OIDC parameters +for the Kubernetes API server](https://kubernetes.io/docs/admin/authentication/#openid-connect-tokens). +This is easy using [`kube-aws` installer](https://github.com/kubernetes-incubator/kube-aws/tree/master/contrib/dex). + +``` +helm install --namespace dex --values dex.yaml charts/dex +helm install --namespace dex --values dex-k8s-authenticator charts/dex-k8s-authenticator +``` diff --git a/charts/dex-k8s-authenticator/.helmignore b/charts/dex-k8s-authenticator/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/dex-k8s-authenticator/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/dex-k8s-authenticator/Chart.yaml b/charts/dex-k8s-authenticator/Chart.yaml new file mode 100644 index 0000000..5b78625 --- /dev/null +++ b/charts/dex-k8s-authenticator/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "0.1" +description: "Authenticator for using Dex with Kubernetes" +name: dex-k8s-authenticator +version: 0.1.0 diff --git a/charts/dex-k8s-authenticator/README.md b/charts/dex-k8s-authenticator/README.md new file mode 100644 index 0000000..863d9fe --- /dev/null +++ b/charts/dex-k8s-authenticator/README.md @@ -0,0 +1,76 @@ +# Helm chart for dex-k8s-authenticator + +This chart installs [`dex-k8s-authenticator`](https://github.com/mintel/dex-k8s-authenticator) in a Kubernetes cluster. +`dex-k8s-authenticator` is a helper application for [`dex`](https://github.com/coreos/dex). `dex` lets you use external +Identify Providers (like Google, Microsoft, GitHUb, LDAP) to authenticate access to Kubernetes cluster +(e.g. for `kubectl`). This helper makes it easy to provide a web UI for one or more clusters. +It give uses the information and commands to configure `kubectl` to work with the credentials `dex` provides. + +You can configure one or more clusters in this chart configuration, for the one or more `dex` installs you may have. + +``` +# Default values for dex-k8s-authenticator. + +# Deploy environment label, e.g. dev, test, prod +global: + deployEnv: dev + +replicaCount: 1 + +image: + repository: 212381861325.dkr.ecr.ap-southeast-2.amazonaws.com/kube/dex-k8s-authenticator + tag: latest + pullPolicy: Always + +dexK8sAuthenticator: + port: 5555 + debug: false + #logoUrl: http:// + #tlsCert: /path/to/dex-client.crt + #tlsKey: /path/to/dex-client.key + clusters: + - name: my-cluster + short_description: "My Cluster" + description: "Example Cluster Long Description..." + client_secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + issuer: https://dex.example.com + k8s_master_uri: https://my-cluster.example.com + client_id: my-cluster + redirect_uri: https://login.example.com/callback/my-cluster + k8s_ca_uri: https://url-to-your-ca.crt + +service: + type: ClusterIP + port: 5555 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - chart-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} +``` diff --git a/charts/dex-k8s-authenticator/templates/NOTES.txt b/charts/dex-k8s-authenticator/templates/NOTES.txt new file mode 100644 index 0000000..db64537 --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/NOTES.txt @@ -0,0 +1,19 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "dex-k8s-authenticator.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "dex-k8s-authenticator.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dex-k8s-authenticator.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "dex-k8s-authenticator.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/charts/dex-k8s-authenticator/templates/_helpers.tpl b/charts/dex-k8s-authenticator/templates/_helpers.tpl new file mode 100644 index 0000000..65e8cca --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "dex-k8s-authenticator.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 "dex-k8s-authenticator.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 "dex-k8s-authenticator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/dex-k8s-authenticator/templates/configmap.yaml b/charts/dex-k8s-authenticator/templates/configmap.yaml new file mode 100644 index 0000000..40ce469 --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/configmap.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "dex-k8s-authenticator.fullname" . }} + labels: + app: {{ template "dex-k8s-authenticator.fullname" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +data: + config.yaml: |- + {{- with .Values.dexK8sAuthenticator }} + listen: http://0.0.0.0:{{ default "5555" .port }} + debug: {{ default "false" .debug }} + {{- if .logoUrl }} + logo_uri: {{ .logoUrl }} + {{- end }} + {{- if and .tlsCert .tlsKey }} + tls_cert: "{{ .tlsCert }}" + tls_key: "{{ .tlsKey }}" + {{- end }} + clusters: +{{ toYaml .clusters | indent 4 }} + {{- end }} + diff --git a/charts/dex-k8s-authenticator/templates/deployment.yaml b/charts/dex-k8s-authenticator/templates/deployment.yaml new file mode 100644 index 0000000..b648591 --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "dex-k8s-authenticator.fullname" . }} + labels: + app: {{ template "dex-k8s-authenticator.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex-k8s-authenticator.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "dex-k8s-authenticator.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "dex-k8s-authenticator.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + release: {{ .Release.Name }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: [ "--config", "config.yaml" ] + ports: + - name: http + containerPort: {{ default "5555" .Values.dexK8sAuthenticator.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + volumeMounts: + - name: config + subPath: config.yaml + mountPath: /app/config.yaml + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "dex-k8s-authenticator.name" . }} diff --git a/charts/dex-k8s-authenticator/templates/ingress.yaml b/charts/dex-k8s-authenticator/templates/ingress.yaml new file mode 100644 index 0000000..93e8da5 --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "dex-k8s-authenticator.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "dex-k8s-authenticator.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex-k8s-authenticator.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . }} + http: + paths: + - path: {{ $ingressPath }} + backend: + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- end }} diff --git a/charts/dex-k8s-authenticator/templates/service.yaml b/charts/dex-k8s-authenticator/templates/service.yaml new file mode 100644 index 0000000..d6ce4f2 --- /dev/null +++ b/charts/dex-k8s-authenticator/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "dex-k8s-authenticator.fullname" . }} + labels: + app: {{ template "dex-k8s-authenticator.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex-k8s-authenticator.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "dex-k8s-authenticator.name" . }} + release: {{ .Release.Name }} diff --git a/charts/dex-k8s-authenticator/values.yaml b/charts/dex-k8s-authenticator/values.yaml new file mode 100644 index 0000000..209d719 --- /dev/null +++ b/charts/dex-k8s-authenticator/values.yaml @@ -0,0 +1,64 @@ +# Default values for dex-k8s-authenticator. + +# Deploy environment label, e.g. dev, test, prod +global: + deployEnv: dev + +replicaCount: 1 + +image: + repository: 212381861325.dkr.ecr.ap-southeast-2.amazonaws.com/kube/dex-k8s-authenticator + tag: latest + pullPolicy: Always + +dexK8sAuthenticator: + port: 5555 + debug: false + #logoUrl: http:// + #tlsCert: /path/to/dex-client.crt + #tlsKey: /path/to/dex-client.key + clusters: + - name: my-cluster + short_description: "My Cluster" + description: "Example Cluster Long Description..." + client_secret: ZXhhbXBsZS1hcHAtc2VjcmV0 + issuer: https://dex.example.com + k8s_master_uri: https://my-cluster.example.com + client_id: my-cluster + redirect_uri: https://login.example.com/callback/my-cluster + k8s_ca_uri: https://url-to-your-ca.crt + +service: + type: ClusterIP + port: 5555 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - chart-example.local + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/dex/.helmignore b/charts/dex/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/dex/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/dex/Chart.yaml b/charts/dex/Chart.yaml new file mode 100644 index 0000000..dde1912 --- /dev/null +++ b/charts/dex/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "2.9.0" +description: "Dex federated authentication service" +name: dex +version: 0.2.0 diff --git a/charts/dex/README.md b/charts/dex/README.md new file mode 100644 index 0000000..4074bb8 --- /dev/null +++ b/charts/dex/README.md @@ -0,0 +1,225 @@ +# Helm Chart for deploying dex + +This chart installs `dex` in a Kubernetes cluster. You can use this deployment for one cluster +or for any number of cluster you configure under `staticClients` in the configuration. + +You also need to configure each Kubernetes cluster to use `dex` by [setting the OIDC parameters +for the Kubernetes API server](https://kubernetes.io/docs/admin/authentication/#openid-connect-tokens). +This is easy using [`kube-aws` installer](https://github.com/kubernetes-incubator/kube-aws/tree/master/contrib/dex). + +If you want an easy way to issue and install `kubectl` credentials, then you should also +install [`dex-k8s-authenticator`](https://github.com/mintel/dex-k8s-authenticator). There +is a `helm` chart available for that too (in its repo). + +``` +# Default values for dex + +# Deploy environment label, e.g. dev, test, prod +global: + deployEnv: dev + +replicaCount: 1 + +image: + repository: quay.io/coreos/dex + tag: v2.9.0 + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 5556 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - dex.example.com + tls: [] + # - secretName: dex.example.com + # hosts: + # - dex.example.com + +# rbac will use the 'default' Service Account if 'serviceAccount.create' is false +rbac: + create: true + +serviceAccount: + create: true + # Service Account name defaults to an automatically generated name + #name: "custom-name" + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 50Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + + +# Configuration file for Dex +# Certainly secret fields can use environment variables +# +config: |- + issuer: https://dex.example.com + + storage: + type: kubernetes + config: + inCluster: true + + web: + http: 0.0.0.0:5556 + + frontend: + theme: "coreos" + issuer: "Example Co" + issuerUrl: "https://example.com" + logoUrl: https://example.com/images/logo-250x25.png + + expiry: + signingKeys: "6h" + idTokens: "24h" + + logger: + level: debug + format: json + + oauth2: + responseTypes: ["code", "token", "id_token"] + skipApprovalScreen: true + + # Remember you can have multiple connectors of the same 'type' (with different 'id's) + # If you need e.g. logins with groups for two different Microsoft 'tenants' + connectors: + + # GitHub configure 'OAuth Apps' -> 'New OAuth App', add callback URL + # https://github.com/settings/developers + - type: github + id: github + name: GitHub + config: + clientID: $GITHUB_CLIENT_ID + clientSecret: $GITHUB_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # 'orgs' can be used to map groups from Github + # https://github.com/coreos/dex/blob/master/Documentation/connectors/github.md + #orgs: + #- name: foo + # teams: + # - team-red + # - team-blue + #- name: bar + + # Google APIs account, 'Create Credentials' -> 'OAuth Client ID', add callback URL + # https://console.developers.google.com/apis/credentials + - type: oidc + id: google + name: Google + config: + issuer: https://accounts.google.com + clientID: $GOOGLE_CLIENT_ID + clientSecret: $GOOGLE_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # Google supports whitelisting allowed domains when using G Suite + # (Google Apps). The following field can be set to a list of domains + # that can log in: + # hostedDomains: + # - example.com + # - other.example.com + + # Microsoft App Dev account, 'Add an app' + # 'Application Secrets' -> 'Generate new password' + # 'Platforms' -> 'Add Platform' -> 'Web', add the callback URL + # https://apps.dev.microsoft.com/ + - type: microsoft + id: microsoft + name: Microsoft + config: + clientID: $MICROSOFT_APPLICATION_ID + clientSecret: $MICROSOFT_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # Restrict access to one tenant + # tenant: or + # Restrict access to certain groups + # groups: + # - group-red + # - group-blue + + # These may not match the schema used by your LDAP server + # https://github.com/coreos/dex/blob/master/Documentation/connectors/ldap.md + - type: ldap + id: ldap + name: "LDAP" + config: + host: ldap.example.com:389 + startTLS: true + bindDN: "cn=serviceAccount,dc=example,dc=com" + bindPW: $LDAP_BINDPW + usernamePrompt: "Username" + userSearch: + # Query should be "(&(objectClass=inetorgperson)(cn=))" + baseDN: "ou=Users,dc=example,dc=com" + filter: "(objectClass=inetorgperson)" + username: cn + # DN must be in capitals + idAttr: DN + emailAttr: mail + nameAttr: displayName + groupSearch: + # Query should be "(&(objectClass=groupOfUniqueNames)(uniqueMember=))" + baseDN: "ou=Groups,dc=example,dc=com" + filter: "(objectClass=groupOfUniqueNames)" + # DN must be in capitals + userAttr: DN + groupAttr: uniqueMember + nameAttr: cn + + # The 'name' must match the k8s API server's 'oidc-client-id' + staticClients: + - id: my-cluster + name: "my-cluster" + secret: "pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok" + redirectURIs: + - https://login.example.com/callback/my-cluster + + enablePasswordDB: False + staticPasswords: + - email: "admin@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + + +# You should not enter your secrets here if this file will be stored in source control +# Instead create a separate file to hold or override these values +# You need only list the environment variables you used in the 'config' above +# You can add any additional ones you need, or remove ones you don't need +# +envSecrets: + # GitHub + GITHUB_CLIENT_ID: "override-me" + GITHUB_CLIENT_SECRET: "override-me" + # Google (oidc) + GOOGLE_CLIENT_ID: "override-me" + GOOGLE_CLIENT_SECRET: "override-me" + # Microsoft + MICROSOFT_APPLICATION_ID: "override-me" + MICROSOFT_CLIENT_SECRET: "override-me" + # LDAP + LDAP_BINDPW: "override-me" +``` diff --git a/charts/dex/templates/NOTES.txt b/charts/dex/templates/NOTES.txt new file mode 100644 index 0000000..2722467 --- /dev/null +++ b/charts/dex/templates/NOTES.txt @@ -0,0 +1,19 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "dex.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ template "dex.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "dex.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "dex.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/charts/dex/templates/_helpers.tpl b/charts/dex/templates/_helpers.tpl new file mode 100644 index 0000000..3a4ec1c --- /dev/null +++ b/charts/dex/templates/_helpers.tpl @@ -0,0 +1,39 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "dex.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 "dex.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 "dex.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create secret key from environment variables +*/}} +{{- define "dex.envkey" -}} +{{ . | replace "_" "-" | lower }} +{{- end -}} diff --git a/charts/dex/templates/configmap.yaml b/charts/dex/templates/configmap.yaml new file mode 100644 index 0000000..da4df93 --- /dev/null +++ b/charts/dex/templates/configmap.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "dex.fullname" . }} + labels: + app: {{ template "dex.fullname" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +data: + config.yaml: |- +{{ .Values.config | indent 4 }} diff --git a/charts/dex/templates/deployment.yaml b/charts/dex/templates/deployment.yaml new file mode 100644 index 0000000..5775d14 --- /dev/null +++ b/charts/dex/templates/deployment.yaml @@ -0,0 +1,77 @@ +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: {{ template "dex.fullname" . }} + labels: + app: {{ template "dex.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + scheduler.alpha.kubernetes.io/critical-pod: '' +spec: + replicas: {{ .Values.replicaCount }} + minReadySeconds: 30 + strategy: + rollingUpdate: + maxUnavailable: 0 + selector: + matchLabels: + app: {{ template "dex.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "dex.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + release: {{ .Release.Name }} + spec: + volumes: + - name: config + configMap: + name: {{ template "dex.fullname" . }} + items: + - key: config.yaml + path: config.yaml + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["/usr/local/bin/dex", "serve", "/etc/dex/config.yaml"] + env: + {{- range $key, $value := .Values.envSecrets }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ template "dex.fullname" $ }} + key: {{ template "dex.envkey" $key }} + {{- end }} + ports: + - name: http + containerPort: 5556 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: 5556 + initialDelaySeconds: 5 + timeoutSeconds: 1 + volumeMounts: + - name: config + mountPath: /etc/dex + resources: +{{ toYaml .Values.resources | indent 10 }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} diff --git a/charts/dex/templates/ingress.yaml b/charts/dex/templates/ingress.yaml new file mode 100644 index 0000000..75a23ec --- /dev/null +++ b/charts/dex/templates/ingress.yaml @@ -0,0 +1,40 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "dex.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ template "dex.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . }} + http: + paths: + - path: {{ $ingressPath }} + backend: + serviceName: {{ $fullName }} + servicePort: http + {{- end }} +{{- end }} diff --git a/charts/dex/templates/rbac.yaml b/charts/dex/templates/rbac.yaml new file mode 100644 index 0000000..1f021ba --- /dev/null +++ b/charts/dex/templates/rbac.yaml @@ -0,0 +1,63 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: {{ template "dex.fullname" . }} +rules: +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ template "dex.fullname" . }} + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: + - dex.coreos.com + resources: + - authcodes + - authrequests + - connectors + - oauth2clients + - offlinesessionses + - passwords + - refreshtokens + - signingkeies + verbs: + - "*" +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: {{ template "dex.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "dex.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ default "default" .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ template "dex.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "dex.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ default "default" .Values.serviceAccount.name }} + namespace: {{ template "dex.fullname" . }} +{{- end }} + + + diff --git a/charts/dex/templates/secret.yaml b/charts/dex/templates/secret.yaml new file mode 100644 index 0000000..6da6e4f --- /dev/null +++ b/charts/dex/templates/secret.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "dex.fullname" . }} + labels: + app: {{ template "dex.fullname" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +data: + {{- range $key, $value := .Values.envSecrets }} + {{ template "dex.envkey" $key }}: "{{ $value | b64enc }}" + {{- end }} diff --git a/charts/dex/templates/service.yaml b/charts/dex/templates/service.yaml new file mode 100644 index 0000000..02ce710 --- /dev/null +++ b/charts/dex/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "dex.fullname" . }} + labels: + app: {{ template "dex.name" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + app: {{ template "dex.name" . }} + release: {{ .Release.Name }} diff --git a/charts/dex/templates/serviceaccount.yaml b/charts/dex/templates/serviceaccount.yaml new file mode 100644 index 0000000..b74dbc3 --- /dev/null +++ b/charts/dex/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- if .Values.serviceAccount.name }} + name: {{ .Values.serviceAccount.name }} + {{- else }} + name: {{ template "dex.fullname" . }} + {{- end }} + labels: + app: {{ template "dex.fullname" . }} + env: {{ default "dev" .Values.global.deployEnv }} + chart: {{ template "dex.chart" . }} + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +{{- end }} diff --git a/charts/dex/values.yaml b/charts/dex/values.yaml new file mode 100644 index 0000000..2dfd0e9 --- /dev/null +++ b/charts/dex/values.yaml @@ -0,0 +1,210 @@ +# Default values for dex + +# Deploy environment label, e.g. dev, test, prod +global: + deployEnv: dev + +replicaCount: 1 + +image: + repository: quay.io/coreos/dex + tag: v2.9.0 + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 5556 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + path: / + hosts: + - dex.example.com + tls: [] + # - secretName: dex.example.com + # hosts: + # - dex.example.com + +# rbac will use the 'default' Service Account if 'serviceAccount.create' is false +rbac: + create: true + +serviceAccount: + create: true + # Service Account name defaults to an automatically generated name + #name: "custom-name" + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 50Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + + +# Configuration file for Dex +# Certainly secret fields can use environment variables +# +config: |- + issuer: https://dex.example.com + + storage: + type: kubernetes + config: + inCluster: true + + web: + http: 0.0.0.0:5556 + + frontend: + theme: "coreos" + issuer: "Example Co" + issuerUrl: "https://example.com" + logoUrl: https://example.com/images/logo-250x25.png + + expiry: + signingKeys: "6h" + idTokens: "24h" + + logger: + level: debug + format: json + + oauth2: + responseTypes: ["code", "token", "id_token"] + skipApprovalScreen: true + + # Remember you can have multiple connectors of the same 'type' (with different 'id's) + # If you need e.g. logins with groups for two different Microsoft 'tenants' + connectors: + + # GitHub configure 'OAuth Apps' -> 'New OAuth App', add callback URL + # https://github.com/settings/developers + - type: github + id: github + name: GitHub + config: + clientID: $GITHUB_CLIENT_ID + clientSecret: $GITHUB_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # 'orgs' can be used to map groups from Github + # https://github.com/coreos/dex/blob/master/Documentation/connectors/github.md + #orgs: + #- name: foo + # teams: + # - team-red + # - team-blue + #- name: bar + + # Google APIs account, 'Create Credentials' -> 'OAuth Client ID', add callback URL + # https://console.developers.google.com/apis/credentials + - type: oidc + id: google + name: Google + config: + issuer: https://accounts.google.com + clientID: $GOOGLE_CLIENT_ID + clientSecret: $GOOGLE_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # Google supports whitelisting allowed domains when using G Suite + # (Google Apps). The following field can be set to a list of domains + # that can log in: + # hostedDomains: + # - example.com + # - other.example.com + + # Microsoft App Dev account, 'Add an app' + # 'Application Secrets' -> 'Generate new password' + # 'Platforms' -> 'Add Platform' -> 'Web', add the callback URL + # https://apps.dev.microsoft.com/ + - type: microsoft + id: microsoft + name: Microsoft + config: + clientID: $MICROSOFT_APPLICATION_ID + clientSecret: $MICROSOFT_CLIENT_SECRET + redirectURI: https://dex.example.com/callback + # Restrict access to one tenant + # tenant: or + # Restrict access to certain groups + # groups: + # - group-red + # - group-blue + + # These may not match the schema used by your LDAP server + # https://github.com/coreos/dex/blob/master/Documentation/connectors/ldap.md + - type: ldap + id: ldap + name: "LDAP" + config: + host: ldap.example.com:389 + startTLS: true + bindDN: "cn=serviceAccount,dc=example,dc=com" + bindPW: $LDAP_BINDPW + usernamePrompt: "Username" + userSearch: + # Query should be "(&(objectClass=inetorgperson)(cn=))" + baseDN: "ou=Users,dc=example,dc=com" + filter: "(objectClass=inetorgperson)" + username: cn + # DN must be in capitals + idAttr: DN + emailAttr: mail + nameAttr: displayName + groupSearch: + # Query should be "(&(objectClass=groupOfUniqueNames)(uniqueMember=))" + baseDN: "ou=Groups,dc=example,dc=com" + filter: "(objectClass=groupOfUniqueNames)" + # DN must be in capitals + userAttr: DN + groupAttr: uniqueMember + nameAttr: cn + + # The 'name' must match the k8s API server's 'oidc-client-id' + staticClients: + - id: my-cluster + name: "my-cluster" + secret: "pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok" + redirectURIs: + - https://login.example.com/callback/my-cluster + + enablePasswordDB: False + staticPasswords: + - email: "admin@example.com" + # bcrypt hash of the string "password" + hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W" + username: "admin" + userID: "08a8684b-db88-4b73-90a9-3cd1661f5466" + + +# You should not enter your secrets here if this file will be stored in source control +# Instead create a separate file to hold or override these values +# You need only list the environment variables you used in the 'config' above +# You can add any additional ones you need, or remove ones you don't need +# +envSecrets: + # GitHub + GITHUB_CLIENT_ID: "override-me" + GITHUB_CLIENT_SECRET: "override-me" + # Google (oidc) + GOOGLE_CLIENT_ID: "override-me" + GOOGLE_CLIENT_SECRET: "override-me" + # Microsoft + MICROSOFT_APPLICATION_ID: "override-me" + MICROSOFT_CLIENT_SECRET: "override-me" + # LDAP + LDAP_BINDPW: "override-me"