1 Commits

Author SHA1 Message Date
97639cb6a4 ci: init 2023-03-01 16:51:10 +03:00
38 changed files with 1491 additions and 559 deletions

21
.drone.yml Normal file
View File

@@ -0,0 +1,21 @@
---
kind: pipeline
type: docker
name: default
trigger:
event:
- push
steps:
- name: release
image: cr.grachevko.ru/drone/helm:RELEASE.2023-03-01T13-46-55Z
settings:
username:
from_secret: HELM_REPO_USERNAME
password:
from_secret: HELM_REPO_PASSWORD
when:
branch:
- master
- rc

View File

@@ -1,29 +0,0 @@
name: Release Chart
on:
push:
tags:
- '*'
jobs:
release:
runs-on: ubuntu-latest
env:
REGISTRY: harbor.grachevko.ru
steps:
- uses: actions/checkout@v4
- uses: yokawasa/action-setup-kube-tools@v0.9.3
with:
setup-tools: helm
- name: deps and lint
run: |
helm dependency update
helm lint --strict .
- name: build
run: helm package --version ${{ gitea.ref_name }} .
- name: publish
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" | helm registry login ${{ env.REGISTRY }} --username "${{ secrets.REGISTRY_USERNAME }}" --password-stdin
helm push ./*.tgz oci://harbor.grachevko.ru/${{ gitea.repository }}

45
.github/workflows/main.yaml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: Build
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Helm
run: |
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm plugin install https://github.com/hayorov/helm-gcs
- name: Lint chart
run: |
helm lint .
release:
needs: lint
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Helm
run: |
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
helm plugin install https://github.com/hayorov/helm-gcs
- name: Dump GCloud auth key
run: |
cat <<'EOF' > gcloud_auth_key.json
${{ secrets.GCLOUD_AUTH_KEY }}
EOF
- name: Release chart
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ github.workspace }}/gcloud_auth_key.json
run: |
helm repo add hahow gs://hahow-helm-charts
helm repo update
PACKAGE_FILE_PATH=$(helm package . | sed 's/^Successfully packaged chart and saved it to: //')
helm gcs push $(basename ${PACKAGE_FILE_PATH}) hahow --public

View File

@@ -27,6 +27,3 @@ starter/
gcloud_auth_key.json
create.sh
README.md
# Ci
.drone.yml

948
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,9 @@ then
exit 1
fi
curl --proto '=https' --tlsv1.2 -sSf https://git.grachevko.ru/helm/common/archive/master.tar.gz | \
tar -xz --strip=2 common/starter
find . -type f -exec sed -i "s/<CHARTNAME>/$1/g" {} \;
mkdir "$1"
curl --proto '=https' --tlsv1.2 -sSf https://codeload.github.com/hahow/common-chart/tar.gz/master | \
tar -xz -C "$1" --strip=2 common-chart-master/starter
find "$1" -type f | xargs sed -i "" "s/<CHARTNAME>/$1/g"
helm dep update
helm dep build "$1"

View File

@@ -1,3 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
}

View File

@@ -21,5 +21,3 @@
.idea/
*.tmproj
.vscode/
# CI
.drone.yml

View File

@@ -24,5 +24,5 @@ appVersion: 1.16.0
dependencies:
- name: common
version: "^0"
repository: oci://cr.grachevko.ru/helm/chart
version: "0.4.1"
repository: "https://hahow-helm-charts.storage.googleapis.com/"

View File

@@ -1,7 +1,3 @@
CHART NAME: {{ .Chart.Name }}
CHART VERSION: {{ .Chart.Version }}
APP VERSION: {{ .Chart.AppVersion }}
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}

View File

@@ -1,12 +0,0 @@
{{- if not .Values.existingConfigmap }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "common.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
data:
{{- if .Values.config.debug }}
DEBUG: true
{{- end }}
{{- end }}

View File

@@ -1,85 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "common.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
{{/* vim: set filetype=mustache: */}}
{{- include "common.deployment" (list . .Values .Values.autoscaling .Values.serviceAccount "<CHARTNAME>.deployment") }}
{{- define "<CHARTNAME>.deployment" -}}
spec:
replicas: 1
selector:
matchLabels:
{{- include "common.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "common.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.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
envFrom:
{{- if .Values.existingConfigmap }}
- configMapRef:
name: {{ .Values.existingConfigmap }}
{{- else }}
- configMapRef:
name: {{ include "common.fullname" . }}
{{- end }}
{{- if .Values.existingSecret }}
- secretRef:
name: {{ .Values.existingSecret }}
{{- else }}
- secretRef:
name: {{ include "common.fullname" . }}
{{- end }}
{{- if .Values.extraEnvVarsSecret }}
- secretRef:
name: {{ .Values.extraEnvVarsSecret }}
{{- end }}
ports:
- name: http
containerPort: 5678
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: http
readinessProbe:
httpGet:
path: /healthz
port: http
startupProbe:
httpGet:
path: /healthz
port: http
failureThreshold: 30
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
- {{- include "common.container" (append . "<CHARTNAME>.container") | nindent 8 }}
{{- end }}
{{- define "<CHARTNAME>.container" -}}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
{{- end }}

View File

@@ -0,0 +1,3 @@
{{/* vim: set filetype=mustache: */}}
{{- include "common.hpa" (list . .Values.autoscaling) -}}

View File

@@ -1,41 +1,3 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "common.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "common.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.className }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ default "ImplementationSpecific" .pathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{/* vim: set filetype=mustache: */}}
{{- include "common.ingress" (list . .Values.ingress .Values.service) }}

View File

@@ -1,10 +0,0 @@
{{- if not .Values.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "common.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
type: Opaque
data: {}
{{- end }}

View File

@@ -1,15 +1,3 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "common.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "common.selectorLabels" . | nindent 4 }}
{{/* vim: set filetype=mustache: */}}
{{- include "common.service" (list . .Values.service) }}

View File

@@ -0,0 +1,3 @@
{{/* vim: set filetype=mustache: */}}
{{- include "common.serviceAccount" (list . .Values.serviceAccount) }}

View File

@@ -8,8 +8,8 @@ metadata:
"helm.sh/hook": test-success
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "common.fullname" . }}:{{ .Values.service.port }}']
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "common.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

View File

@@ -2,17 +2,9 @@
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
config: {}
existingConfigmap:
existingSecret:
extraEnvVarsSecret:
replicaCount: 1
image:
registry: docker.io
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
@@ -50,11 +42,6 @@ service:
ingress:
enabled: false
## @param ingress.ingressClassName IngressClass that will be used to implement the Ingress (Kubernetes 1.18+)
## This is supported in Kubernetes 1.18+ and required if you have more than one IngressClass marked as the default for your cluster.
## ref: https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/
##
ingressClassName: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"

14
templates/_configmap.yaml Normal file
View File

@@ -0,0 +1,14 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.configMap.tpl" -}}
{{- $top := first . }}
apiVersion: v1
kind: ConfigMap
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
data: {}
{{- end }}
{{- define "common.configMap" -}}
{{- include "common.utils.merge" (append . "common.configMap.tpl") }}
{{- end }}

18
templates/_container.yaml Normal file
View File

@@ -0,0 +1,18 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.container.tpl" -}}
{{- $top := first . }}
{{- $container := index . 1 }}
{{- $image := $container.image | default (dict) }}
name: {{ $top.Chart.Name }}
securityContext:
{{- toYaml $container.securityContext | nindent 2 }}
image: "{{ $image.repository }}:{{ $image.tag | default $top.Chart.AppVersion }}"
imagePullPolicy: {{ $container.image.pullPolicy }}
resources:
{{- toYaml $container.resources | nindent 2 }}
{{- end }}
{{- define "common.container" -}}
{{- include "common.utils.merge" (append . "common.container.tpl") }}
{{- end }}

49
templates/_cronjob.yaml Normal file
View File

@@ -0,0 +1,49 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.cronJob.pod" -}}
spec:
restartPolicy: OnFailure
{{- end }}
{{- define "common.cronJob.tpl" -}}
{{- $top := first . }}
{{- $cronJob := index . 1 }}
{{- $pod := index . 2 }}
{{- $serviceAccount := index . 3 }}
{{- if semverCompare ">=1.21-0" $top.Capabilities.KubeVersion.GitVersion -}}
apiVersion: batch/v1
{{- else -}}
apiVersion: batch/v1beta1
{{- end }}
kind: CronJob
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
spec:
schedule: "{{ $cronJob.schedule }}"
{{- with $cronJob.concurrencyPolicy }}
concurrencyPolicy: {{ . }}
{{- end }}
{{- with $cronJob.failedJobsHistoryLimit }}
failedJobsHistoryLimit: {{ . }}
{{- end }}
{{- with $cronJob.successfulJobsHistoryLimit }}
successfulJobsHistoryLimit: {{ . }}
{{- end }}
{{- with $cronJob.suspend }}
suspend: {{ . }}
{{- end }}
jobTemplate:
metadata:
labels:
{{- include "common.selectorLabels" $top | nindent 8 }}
spec:
{{- with $cronJob.activeDeadlineSeconds }}
activeDeadlineSeconds: {{ . }}
{{- end }}
template:
{{- include "common.pod.template" (list $top $pod $serviceAccount "common.cronJob.pod") | nindent 8 }}
{{- end }}
{{- define "common.cronJob" -}}
{{- include "common.utils.merge" (append . "common.cronJob.tpl") }}
{{- end }}

View File

@@ -1,3 +0,0 @@
{{- define "common.dd" -}}
{{- . | toYaml | fail }}
{{- end -}}

View File

@@ -0,0 +1,25 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.deployment.tpl" -}}
{{- $top := first . }}
{{- $deployment := index . 1 }}
{{- $autoscaling := index . 2 }}
{{- $serviceAccount := index . 3 }}
apiVersion: apps/v1
kind: Deployment
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
spec:
{{- if not $autoscaling.enabled }}
replicas: {{ $deployment.replicaCount | default 1 }}
{{- end }}
selector:
matchLabels:
{{- include "common.selectorLabels" $top | nindent 6 }}
template:
{{- include "common.pod.template" (list $top $deployment $serviceAccount) | nindent 4 }}
{{- end }}
{{- define "common.deployment" -}}
{{- include "common.utils.merge" (append . "common.deployment.tpl") }}
{{- end }}

View File

@@ -1,23 +0,0 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Through error when upgrading using empty passwords values that must not be empty.
Usage:
{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}}
{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}}
{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }}
Required password params:
- validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error.
- context - Context - Required. Parent context.
*/}}
{{- define "common.errors.upgrade.passwords.empty" -}}
{{- $validationErrors := join "" .validationErrors -}}
{{- if and $validationErrors .context.Release.IsUpgrade -}}
{{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}}
{{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}}
{{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}}
{{- $errorString = print $errorString "\n%s" -}}
{{- printf $errorString $validationErrors | fail -}}
{{- end -}}
{{- end -}}

45
templates/_hpa.yaml Normal file
View File

@@ -0,0 +1,45 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.hpa.tpl" -}}
{{- $top := first . }}
{{- $autoscaling := index . 1 }}
{{- if semverCompare ">=1.23-0" $top.Capabilities.KubeVersion.GitVersion -}}
apiVersion: autoscaling/v2
{{- else -}}
apiVersion: autoscaling/v2beta2
{{- end }}
kind: HorizontalPodAutoscaler
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "common.fullname" $top }}
minReplicas: {{ $autoscaling.minReplicas }}
maxReplicas: {{ $autoscaling.maxReplicas }}
metrics:
{{- with $autoscaling.cpuUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ . }}
{{- end }}
{{- with $autoscaling.memoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ . }}
{{- end }}
{{- end }}
{{- define "common.hpa" -}}
{{- $autoscaling := index . 1 }}
{{- if $autoscaling.enabled }}
{{- include "common.utils.merge" (append . "common.hpa.tpl") }}
{{- end }}
{{- end }}

67
templates/_ingress.yaml Normal file
View File

@@ -0,0 +1,67 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.ingress.metadata" -}}
{{- $ingress := index . 1 }}
{{- with $ingress.annotations }}
annotations:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- define "common.ingress.tpl" -}}
{{- $top := first . }}
{{- $ingress := index . 1 }}
{{- $service := index . 2 }}
{{- $fullName := include "common.fullname" $top }}
{{- $svcPort := $service.port }}
{{- if semverCompare ">=1.19-0" $top.Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" $top.Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
{{- include "common.metadata" (append . "common.ingress.metadata") | nindent 2 }}
spec:
{{- if $ingress.tls }}
tls:
{{- range $ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range $ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $top.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $top.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- define "common.ingress" -}}
{{- $ingress := index . 1 }}
{{- if $ingress.enabled }}
{{- include "common.utils.merge" (append . "common.ingress.tpl") }}
{{- end }}
{{- end }}

View File

@@ -44,10 +44,3 @@ Create the name of the service account to use.
{{- default "default" $serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts.
*/}}
{{- define "common.namespace" -}}
{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

36
templates/_pdb.yaml Normal file
View File

@@ -0,0 +1,36 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.pdb.tpl" -}}
{{- $top := first . }}
{{- $pdb := index . 1 }}
{{- if semverCompare ">=1.21-0" $top.Capabilities.KubeVersion.GitVersion -}}
apiVersion: policy/v1
{{- else -}}
apiVersion: policy/v1beta1
{{- end }}
kind: PodDisruptionBudget
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
spec:
selector:
matchLabels:
{{- include "common.selectorLabels" $top | nindent 6 }}
{{- if not (or (empty $pdb.minAvailable) (empty $pdb.maxUnavailable)) }}
{{- fail "minAvailable and maxUnavailable can not be set together" }}
{{- end }}
{{- with $pdb.minAvailable }}
minAvailable: {{ . }}
{{- end }}
{{- with $pdb.maxUnavailable }}
maxUnavailable: {{ . }}
{{- end }}
{{- end }}
{{- define "common.pdb" -}}
{{- $top := first . }}
{{- $deployment := index . 2 }}
{{- $autoscaling := index . 3 }}
{{- if or (and $autoscaling.enabled (gt ($autoscaling.minReplicas | int) 1)) (and (not $autoscaling.enabled) (gt ($deployment.replicaCount | int) 1)) }}
{{- include "common.utils.merge" (append . "common.pdb.tpl") }}
{{- end }}
{{- end }}

46
templates/_pod.tpl Normal file
View File

@@ -0,0 +1,46 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.pod.template.tpl" -}}
{{- $top := first . }}
{{- $pod := index . 1 }}
{{- $serviceAccount := index . 2 }}
metadata:
{{- with $pod.podAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "common.selectorLabels" $top | nindent 4 }}
{{- with $pod.podLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with $pod.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 4 }}
{{- end }}
serviceAccountName: {{ include "common.serviceAccountName" (list $top $serviceAccount) }}
securityContext:
{{- toYaml $pod.podSecurityContext | nindent 4 }}
containers:
- {{- include "common.container" (list $top $pod) | nindent 4 }}
{{- with $pod.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $pod.affinity }}
affinity:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $pod.tolerations }}
tolerations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with $pod.priorityClassName }}
priorityClassName: {{ . }}
{{- end }}
{{- end }}
{{- define "common.pod.template" -}}
{{- include "common.utils.merge" (append . "common.pod.template.tpl") }}
{{- end }}

15
templates/_secret.yaml Normal file
View File

@@ -0,0 +1,15 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.secret.tpl" -}}
{{- $top := first . }}
apiVersion: v1
kind: Secret
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
type: Opaque
data: {}
{{- end }}
{{- define "common.secret" -}}
{{- include "common.utils.merge" (append . "common.secret.tpl") }}
{{- end }}

View File

@@ -1,184 +0,0 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Generate secret name.
Usage:
{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }}
Params:
- existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user
to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility.
+info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret
- defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment.
- context - Dict - Required. The context for the template evaluation.
*/}}
{{- define "common.secrets.name" -}}
{{- $name := (include "common.fullname" .context) -}}
{{- if .defaultNameSuffix -}}
{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- with .existingSecret -}}
{{- if not (typeIs "string" .) -}}
{{- with .name -}}
{{- $name = . -}}
{{- end -}}
{{- else -}}
{{- $name = . -}}
{{- end -}}
{{- end -}}
{{- printf "%s" $name -}}
{{- end -}}
{{/*
Generate secret key.
Usage:
{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }}
Params:
- existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user
to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility.
+info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret
- key - String - Required. Name of the key in the secret.
*/}}
{{- define "common.secrets.key" -}}
{{- $key := .key -}}
{{- if .existingSecret -}}
{{- if not (typeIs "string" .existingSecret) -}}
{{- if .existingSecret.keyMapping -}}
{{- $key = index .existingSecret.keyMapping $.key -}}
{{- end -}}
{{- end }}
{{- end -}}
{{- printf "%s" $key -}}
{{- end -}}
{{/*
Generate secret password or retrieve one if already created.
Usage:
{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }}
Params:
- secret - String - Required - Name of the 'Secret' resource where the password is stored.
- key - String - Required - Name of the key in the secret.
- providedValues - List<String> - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value.
- length - int - Optional - Length of the generated random password.
- strong - Boolean - Optional - Whether to add symbols to the generated random password.
- chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart.
- context - Context - Required - Parent context.
The order in which this function returns a secret password:
1. Already existing 'Secret' resource
(If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned)
2. Password provided via the values.yaml
(If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned)
3. Randomly generated secret password
(A new random secret password with the length specified in the 'length' parameter will be generated and returned)
*/}}
{{- define "common.secrets.passwords.manage" -}}
{{- $password := "" }}
{{- $subchart := "" }}
{{- $chartName := default "" .chartName }}
{{- $passwordLength := default 32 .length }}
{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }}
{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }}
{{- $secretData := (lookup "v1" "Secret" (include "common.namespace" .context) .secret).data }}
{{- if $secretData }}
{{- if hasKey $secretData .key }}
{{- $password = index $secretData .key | quote }}
{{- else }}
{{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}}
{{- end -}}
{{- else if $providedPasswordValue }}
{{- $password = $providedPasswordValue | toString | b64enc | quote }}
{{- else }}
{{- if .context.Values.enabled }}
{{- $subchart = $chartName }}
{{- end -}}
{{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}}
{{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}}
{{- $passwordValidationErrors := list $requiredPasswordError -}}
{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}}
{{- if .strong }}
{{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }}
{{- $password = randAscii $passwordLength }}
{{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }}
{{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }}
{{- else if .hex }}
{{- $password = include "common.secrets.randHex" $passwordLength | b64enc | quote }}
{{- else }}
{{- $password = randAlphaNum $passwordLength | b64enc | quote }}
{{- end }}
{{- end -}}
{{- printf "%s" $password -}}
{{- end -}}
{{- /*
Returns given number of random Hex characters.
- randNumeric 4 | atoi generates a random number in [0, 10^4)
This is a range evenly divisble by 16, but even if off by one,
that last partial interval offsetting randomness is only 1 part in 625.
- mod N 16 maps to the range 0-15
- printf "%x" represents a single number 0-15 as a single hex character
*/}}
{{- define "common.secrets.randHex" -}}
{{- $result := "" }}
{{- range $i := until . }}
{{- $rand_hex_char := mod (randNumeric 4 | atoi) 16 | printf "%x" }}
{{- $result = print $result $rand_hex_char }}
{{- end }}
{{- $result }}
{{- end }}
{{/*
Reuses the value from an existing secret, otherwise sets its value to a default value.
Usage:
{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }}
Params:
- secret - String - Required - Name of the 'Secret' resource where the password is stored.
- key - String - Required - Name of the key in the secret.
- defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value.
- context - Context - Required - Parent context.
*/}}
{{- define "common.secrets.lookup" -}}
{{- $value := "" -}}
{{- $defaultValue := required "\n'common.secrets.lookup': Argument 'defaultValue' missing or empty" .defaultValue -}}
{{- $secretData := (lookup "v1" "Secret" (include "common.namespace" .context) .secret).data -}}
{{- if and $secretData (hasKey $secretData .key) -}}
{{- $value = index $secretData .key -}}
{{- else -}}
{{- $value = $defaultValue | toString | b64enc -}}
{{- end -}}
{{- printf "%s" $value -}}
{{- end -}}
{{/*
Returns whether a previous generated secret already exists
Usage:
{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }}
Params:
- secret - String - Required - Name of the 'Secret' resource where the password is stored.
- context - Context - Required - Parent context.
*/}}
{{- define "common.secrets.exists" -}}
{{- $secret := (lookup "v1" "Secret" (include "common.namespace" .context) .secret) }}
{{- if $secret }}
{{- true -}}
{{- end -}}
{{- end -}}

23
templates/_service.yaml Normal file
View File

@@ -0,0 +1,23 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.service.tpl" -}}
{{- $top := first . }}
{{- $service := index . 1 }}
apiVersion: v1
kind: Service
metadata:
{{- include "common.metadata" (list $top) | nindent 2 }}
spec:
type: {{ $service.type }}
ports:
- port: {{ $service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "common.selectorLabels" $top | nindent 4 }}
{{- end }}
{{- define "common.service" -}}
{{- include "common.utils.merge" (append . "common.service.tpl") }}
{{- end }}

View File

@@ -0,0 +1,26 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.serviceAccount.metadata" -}}
{{- $top := first . }}
{{- $serviceAccount := index . 1 }}
name: {{ include "common.serviceAccountName" . }}
{{- with $serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- define "common.serviceAccount.tpl" -}}
apiVersion: v1
kind: ServiceAccount
metadata:
{{- include "common.metadata" (append . "common.serviceAccount.metadata") | nindent 2 }}
{{- end }}
{{- define "common.serviceAccount" -}}
{{- $top := first . }}
{{- $serviceAccount := index . 1 }}
{{- if $serviceAccount.create }}
{{- include "common.utils.merge" (append . "common.serviceAccount.tpl") }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,25 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.serviceMonitor.secret.tpl" -}}
{{- $top := first . }}
{{- $serviceMonitor := index . 1 }}
{{- $basicAuth := $serviceMonitor.basicAuth | default (dict) }}
metadata:
name: {{ $basicAuth.secretName | default (include "common.fullname" $top) }}
{{- with $serviceMonitor.namespace }}
namespace: {{ . }}
{{- end }}
{{- if $basicAuth.enabled }}
data:
{{ $basicAuth.usernameKey | default "username" }}: {{ $basicAuth.username | toString | b64enc | quote }}
{{ $basicAuth.passwordKey | default "password" }}: {{ $basicAuth.password | toString | b64enc | quote }}
{{- end }}
{{- end }}
{{- define "common.serviceMonitor.secret" -}}
{{- $top := first . }}
{{- $serviceMonitor := index . 1 }}
{{- if $serviceMonitor.enabled }}
{{- include "common.secret" (append . "common.serviceMonitor.secret.tpl") }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,54 @@
{{/* vim: set filetype=mustache: */}}
{{- define "common.serviceMonitor.metadata" -}}
{{- $serviceMonitor := index . 1 }}
{{- with $serviceMonitor.namespace }}
namespace: {{ . }}
{{- end }}
{{- end }}
{{- define "common.serviceMonitor.tpl" -}}
{{- $top := first . }}
{{- $serviceMonitor := index . 1 }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
{{- include "common.metadata" (append . "common.serviceMonitor.metadata") | nindent 2 }}
spec:
selector:
matchLabels:
{{- include "common.selectorLabels" $top | nindent 6 }}
namespaceSelector:
matchNames:
- {{ $top.Release.Namespace | quote }}
endpoints:
- port: "{{ $serviceMonitor.port }}"
{{- with $serviceMonitor.path }}
path: {{ . }}
{{- end }}
{{- with $serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with $serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
{{- $basicAuth := $serviceMonitor.basicAuth | default (dict) }}
{{- $name := $basicAuth.secretName | default (include "common.fullname" $top) }}
{{- if $basicAuth.enabled }}
basicAuth:
username:
name: {{ $name }}
key: {{ $basicAuth.usernameKey | default "username" }}
password:
name: {{ $name }}
key: {{ $basicAuth.passwordKey | default "password" }}
{{- end }}
{{- end }}
{{- define "common.serviceMonitor" -}}
{{- $top := first . }}
{{- $serviceMonitor := index . 1 }}
{{- if $serviceMonitor.enabled }}
{{- include "common.utils.merge" (append . "common.serviceMonitor.tpl") }}
{{- end }}
{{- end }}

View File

@@ -22,65 +22,3 @@ This takes an list of values:
{{- include $tplName $args }}
{{- end }}
{{- end }}
{{/*
Print instructions to get a secret value.
Usage:
{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }}
*/}}
{{- define "common.utils.secret.getvalue" -}}
{{- $varname := include "common.utils.fieldToEnvVar" . -}}
export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d)
{{- end -}}
{{/*
Build env var name given a field
Usage:
{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }}
*/}}
{{- define "common.utils.fieldToEnvVar" -}}
{{- $fieldNameSplit := splitList "-" .field -}}
{{- $upperCaseFieldNameSplit := list -}}
{{- range $fieldNameSplit -}}
{{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}}
{{- end -}}
{{ join "_" $upperCaseFieldNameSplit }}
{{- end -}}
{{/*
Gets a value from .Values given
Usage:
{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }}
*/}}
{{- define "common.utils.getValueFromKey" -}}
{{- $splitKey := splitList "." .key -}}
{{- $value := "" -}}
{{- $latestObj := $.context.Values -}}
{{- range $splitKey -}}
{{- if not $latestObj -}}
{{- printf "please review the entire path of '%s' exists in values" $.key | fail -}}
{{- end -}}
{{- $value = ( index $latestObj . ) -}}
{{- $latestObj = $value -}}
{{- end -}}
{{- printf "%v" (default "" $value) -}}
{{- end -}}
{{/*
Returns first .Values key with a defined value or first of the list if all non-defined
Usage:
{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }}
*/}}
{{- define "common.utils.getKeyFromList" -}}
{{- $key := first .keys -}}
{{- $reverseKeys := reverse .keys }}
{{- range $reverseKeys }}
{{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }}
{{- if $value -}}
{{- $key = . }}
{{- end -}}
{{- end -}}
{{- printf "%s" $key -}}
{{- end -}}

View File

@@ -1,46 +0,0 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Validate values must not be empty.
Usage:
{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}}
{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}}
{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }}
Validate value params:
- valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password"
- secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret"
- field - String - Optional. Name of the field in the secret data, e.g: "mysql-password"
*/}}
{{- define "common.validations.values.multiple.empty" -}}
{{- range .required -}}
{{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}}
{{- end -}}
{{- end -}}
{{/*
Validate a value must not be empty.
Usage:
{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }}
Validate value params:
- valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password"
- secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret"
- field - String - Optional. Name of the field in the secret data, e.g: "mysql-password"
- subchart - String - Optional - Name of the subchart that the validated password is part of.
*/}}
{{- define "common.validations.values.single.empty" -}}
{{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }}
{{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }}
{{- if not $value -}}
{{- $varname := "my-value" -}}
{{- $getCurrentValue := "" -}}
{{- if and .secret .field -}}
{{- $varname = include "common.utils.fieldToEnvVar" . -}}
{{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}}
{{- end -}}
{{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}}
{{- end -}}
{{- end -}}