24 Commits

Author SHA1 Message Date
Renovate Bot
a83c9f9e08 Add renovate.json 2023-09-01 22:24:10 +00:00
96ece23aee feat: change drone to gitea actions
All checks were successful
Release Chart / release (push) Successful in 13s
2023-08-28 01:05:31 +03:00
c9f4c7eeb4 fix: use oci in templates
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-06-18 16:55:08 +03:00
e602d9f045 ci: use oci
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2023-05-18 01:14:45 +03:00
1bbfd49265 feat(secret): allow generate hex
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-03 23:59:32 +03:00
93c81fddb9 cs: fix 2023-03-03 23:02:51 +03:00
964f7e9c5d fix: remove duplicated pullSecret
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-03 22:59:07 +03:00
4f80520c7e fix(deployment): envFrom 2023-03-03 22:57:28 +03:00
c850e79d2a fix(starter): add image.registry to values.yaml
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-03 00:05:12 +03:00
eafcf8ba09 chore: increase default password length up to 32
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 23:57:38 +03:00
6342d7be31 cs: fix
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 23:44:38 +03:00
1975611101 fix: add ingressClassName 2023-03-02 23:43:26 +03:00
42a80492ad fix(metadata): remove duplications
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 23:31:55 +03:00
23bbb0a65d chore(starter): remove compatibility with older k8s from ingress
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 23:30:31 +03:00
460c4b6c5c feat: simplify starter
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-02 23:21:08 +03:00
bcf9648dae feat: add app.kubernetes.io/name and app.kubernetes.io/instance to default labels 2023-03-02 23:20:23 +03:00
19440d56a6 ci: ignore .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-01 23:40:14 +03:00
b4fe1239b5 refactor: print debug as yaml 2023-03-01 23:39:53 +03:00
98d893e74b feat: add debug 2023-03-01 22:04:37 +03:00
1f3a7e1050 feat: add some templates from bitnami/common
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-01 20:59:09 +03:00
76793993d9 feat(starter): add configmap and secret
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-01 18:52:10 +03:00
ef59f16734 chore(starter): use ^0 common version
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-01 18:46:18 +03:00
1063874798 fix: create boilerplate to current dir
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-01 18:42:14 +03:00
0c268065b8 chore: change urls #2 2023-03-01 18:41:30 +03:00
38 changed files with 557 additions and 1489 deletions

View File

@@ -1,21 +0,0 @@
---
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

@@ -0,0 +1,29 @@
name: Release Chart
on:
push:
tags:
- '*'
jobs:
release:
runs-on: ubuntu-latest
env:
REGISTRY: harbor.grachevko.ru
steps:
- uses: actions/checkout@v3
- 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 }}

View File

@@ -1,45 +0,0 @@
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,3 +27,6 @@ starter/
gcloud_auth_key.json
create.sh
README.md
# Ci
.drone.yml

946
README.md

File diff suppressed because it is too large Load Diff

View File

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

3
renovate.json Normal file
View File

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

View File

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

View File

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

View File

@@ -1,3 +1,7 @@
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

@@ -0,0 +1,12 @@
{{- 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,26 +1,85 @@
{{/* vim: set filetype=mustache: */}}
{{- include "common.deployment" (list . .Values .Values.autoscaling .Values.serviceAccount "<CHARTNAME>.deployment") }}
{{- define "<CHARTNAME>.deployment" -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "common.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
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:
- {{- 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 }}
- 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 }}

View File

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

View File

@@ -1,3 +1,41 @@
{{/* vim: set filetype=mustache: */}}
{{- include "common.ingress" (list . .Values.ingress .Values.service) }}
{{- 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 }}

View File

@@ -0,0 +1,10 @@
{{- 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,3 +1,15 @@
{{/* vim: set filetype=mustache: */}}
{{- include "common.service" (list . .Values.service) }}
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 }}

View File

@@ -1,3 +0,0 @@
{{/* 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,9 +2,17 @@
# 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.
@@ -42,6 +50,11 @@ 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"

View File

@@ -1,14 +0,0 @@
{{/* 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 }}

View File

@@ -1,18 +0,0 @@
{{/* 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 }}

View File

@@ -1,49 +0,0 @@
{{/* 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 }}

3
templates/_debug.yaml Normal file
View File

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

View File

@@ -1,25 +0,0 @@
{{/* 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 }}

23
templates/_errors.tpl Normal file
View File

@@ -0,0 +1,23 @@
{{/* 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 -}}

View File

@@ -1,45 +0,0 @@
{{/* 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 }}

View File

@@ -1,67 +0,0 @@
{{/* 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,3 +44,10 @@ 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 -}}

View File

@@ -1,36 +0,0 @@
{{/* 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 }}

View File

@@ -1,46 +0,0 @@
{{/* 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 }}

View File

@@ -1,15 +0,0 @@
{{/* 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 }}

184
templates/_secrets.tpl Normal file
View File

@@ -0,0 +1,184 @@
{{/* 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 -}}

View File

@@ -1,23 +0,0 @@
{{/* 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

@@ -1,26 +0,0 @@
{{/* 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

@@ -1,25 +0,0 @@
{{/* 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

@@ -1,54 +0,0 @@
{{/* 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,3 +22,65 @@ 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

@@ -0,0 +1,46 @@
{{/* 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 -}}