Browse Source

feat: initial helm chart

Kellin McAvoy 5 years ago
parent
commit
a7a074dd02

+ 5 - 0
.github/ci/ct.yaml

@@ -0,0 +1,5 @@
+chart-dirs:
+  - deploy/charts
+helm-extra-args: "--timeout=5m"
+check-version-increment: false
+target-branch: main

+ 4 - 0
.github/workflows/all.yml

@@ -7,8 +7,12 @@ on:
       - '*/*'       # matches every branch containing a single '/'
       - '**'        # matches every branch
       - '!main'     # excludes main
+    paths-ignore:
+      - 'deploy/**'
   pull_request:
     branches: [ '!main' ]
+    paths-ignore:
+      - 'deploy/**'
 
 env:
   KUBEBUILDER_VERSION: 2.3.1

+ 55 - 0
.github/workflows/helm.yml

@@ -0,0 +1,55 @@
+name: Helm
+
+on:
+  push:
+    tags:
+      - '*'
+    paths:
+      - 'deploy/charts/**'
+  pull_request:
+    branches: main
+    paths:
+      - 'deploy/charts/**'
+
+jobs:
+  lint-and-test:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+
+      - name: Generate chart
+        run: |
+          make crds-to-chart
+
+      - name: Set up Helm
+        uses: azure/setup-helm@v1
+        with:
+          version: v3.4.2
+
+      - uses: actions/setup-python@v2
+        with:
+          python-version: 3.7
+
+      - name: Set up chart-testing
+        uses: helm/chart-testing-action@v2.0.1
+
+      - name: Run chart-testing (list-changed)
+        id: list-changed
+        run: |
+          changed=$(ct list-changed --config=.github/ci/ct.yaml)
+          if [[ -n "$changed" ]]; then
+            echo "::set-output name=changed::true"
+          fi
+
+      - name: Run chart-testing (lint)
+        run: ct lint --config=.github/ci/ct.yaml
+
+      - name: Create kind cluster
+        uses: helm/kind-action@v1.1.0
+        if: steps.list-changed.outputs.changed == 'true'
+
+      - name: Run chart-testing (install)
+        run: ct install --config=.github/ci/ct.yaml

+ 4 - 0
.github/workflows/main.yml

@@ -5,8 +5,12 @@ on:
     branches: [ main ]
     tags:
       - '*'
+    paths-ignore:
+      - 'deploy/**'
   pull_request:
     branches: [ main ]
+    paths-ignore:
+      - 'deploy/**'
 
 env:
   KUBEBUILDER_VERSION: 2.3.1

+ 2 - 0
.gitignore

@@ -24,3 +24,5 @@ bin
 
 # Code test output
 cover.out
+
+deploy/charts/external-secrets/templates/crds/*.yaml

+ 12 - 0
Makefile

@@ -7,6 +7,8 @@ SHELL         := /bin/bash
 IMG ?= controller:latest
 # Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
 CRD_OPTIONS ?= "crd:trivialVersions=true"
+HELM_DIR    ?= deploy/charts/external-secrets
+CRD_DIR     ?= config/crd/bases
 
 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
 ifeq (,$(shell go env GOBIN))
@@ -77,6 +79,16 @@ docker-build: test ## Build the docker image
 docker-push: ## Push the docker image
 	docker push ${IMG}
 
+helm-docs: ## Generate helm docs
+	cd $(HELM_DIR); \
+	docker run --rm -v $(shell pwd)/$(HELM_DIR):/helm-docs -u $(shell id -u) jnorwood/helm-docs:latest
+
+crds-to-chart: # Copy crds to helm chart directory
+	cp $(CRD_DIR)/*.yaml $(HELM_DIR)/templates/crds/; \
+	for i in $(HELM_DIR)/templates/crds/*.yaml; do \
+		sed -i '1s/.*/{{- if .Values.installCRDs }}/;$$a{{- end }}' $$i; \
+	done
+
 # find or download controller-gen
 # download controller-gen if necessary
 controller-gen:

+ 26 - 0
deploy/charts/external-secrets/.helmignore

@@ -0,0 +1,26 @@
+# 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/
+
+# CRD README.md
+templates/crds/README.md

+ 14 - 0
deploy/charts/external-secrets/Chart.yaml

@@ -0,0 +1,14 @@
+apiVersion: v2
+name: external-secrets
+description: External secret management for Kubernetes
+type: application
+version: "0.1.0"
+appVersion: "0.1.0"
+kubeVersion: ">= 1.11.0"
+keywords:
+  - kubernetes-external-secrets
+  - secrets
+home: https://github.com/external-secrets/external-secrets
+maintainers:
+  - name: mcavoyk
+    email: kellinmcavoy@gmail.com

+ 63 - 0
deploy/charts/external-secrets/README.md

@@ -0,0 +1,63 @@
+# external-secrets
+
+[//]: # (README.md generated by gotmpl. DO NOT EDIT.)
+
+![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![AppVersion: 0.1.0](https://img.shields.io/badge/AppVersion-0.1.0-informational?style=flat-square)
+
+External secret management for Kubernetes
+
+## TL;DR
+```bash
+helm repo add external-secrets https://external-secrets.github.io/external-secrets
+helm install external-secrets/external-secrets
+```
+
+## Installing the Chart
+To install the chart with the release name `external-secrets`:
+```bash
+helm install external-secrets external-secrets/external-secrets
+```
+
+### Custom Resources
+By default, the chart will install external-secrets CRDs, this can be controlled with `installCRDs` value.
+
+## Uninstalling the Chart
+To uninstall the `external-secrets` deployment:
+```bash
+helm uninstall external-secrets
+```
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Configuration
+Read through the external-secrets [values.yaml](https://github.com/external-secrets/external-secrets/blob/master/deploy/charts/external-secrets/values.yaml)
+file. It has several commented out suggested values.
+
+## Values
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| affinity | object | `{}` |  |
+| extraArgs | object | `{}` |  |
+| extraEnv | list | `[]` |  |
+| fullnameOverride | string | `""` |  |
+| image.pullPolicy | string | `"IfNotPresent"` |  |
+| image.repository | string | `"ghcr.io/external-secrets/external-secrets"` |  |
+| image.tag | string | `""` | The image tag to use. The default is the chart appVersion. |
+| imagePullSecrets | list | `[]` |  |
+| installCRDs | bool | `true` | If set, install and upgrade CRDs through helm chart. |
+| leaderElect | bool | `true` | If true, external-secrets will perform leader election between instances to ensure no more than one instance of external-secrets operates at a time. |
+| nameOverride | string | `""` |  |
+| nodeSelector | object | `{}` |  |
+| podAnnotations | object | `{}` |  |
+| podLabels | object | `{}` |  |
+| podSecurityContext | object | `{}` |  |
+| prometheus.enabled | bool | `false` | Specifies whether to expose Service resource for collecting Prometheus metrics |
+| prometheus.service.port | int | `8080` |  |
+| rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. |
+| replicaCount | int | `1` |  |
+| resources | object | `{}` |  |
+| securityContext | object | `{}` |  |
+| serviceAccount.annotations | object | `{}` | Annotations to add to the service account. |
+| serviceAccount.create | bool | `true` | Specifies whether a service account should be created. |
+| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. |
+| tolerations | list | `[]` |  |

+ 38 - 0
deploy/charts/external-secrets/README.md.gotmpl

@@ -0,0 +1,38 @@
+{{- $valuesYAML := "https://github.com/external-secrets/external-secrets/blob/master/deploy/charts/external-secrets/values.yaml" -}}
+{{- $chartRepo := "https://external-secrets.github.io/external-secrets" -}}
+{{- $org := "external-secrets" -}}
+{{ template "chart.header" . }}
+
+[//]: # (README.md generated by gotmpl. DO NOT EDIT.)
+
+{{ template "chart.typeBadge" . }}{{ template "chart.versionBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+{{ template "chart.description" . }}
+
+## TL;DR
+```bash
+helm repo add {{ $org }} {{ $chartRepo }}
+helm install {{ $org }}/{{ template "chart.name" . }}
+```
+
+## Installing the Chart
+To install the chart with the release name `{{ template "chart.name" . }}`:
+```bash
+helm install {{ template "chart.name" . }} {{ $org }}/{{ template "chart.name" . }}
+```
+
+### Custom Resources
+By default, the chart will install external-secrets CRDs, this can be controlled with `installCRDs` value.
+
+## Uninstalling the Chart
+To uninstall the `{{ template "chart.name" . }}` deployment:
+```bash
+helm uninstall {{ template "chart.name" . }}
+```
+The command removes all the Kubernetes components associated with the chart and deletes the release.
+
+## Configuration
+Read through the {{ template "chart.name" . }} [values.yaml]({{ $valuesYAML }})
+file. It has several commented out suggested values.
+
+{{ template "chart.valuesSection" . }}

+ 2 - 0
deploy/charts/external-secrets/ci/main-values.yaml

@@ -0,0 +1,2 @@
+image:
+  tag: main

+ 7 - 0
deploy/charts/external-secrets/templates/NOTES.txt

@@ -0,0 +1,7 @@
+external-secrets has been deployed successfully!
+
+In order to begin using ExternalSecrets, you will need to set up a SecretStore
+or ClusterSecretStore resource (for example, by creating a 'vault' SecretStore).
+
+More information on the different types of SecretStores and how to configure them
+can be found in our Github: {{ .Chart.Home }}

+ 62 - 0
deploy/charts/external-secrets/templates/_helpers.tpl

@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "external-secrets.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 "external-secrets.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 "external-secrets.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "external-secrets.labels" -}}
+helm.sh/chart: {{ include "external-secrets.chart" . }}
+{{ include "external-secrets.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "external-secrets.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "external-secrets.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "external-secrets.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "external-secrets.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}

+ 4 - 0
deploy/charts/external-secrets/templates/crds/README.md

@@ -0,0 +1,4 @@
+# CRD Template Directory
+the CRDs are generated in pipeline during helm package. To install the CRDs please set `installCRDS: true`.
+
+The latest CRDs in the repository are located [here](../../../../../config/crd/bases)

+ 74 - 0
deploy/charts/external-secrets/templates/deployment.yaml

@@ -0,0 +1,74 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "external-secrets.fullname" . }}
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "external-secrets.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      {{- with .Values.podAnnotations }}
+      annotations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      labels:
+        {{- include "external-secrets.selectorLabels" . | nindent 8 }}
+        {{- with .Values.podLabels }}
+          {{- toYaml . | nindent 8 }}
+        {{- end }}
+    spec:
+      {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "external-secrets.serviceAccountName" . }}
+      {{- with .Values.podSecurityContext }}
+      securityContext:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      containers:
+        - name: {{ .Chart.Name }}
+          {{- with .Values.securityContext }}
+          securityContext:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          args:
+          {{- if .Values.leaderElect }}
+          - --enable-leader-election=true
+          {{- end }}
+          {{- range $key, $value := .Values.extraArgs }}
+            {{- if $value }}
+          - --{{ $key }}={{ $value }}
+            {{- else }}
+          - --{{ $key }}
+            {{- end }}
+          {{- end }}
+          ports:
+            - containerPort: {{ .Values.prometheus.service.port }}
+              protocol: TCP
+          {{- with .Values.extraEnv }}
+          env:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          {{- with .Values.resources }}
+          resources:
+            {{- 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 }}

+ 101 - 0
deploy/charts/external-secrets/templates/rbac.yaml

@@ -0,0 +1,101 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ include "external-secrets.fullname" . }}-controller
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+rules:
+  - apiGroups:
+    - "external-secrets.io"
+    resources:
+    - "secretstores"
+    - "clustersecretstores"
+    - "externalsecrets"
+    verbs:
+    - "get"
+    - "list"
+    - "watch"
+  - apiGroups:
+    - "external-secrets.io"
+    resources:
+    - "externalsecrets"
+    - "externalsecrets/status"
+    verbs:
+    - "update"
+    - "patch"
+  - apiGroups:
+    - ""
+    resources:
+    - "secrets"
+    verbs:
+    - "get"
+    - "list"
+    - "watch"
+    - "create"
+    - "update"
+    - "delete"
+  - apiGroups:
+    - ""
+    resources:
+    - "events"
+    verbs:
+    - "create"
+    - "patch"
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "external-secrets.fullname" . }}-controller
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "external-secrets.fullname" . }}-controller
+subjects:
+  - name: {{ include "external-secrets.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace | quote }}
+    kind: ServiceAccount
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: {{ include "external-secrets.fullname" . }}-leaderelection
+  namespace: {{ .Release.Namespace | quote }}
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+rules:
+  - apiGroups:
+    - ""
+    resources:
+    - "configmaps"
+    resourceNames:
+    - "external-secrets-controller"
+    verbs:
+    - "get"
+    - "update"
+    - "patch"
+  - apiGroups:
+    - ""
+    resources:
+    - "configmaps"
+    verbs:
+    - "create"
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ include "external-secrets.fullname" . }}-leaderelection
+  namespace: {{ .Release.Namespace | quote }}
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "external-secrets.fullname" . }}-leaderelection
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "external-secrets.serviceAccountName" . }}
+    namespace: {{ .Release.Namespace | quote }}
+{{- end }}

+ 20 - 0
deploy/charts/external-secrets/templates/service.yaml

@@ -0,0 +1,20 @@
+{{- if .Values.prometheus.enabled }}
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "external-secrets.fullname" . }}-metrics
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+  annotations:
+    prometheus.io/path: "/metrics"
+    prometheus.io/scrape: "true"
+    prometheus.io/port: {{ .Values.prometheus.service.port | quote }}
+spec:
+  type: ClusterIP
+  ports:
+    - port: {{ .Values.prometheus.service.port }}
+      targetPort: {{ .Values.prometheus.service.port }}
+      protocol: TCP
+  selector:
+    {{- include "external-secrets.selectorLabels" . | nindent 4 }}
+{{- end }}

+ 12 - 0
deploy/charts/external-secrets/templates/serviceaccount.yaml

@@ -0,0 +1,12 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "external-secrets.serviceAccountName" . }}
+  labels:
+    {{- include "external-secrets.labels" . | nindent 4 }}
+  {{- with .Values.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}

+ 68 - 0
deploy/charts/external-secrets/values.yaml

@@ -0,0 +1,68 @@
+replicaCount: 1
+
+image:
+  repository: ghcr.io/external-secrets/external-secrets
+  pullPolicy: IfNotPresent
+  # -- The image tag to use. The default is the chart appVersion.
+  tag: ""
+
+# -- If set, install and upgrade CRDs through helm chart.
+installCRDs: true
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+# -- If true, external-secrets will perform leader election between instances to ensure no more
+# than one instance of external-secrets operates at a time.
+leaderElect: false
+
+serviceAccount:
+  # -- Specifies whether a service account should be created.
+  create: true
+  # -- Annotations to add to the service account.
+  annotations: {}
+  # -- The name of the service account to use.
+  # If not set and create is true, a name is generated using the fullname template.
+  name: ""
+
+rbac:
+  # -- Specifies whether role and rolebinding resources should be created.
+  create: true
+
+## -- Extra environment variables to add to container.
+extraEnv: []
+
+## -- Map of extra arguments to pass to container.
+extraArgs: {}
+
+podAnnotations: {}
+podLabels: {}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+resources: {}
+  # requests:
+  #   cpu: 10m
+  #   memory: 32Mi
+
+prometheus:
+  # -- Specifies whether to expose Service resource for collecting Prometheus metrics
+  enabled: false
+  service:
+    port: 8080
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}

+ 1 - 1
main.go

@@ -57,7 +57,7 @@ func main() {
 		MetricsBindAddress: metricsAddr,
 		Port:               9443,
 		LeaderElection:     enableLeaderElection,
-		LeaderElectionID:   "1fc40399.io",
+		LeaderElectionID:   "external-secrets-controller",
 	})
 	if err != nil {
 		setupLog.Error(err, "unable to start manager")