Add the helm chart
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Nikolai Rodionov 2025-01-18 11:59:15 +01:00
parent 609949bb08
commit 65b90453dc
Signed by: allanger
GPG Key ID: 09F8B434D0FDD99B
33 changed files with 1205 additions and 0 deletions

23
helm/.helmignore Normal file
View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

6
helm/Chart.lock Normal file
View File

@ -0,0 +1,6 @@
dependencies:
- name: helm-library
repository: oci://ghcr.io/allanger/allangers-helm-library
version: 0.2.1
digest: sha256:1a2c38771fede69ddcb6fa6da8927780f1dc36e1f0f92233d747e943cd76dedb
generated: "2025-01-13T14:09:55.344423+01:00"

15
helm/Chart.yaml Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v2
name: xray-docs
type: application
version: 0.1.0
appVersion: 0.1.0
maintainers:
- name: allanger
email: allanger@zohomail.com
url: https://badhouseplants.net
dependencies:
- name: helm-library
version: 0.2.1
repository: oci://ghcr.io/allanger/allangers-helm-library
annotations:
allowed_workload_kinds: "Deployment"

Binary file not shown.

View File

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@ -0,0 +1,6 @@
dependencies:
- name: raw
repository: https://bedag.github.io/helm-charts/
version: 2.0.0
digest: sha256:12c18557553d75f5e57efa02a359517b9d95e47e80be270af17c63f9ccaff3d1
generated: "2024-12-29T11:06:41.044864+01:00"

View File

@ -0,0 +1,12 @@
apiVersion: v2
description: A Helm library to be reused by allanger's charts. It's supposed to become
an alternative for k8s-at-home
keywords:
- allanger
- k8s-at-home
maintainers:
- email: allanger@badhouseplants.net
name: allanger
name: helm-library
type: library
version: 0.2.0+09454ec

View File

@ -0,0 +1,57 @@
{{/*
* Expand the name of the chart.
*/}}
{{- define "lib.chart.name" -}} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
{{- default .ctx.Chart.Name .ctx.Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }} {{- /*/define[0] */}}
{{/*
* Create chart name and version as used by the chart label.
*/}}
{{- define "lib.chart.chart" -}} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
{{- printf "%s-%s" .ctx.Chart.Name .ctx.Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }} {{- /*/define[0] */}}
{{/*
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 "lib.chart.fullname" -}}
{{- include "lib.error.noCtx" . -}}
{{- if .ctx.Values.fullnameOverride }}
{{- .ctx.Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .ctx.Chart.Name .ctx.Values.nameOverride }}
{{- if contains $name .ctx.Release.Name }}
{{- .ctx.Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .ctx.Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
* Common labels
*/}}
{{- define "lib.chart.labels" -}} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
helm.sh/chart: {{ include "lib.chart.chart" (dict "ctx" .ctx) }}
{{ include "lib.chart.selectorLabels" (dict "ctx" .ctx) }}
{{- if .ctx.Chart.AppVersion }} {{- /* if[1] */}}
app.kubernetes.io/version: {{ .ctx.Chart.AppVersion | quote }}
{{- end }} {{- /* /if[1] */}}
app.kubernetes.io/managed-by: {{ .ctx.Release.Service }}
{{- end }} {{- /*/define[0] */}}
{{/*
* Selector labels
*/}}
{{- define "lib.chart.selectorLabels" -}} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
app.kubernetes.io/name: {{ include "lib.chart.name" (dict "ctx" .ctx) }}
app.kubernetes.io/instance: {{ .ctx.Release.Name }}
{{- end }} {{- /*/define[0] */}}

View File

@ -0,0 +1,15 @@
{{- define "lib.error.noCtx" -}} {{- /* define[0] */ -}}
{{- if not .ctx -}}{{- fail "no context provided" -}}{{- end -}}
{{- if not (kindIs "map" .ctx) -}} {{- /* if[1] */ -}}
{{- fail "unexpected type of ctx" -}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.error.noKey" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- if not .key -}}{{ fail "error handler must receive a key to find" }}{{- end -}}
{{- if not (hasKey .ctx .key) -}} {{- /* if[1] */ -}}
{{- fail (printf "key %s must be not null" .key) -}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,17 @@
{{/*
* CRDs should always be managed as a separate chart
* They must be written to the ./crd folder and then
* they will be read by the .Files helm feature
*/}}
{{- define "lib.component.crd" -}} {{- /* define[0] */ -}}
{{-
$metadata := include "lib.metadata"
(dict "ctx" $ "annotations" .Values.workload.annotations)
}}
{{ $currentScope := .}}
{{ range $path, $_ := .Files.Glob "**.yaml" }}
{{- with $currentScope}}
{{ .Files.Get $path }}
{{- end }}
{{ end }}
{{- end -}} {{- /* define[0] */ -}}

View File

@ -0,0 +1,46 @@
{{/*
* This component should make it easier to create sets
* of environment variables via configmaps and secrets
*/}}
{{- define "lib.component.environment" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- range $k, $v := .ctx.Values.config.env }} {{- /* range[0] */}}
{{- $customName := include "lib.component.env.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.enabled }} {{- /* if[0] */}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" $.ctx
"global" ($.ctx.Values.metadata).labels
"local" ($v.metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" $.ctx
"name" $customName
"annotations" ($v.metadata).annotations
"labels" $labels
)
}}
{{- $data := dict -}}
{{- range $key, $value := $v.data }} {{- /* range[1] */}}
{{- if not (has $key ($v.remove)) }} {{- /* if[1] */}}
{{- $_ := set $data $key (tpl (toString $value) $.ctx) }}
{{- end }} {{- /* /if[1] */}}
{{- end }} {{- /* /range[1] */}}
{{- if $v.sensitive }} {{- /* if[1] */}}
{{ include "lib.core.secret" (dict "ctx" $ "metadata" $metadata "data" $data) }}
{{- else }}
{{ include "lib.core.configmap" (dict "ctx" $ "metadata" $metadata "data" $data) }}
{{- end -}} {{- /* /if[1] */}}
{{- end }} {{- /* /if[0] */}}
{{- end }} {{- /* /range[0] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.component.env.name" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
{{ printf "%s-%s-env" .ctx.Release.Name .name }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,16 @@
{{- define "lib.component.templates" }} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" .ctx
"global" ((.ctx.Values).metadata).labels
)
}}
{{- with (.ctx.Values.extra).templates }} {{- /* with[1] */}}
{{- range . }} {{- /* range[2] */}}
---
{{- tpl . $.ctx | indent 0 }}
{{- end }} {{- /* /range[2] */}}
{{- end }} {{- /* /with[1] */}}
{{- end }} {{- /* /define[0] */}}

View File

@ -0,0 +1,64 @@
{{/*
* This component should make it easier to create sets
* of environment variables via configmaps and secrets
*/}}
{{- define "lib.component.files" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- range $k, $v := .ctx.Values.config.files }} {{- /* range[0] */}}
{{- $customName := include "lib.component.file.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.enabled }} {{- /* if[0] */}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" $.ctx
"global" ($.ctx.Values.metadata).labels
"local" ($v.metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" $.ctx
"name" $customName
"annotations" $v.annotations
"labels" $labels
)
}}
{{- $entries := dict -}}
{{- range $key, $value := $v.entries }} {{- /* range[1] */}}
{{- if not (has $key ($v.remove)) }} {{- /* if[1] */}}
{{- $data := $value.data }}
{{- if and (kindIs "string" $data) ($value.convertTo) }} {{- /* if[2] */}}
{{- fail "convering is only possible for plain yaml, strings are not supported" -}}
{{- end }} {{- /* /if[2] */}}
{{- if $value.convertTo -}} {{- /* if[2] */ -}}
{{- if eq $value.convertTo "json" }} {{- /* if[3] */}}
{{- $data = include "lib.helpers.convertToJson" $data -}}
{{- else if eq $value.convertTo "toml" -}}
{{- $data = include "lib.helpers.convertToToml" $data -}}
{{- else if eq $value.convertTo "yaml" -}}
{{- $data = include "lib.helpers.convertToYaml" $data -}}
{{- else -}}
{{- fail (printf "converion to %s is not supported yet" $value.convertTo) -}}
{{- end -}} {{- /* /if[3] */ -}}
{{- end -}} {{- /* /if[2] */ -}}
{{- if not (kindIs "string" $data) -}}
{{- fail (printf "it must be a string, but it's a %s: %v" (kindOf $data) $data) -}}
{{- end -}}
{{- $_ := set $entries $key (tpl $data $.ctx) }}
{{- end }} {{- /* /if[1] */}}
{{- end }} {{- /* /range[1] */}}
{{- if $v.sensitive }} {{- /* if[1] */}}
{{ include "lib.core.secret" (dict "ctx" $ "metadata" $metadata "data" $entries) }}
{{- else }}
{{ include "lib.core.configmap" (dict "ctx" $ "metadata" $metadata "data" $entries) }}
{{- end -}} {{- /* /if[1] */}}
{{- end }} {{- /* /if[0] */}}
{{- end }} {{- /* /range[0] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.component.file.name" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
{{ printf "%s-%s-file" .ctx.Release.Name .name }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,33 @@
{{- define "lib.component.ingress" }}
{{- range $k, $v := .ctx.Values.ingress }}
{{- $customName := include "lib.component.ingress.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.enabled }} {{- /* if[0] */}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" $.ctx
"global" ($.ctx.Values.metadata).labels
"local" ($v.metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" $.ctx
"annotations" ($v.metadata).annotations
"labels" $labels
"name" $customName
)
}}
{{- $spec := $v -}}
{{- $_ := unset $spec "enabled" -}}
{{ include "lib.core.ingress" (dict "ctx" $.ctx "metadata" $metadata "spec" $spec ) }}
{{- end }}
{{- end }}
{{- end }}
{{- define "lib.component.ingress.name" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
{{ printf "%s-%s" .ctx.Release.Name .name }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,42 @@
{{/*
* This component should make it easier to create pvc
*/}}
{{- define "lib.component.service" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- range $k, $v := .ctx.Values.services }} {{- /* range[1] */}}
{{- $customName := include "lib.component.service.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.enabled }} {{- /* if[2] */}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" $.ctx
"global" ($.ctx.Values.metadata).labels
"local" ($v.metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" $.ctx
"name" $customName
"annotations" ($v.metadata).annotations
"labels" $labels
)
}}
{{ $spec := $v }}
{{- if not $spec.type -}}
{{- set $spec "type" "ClusterIP" -}}
{{- end }}
{{
include "lib.core.service"
(dict "ctx" $.ctx "metadata" $metadata "spec" $spec)
}}
{{- end }}
{{- end }}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.component.service.name" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
{{ printf "%s-%s" .ctx.Release.Name .name }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,35 @@
{{/*
* This component should make it easier to create pvc
*/}}
{{- define "lib.component.storage" -}}
{{- include "lib.error.noCtx" . -}}
{{- range $k, $v := .ctx.Values.storage }}
{{- $customName := include "lib.component.storage.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.enabled }} {{- /* if[0] */}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" $.ctx
"global" ($.ctx.Values.metadata).labels
"local" ($v.metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" $.ctx
"annotations" ($v.metadata).annotations
"labels" $labels
"name" $customName
)
}}
{{ include "lib.core.pvc" (dict "metadata" $metadata "spec" $v) }}
{{- end }} {{- /* /if[0] */}}
{{- end }}
{{- end -}}
{{- define "lib.component.storage.name" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
{{ printf "%s-%s-storage" .ctx.Release.Name .name }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,65 @@
{{- define "lib.component.workload.allowed" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{ index .ctx.Chart.Annotations "allowed_workload_kinds" }}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.component.workload" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{-
$labels := include "lib.metadata.mergeLabels"
(dict
"ctx" .ctx
"global" ((.ctx.Values).metadata).labels
"local" (((.ctx.Values.base).workload).metadata).labels
)
}}
{{-
$metadata := include "lib.metadata"
(dict
"ctx" .ctx
"annotations" (((.ctx.Values.base).workload).metadata).annotations
"labels" $labels
)
}}
{{-
$securityContext := include "lib.core.pod.securityContext"
(dict
"securityContext" .ctx.Values.base.workload.securityContext
)
}}
{{
$containers := include "lib.core.pod.containers"
(dict
"ctx" .ctx
"containers" .ctx.Values.base.workload.containers
)
}}
{{
$volumes := include "lib.core.pod.volumes"
(dict
"ctx" .ctx
"files" (.ctx.Values.config).files
"storage" .ctx.Values.storage
"extraVolumes" .ctx.Values.extraVolumes
)
}}
{{- if eq .ctx.Values.base.workload.kind "Deployment" -}} {{- /* if[0] */ -}}
{{- if contains .ctx.Values.base.workload.kind (include "lib.component.workload.allowed" (dict "ctx" .ctx)) }}{{- /* if[0] */ -}}
{{-
include "lib.core.deployment"
(dict
"ctx" .ctx
"metadata" $metadata
"securityContext" $securityContext
"containers" $containers
"volumes" $volumes
)
}}
{{- else -}}
{{- fail (printf "workload kind is not allowed: %s" .ctx.Values.base.workload.kind) -}}
{{- end }}{{- /* if[1] */ -}}
{{- end -}} {{- /* /if[0]*/ -}}
{{- end -}}{{- /* /define[0] */ -}}

View File

@ -0,0 +1,18 @@
{{- define "lib.core.configmap" -}} {{- /* define[0] */}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "metadata") -}}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata:
{{ .metadata | indent 2 }}
data:
{{- range $key, $value := .data }}
{{- if $value }}
{{ $key }}: {{ tpl $value $.Context | quote }}
{{- end }}
{{- end }}
{{- end -}} {{- /* /define[0]) */ -}}

View File

@ -0,0 +1,78 @@
{{/*
* Bootstrap a deployment
* It should always receive a dict as an argument
*/}}
{{- define "lib.core.deployment" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "securityContext") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "metadata") -}}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
{{ .metadata | indent 2 }}
spec:
{{-
include "lib.core.deployment.spec"
(dict
"ctx" .ctx
"securityContext" .securityContext
"metadata" .metadata
"containers" .containers
"volumes" .volumes
)
| indent 2
}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.deployment.spec" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . }}
{{- include "lib.error.noKey" (dict "ctx" . "key" "securityContext") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "metadata") }}
replicas: {{ .ctx.Values.base.workload.replicas | default 1 }}
selector:
matchLabels:
{{- include "lib.chart.selectorLabels" (dict "ctx" .ctx) | nindent 6 }}
{{
include "lib.core.deployment.template"
(dict
"ctx" .ctx
"securityContext" .securityContext
"metadata" .metadata
"containers" .containers
"volumes" .volumes
)
}}
{{- end -}} {{- /* /define[0] */ -}}
{{- /* A deployment temopalte goes here */ -}}
{{- define "lib.core.deployment.template" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "securityContext") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "metadata") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "containers") -}}
{{- $labels := toYaml (index (fromYaml .metadata) "labels") -}}
{{- $annotations := toYaml (index (fromYaml .metadata) "annotations") -}}
template:
metadata:
labels:
{{- $labels | nindent 6 }}
annotations:
{{- if not (eq $annotations "null") }}
{{- $annotations | nindent 6 }}
{{- end }}
{{
include "lib.helpers.hashes"
(dict
"env" (.ctx.Values.config).env
"files" (.ctx.Values.config).files)
| nindent 6
}}
spec:
{{- .securityContext | nindent 4 }}
{{ .containers | nindent 4 }}
{{ .volumes | nindent 4 }}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,20 @@
{{- define "lib.core.ingress" }}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
{{- .metadata | nindent 2 }}
spec:
ingressClassName: {{ .spec.class }}
{{- with .spec.rules }}
rules:
{{- tpl ( . | toYaml | nindent 4 | toString) $.ctx }}
{{- end }}
{{- with .spec.tls }}
tls:
{{- tpl ( . | toYaml | nindent 4 | toString) $.ctx }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,117 @@
{{- define "lib.core.pod" -}} {{- /* define[0] */ -}}
{{- fail "pods are not implemented net" -}}
{{- end -}} {{- /* /define[0] */ -}}
{{/*
* This function should accept a seucrityContext
* from values, so please use it with values
* directly
* SecurityContext is not templated, so it will be
* added as is
*/}}
{{- define "lib.core.pod.securityContext" -}} {{- /* define[0] */ -}}
securityContext:
{{- if not .securityContext }} {{- /* if[1] */}}
# ---------------------------------------------------------------------
# Using the default security context, if it doesn't work for you,
# please update `.Values.base.workload.securityContext`
# ---------------------------------------------------------------------
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
{{- else -}}
{{- with .securityContext }} {{- /* with[2] */}}
{{ toYaml . | indent 2 }}
{{- end -}} {{- /* /with[2] */}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* define[0] */ -}}
{{- define "lib.core.pod.volumes" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "storage") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "files") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "extraVolumes") -}}
{{- if or (or .storage .files) .extraVolumes -}} {{- /* if[0]*/ -}}
volumes:
{{- /* If storage is defined, mount a pvc */ -}}
{{- if .storage }} {{- /* if[1] */}}
{{- range $k, $v := .storage }} {{- /* range[0] */}}
{{- if $v.enabled }}
{{- $name := include "lib.component.storage.name" (dict "ctx" $.ctx "name" $k) }}
- name: {{ $k }}-storage
persistentVolumeClaim:
claimName: {{ $name }}
{{- end }}
{{- end }} {{- /* /range[0] */}}
{{- end }} {{- /* /if[1] */}}
{{- if .extraVolumes}} {{- /* if[1] */}}
{{- range $k, $v := .extraVolumes}} {{- /* range[0] */}}
- name: {{ $k }}-extra
{{- $v | toYaml | nindent 4 }}
{{- end }} {{- /* /range[0] */}}
{{- end }} {{- /* /if[1] */}}
{{- if .files }} {{- /* if[1] */}}
{{- range $k, $v := .files }} {{- /* range[0] */}}
- name: {{ $k }}-file
{{- $name := include "lib.component.file.name" (dict "ctx" $.ctx "name" $k) }}
{{- if $v.sensitive }} {{- /* if[2] */}}
secret:
defaultMode: 420
secretName: {{ $name }}
{{- else }}
configMap:
name: {{ $name }}
{{- end }} {{- /* /if[2] */}}
{{- end }} {{- /* /range[0] */}}
{{- end }} {{- /* /if[1] */}}
{{- end -}} {{- /* /if[0] */ -}}
{{- end -}} {{- /* define[0] */ -}}
{{/*
* This template should generate a valid container
* defintion that should be used by both
* containers and initContainers
*/}}
{{- define "lib.core.pod.containers" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "containers") -}}
{{- $ctx := .ctx }}
containers:
{{- $containers := list }}
{{- range $k, $v := .containers }} {{- /* range[1] */}}
{{- $containerRaw := include "lib.core.pod.container"
(dict
"ctx" $ctx
"name" $k
"data" $v
)
}}
{{- $container := fromYaml $containerRaw }}
{{- if hasKey $container "Error" }} {{- /* if[2] */}}
{{- fail (printf "%s\n%v" $container $containerRaw) }}
{{- end }} {{- /* /if[1] */}}
{{- $containers = append $containers $container }}
{{- end }} {{- /* /range[1] */}}
{{ $containers | toYaml | indent 2 }}
{{- end -}} {{- /* define[0] */ -}}
{{- define "lib.core.pod.initContainers" -}} {{- /* define[0] */ -}}
{{- end -}} {{- /* define[0] */ -}}
{{- define "lib.core.pod.container.image.tag" -}} {{/* define[0] */}}
{{- if or .tag .appVersion -}} {{/* if[1] */}}
{{- if .tag -}} {{/* if[2] */}}
{{- .tag -}}
{{- else -}}
{{- .appVersion -}}
{{- end -}} {{/* /if[2] */}}
{{- else -}}
{{ fail ".tag or .appVersion must be passed to this helper"}}
{{- end -}} {{/* /if[1] */}}
{{- end -}} {{/* /define[0] */}}

View File

@ -0,0 +1,21 @@
{{- define "lib.core.pvc" -}}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
{{- .metadata | nindent 2 }}
spec:
{{- with .spec.accessModes }}
accessModes:
{{ toYaml . | indent 4}}
{{- end }}
resources:
requests:
storage: {{ .spec.size }}
{{- if ne .spec.storageClassName "default" }}
storageClassName: {{ .spec.storageClassName }}
{{- end }}
{{- end -}}

View File

@ -0,0 +1,16 @@
{{- define "lib.core.secret" -}} {{- /* define[0] */}}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: v1
kind: Secret
metadata:
{{- .metadata | nindent 2 }}
data:
{{- range $key, $value := .data }}
{{- if $value }}
{{ $key }}: {{ tpl $value $.Context | b64enc }}
{{- end }}
{{- end }}
{{- end -}} {{- /* /define[0]) */ -}}

View File

@ -0,0 +1,21 @@
{{- define "lib.core.service" }}
---
# ---------------------------------------------------------------------
# -- This resource is managed by the allanger's helm library
# ---------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
{{- .metadata | nindent 2 }}
spec:
type: {{ .spec.type }}
selector:
{{- include "lib.chart.selectorLabels" (dict "ctx" .ctx) | nindent 4 }}
ports:
{{- range $k,$v := .spec.ports }} {{- /* range[0] */}}
- name: {{ $k }}
port: {{ $v.port }}
targetPort: {{ $v.targetPort}}
protocol: {{ $v.protocol}}
{{- end }} {{- /* /range[0] */}}
{{- end }}

View File

@ -0,0 +1,214 @@
{{/*
* This template should be able to create a valid container spec
*/}}
{{- define "lib.core.pod.container" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "data") -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "name") -}}
name: {{ .name }}
{{ include "lib.core.pod.container.securityContext" (dict "securityContext" .data.securityContext) }}
{{ include "lib.core.pod.container.command" (dict "command" .data.command) }}
{{ include "lib.core.pod.container.args" (dict "args" .data.command) }}
{{ include "lib.core.pod.container.livenessProbe" (dict "ctx" .ctx "probe" .data.livenessProbe) }}
{{ include "lib.core.pod.container.readinessProbe" (dict "ctx" .ctx "probe" .data.readinessProbe) }}
{{ include "lib.core.pod.container.startupProbe" (dict "ctx" .ctx "probe" .data.readinessProbe) }}
{{ include "lib.core.pod.container.image" (dict "ctx" .ctx "image" .data.image) }}
{{ include "lib.core.pod.container.envFrom" (dict "ctx" .ctx "envFrom" .data.envFrom) }}
{{ include "lib.core.pod.container.volumeMounts" (dict "ctx" .ctx "mounts" .data.volumeMounts) }}
{{ include "lib.core.pod.container.ports" (dict "ctx" .ctx "ports" .data.ports) }}
{{- /*
{{-
include "lib.core.pod.container.ports"
(dict "Context" .Context "Container" .ContainerData)
| indent 2
-}}
{{-
include "lib.core.pod.container.volumeMounts"
.ContainerData | indent 2
-}}
*/}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.securityContext" }} {{- /* define[0] */ -}}
securityContext:
{{- if not .securityContext }} {{- /* if[1] */}}
# ---------------------------------------------------------------------
# Using the default security context, if it doesn't work for you,
# please update `.Values.base.workload.containers[].securityContext`
# ---------------------------------------------------------------------
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
{{- else }}
{{- with .securityContext }} {{- /* with[2] */}}
{{ toYaml . | indent 2 }}
{{- end }} {{- /* /with[2] */}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{/*
* Command and Args are accepting a dict as an argument
* dict should contain the following keys:
* - ctx
* - command/args (optional list) - When empty, entry is not added
*/}}
{{- define "lib.core.pod.container.command" -}} {{- /* define[0] */ -}}
{{- with .command -}} {{- /* with[1] */ -}}
command:
{{ . | toYaml | indent 2 }}
{{- end -}} {{- /* /with[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.args" -}} {{- /* define[0] */ -}}
{{- with .args -}} {{- /* with[1] */ -}}
args:
{{ . | toYaml | indent 2 }}
{{- end -}} {{- /* /with[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{/*
* Probes are accepting a dict as an argument
* dict should contain the following keys:
* - ctx
* - probe (optional) - When empty, probe is not added
*
* Notes: Probes can be tempalted, because some kinds of probes
* need to be aware of a port to be checking against. And to avoid
* copypaste all the probes are tempalted
*/}}
{{- define "lib.core.pod.container.readinessProbe" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "probe") -}}
{{- if .probe }} {{- /* if[1] */}}
{{- $probe := tpl (toYaml .probe) .ctx -}}
readinessProbe:
{{ $probe | indent 2}}
{{- end }} {{- /* /if[1] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.livenessProbe" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "probe") -}}
{{- if .probe }} {{- /* if[1] */}}
{{- $probe := tpl (toYaml .probe) .ctx -}}
livenessProbe:
{{ $probe | indent 2}}
{{- end }} {{- /* /if[1] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.startupProbe" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "probe") -}}
{{- if .probe }} {{- /* if[1] */}}
{{- $probe := tpl (toYaml .probe) .ctx -}}
startupProbe:
{{ $probe | indent 2}}
{{- end }} {{- /* /if[1] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.image" -}} {{/* define[0] */}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "image") -}}
image: {{ printf "%s/%s:%s"
.image.registry .image.repository
(include "lib.core.pod.container.image.tag"
(dict "appVersion" .ctx.Chart.AppVersion "tag" .image.tag))
}}
imagePullPolicy: {{ .image.pullPolicy | default "Always" }}
{{- end -}} {{/* /define[0] */}}
{{/*
* EnvFrom can either take values from predefined env values
* or add a raw envFrom entries to the manifests
* When using the predefined env, it's possible to remove entries
* using the '.remove' entry from the env mountpoint
*
* Should accept a dict with the followibg keys
* ctx
* envFrom
*
*/}}
{{- define "lib.core.pod.container.envFrom" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "envFrom") -}}
{{- /* If env should be set from a Configmap/Secret */ -}}
{{- if .envFrom -}} {{- /* if[1] */ -}}
envFrom:
{{- range $k, $v := .envFrom -}} {{- /* range[2] */ -}}
{{- if not (eq $k "raw") -}} {{- /* if[3] */ -}}
{{- $source := include "lib.helpers.lookup.env" (dict "ctx" $.ctx "key" $k) | fromYaml }}
{{- if $source.sensitive }}
- secretRef:
{{- else }}
- configMapRef:
{{- end }}
name: {{ include "lib.component.env.name" (dict "ctx" $.ctx "name" $k) }}
{{- else -}}
{{ $v | toYaml | nindent 2}}
{{- end }} {{- /* if[3] */}}
{{- end }} {{- /* /range[2] */}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.volumeMounts" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "mounts") -}}
{{- if .mounts }} {{- /* if[1] */}}
volumeMounts:
{{- range $mountKind, $mountData := .mounts }} {{- /* range[1] */}}
{{- if eq $mountKind "storage" }} {{- /* if[2] */}}
{{- range $mountName, $mountEntry := $mountData }} {{- /* range[3] */}}
{{- $name := include "lib.component.storage.name" (dict "ctx" $.ctx "name" $mountName) }}
- name: {{ $mountName }}-storage
mountPath: {{ $mountEntry.path }}
{{- end }} {{- /* /range[1] */}}
{{- end }} {{- /* /if[1] */}}
{{- if eq $mountKind "files" }} {{- /* if[1] */}}
{{- range $mountName, $mountEntry := $mountData }} {{- /* range[1] */}}
{{- $name := include "lib.component.file.name" (dict "ctx" $.ctx "name" $mountName) }}
- name: {{ $name }}
mountPath: {{ $mountEntry.path }}
{{- if $mountEntry.subPath }} {{- /* if[2] */}}
subPath: {{ $mountEntry.subPath }}
{{- end }} {{- /* /if[2] */}}
{{- end }} {{- /* /range[1] */}}
{{- end }} {{- /* /if[1] */}}
{{- if eq $mountKind "extraVolumes" }} {{- /* if[1] */}}
{{- range $mountName, $mountEntry := $mountData }} {{- /* range[1] */}}
- name: {{ printf "%s-extra" $mountName }}
mountPath: {{ $mountEntry.path }}
{{- end }} {{- /* /range[1] */}}
{{- end }} {{- /* /if[1] */}}
{{- end }} {{- /* /range[0] */}}
{{- end }} {{- /* /if[0] */}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.core.pod.container.ports" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "ports") -}}
{{- if .ports }} {{- /* if[0] */}}
ports:
{{- range $k, $v := .ports }} {{- /* range[0] */}}
{{- if and (kindIs "string" $v) (eq $k "raw") }} {{- /* if[1] */}}
{{- fail "raw port should be an array of ports" -}}
{{- end -}}
{{- if ne $k "raw" }}
{{- $service := include "lib.helpers.lookup.service" (dict "ctx" $.ctx "key" $k) | fromYaml -}}
{{- $ports := index $service "ports" }}
{{- range $port := $v }}
{{- $protocol := index (index $ports $port) "protocol" }}
{{- $containerPort := index (index $ports $port) "targetPort" }}
- containerPort: {{ $containerPort }}
protocol: {{ $protocol }}
{{- end }}
{{- else }}
{{ $v | toYaml | indent 2 -}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /range[0] */ -}}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,31 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "chart.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 "chart.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 "chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

View File

@ -0,0 +1,11 @@
{{- define "lib.helpers.convertToJson" -}}
{{ toString (toJson . ) }}
{{- end -}}
{{- define "lib.helpers.convertToToml" -}}
{{ toString (toToml .) }}
{{- end -}}
{{- define "lib.helpers.convertToYaml" -}}
{{ toString (toYaml .) }}
{{- end -}}

View File

@ -0,0 +1,31 @@
{{/*
* Populate hashes from configmaps and secret to
* trigger pod restart after config was changed
* TODO: Remove the extra empty line after annotations
*/}}
{{- define "lib.helpers.hashes" -}} {{- /* define[0] */ -}}
# ---------------------------------------------------------------------
# -- A note from the library:
# -- Pod annotations currently only support hashes of mounted
# -- config files and env variables and annotations inherited from
# -- the deployment
# ---------------------------------------------------------------------
{{ range $k, $v := .env -}} {{/* range[1] */ -}}
{{- if $v.enabled -}} {{- /* if[2] */ -}}
{{
include "lib.helpers.hash"
(dict "kind" "env" "name" $k "data" $v.data)
}}
{{ end -}} {{/* /if[2] */ -}}
{{- end -}} {{- /* /range[1] */ -}}
{{ range $k, $v := .files -}} {{/* range[1] */ -}}
{{
include "lib.helpers.hash"
(dict "kind" "file" "name" $k "data" ($v).entries)
}}
{{- end -}} {{- /* /range[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.helpers.hash" -}} {{- /* define[0] */ -}}
{{ printf "helm.badhouseplants.net/%s-%s" .kind .name }}: {{ .data | toString | sha256sum }}
{{- end -}} {{- /* /end[0] */ -}}

View File

@ -0,0 +1,32 @@
{{- define "lib.helpers.lookup.env" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "key") -}}
{{- $data := (index .ctx.Values.config.env .key) -}}
{{- if not $data }} {{- /* if[1] */}}
{{- fail (printf "entry %s is not found in env" .key) }}
{{- else -}} {{- /* .if[1] */ -}}
{{ toYaml $data }}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.helpers.lookup.storage" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "key") -}}
{{- $data := (index .ctx.Values.storage .key) -}}
{{- if not $data }} {{- /* if[1] */}}
{{- fail (printf "entry %s is not found in storage" .key) }}
{{- else -}} {{- /* .if[1] */ -}}
{{ toYaml $data }}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}
{{- define "lib.helpers.lookup.service" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "key") -}}
{{- $data := (index .ctx.Values.services .key) -}}
{{- if not $data }} {{- /* if[1] */}}
{{- fail (printf "entry %s is not found in services" .key) }}
{{- else -}} {{- /* .if[1] */ -}}
{{ toYaml $data }}
{{- end -}} {{- /* /if[1] */ -}}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,46 @@
{{/*
* Metadata is accepting a dict as an argument
* dict should contain the following keys:
* - ctx
* - name (optional)
* - labels
* - annotations (optional)
* TODO: Add a check to labels for an empty map (Labels must not be empty)
* TODO: Think about whether it's a good idea to let this function create resoutce with any namy
*/}}
{{- define "lib.metadata" -}} {{- /* define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{- include "lib.error.noKey" (dict "ctx" . "key" "labels") -}}
{{- if .name -}} {{- /* if[1] */ -}}
name: {{ .name }}
{{- else -}}
name: {{ include "lib.chart.fullname" (dict "ctx" .ctx) }}
{{- end }} {{- /* /if[1] */}}
labels:
{{ .labels | indent 2 }}
{{- if .annotations }} {{- /* if[1] */}}
annotations:
{{ toYaml .annotations | indent 2 }}
{{- end }} {{- /* /if[1] */}}
{{- end }} {{- /* /define[0] */ -}}
{{/*
* Merge global helm labels with custom ones
* accepts:
* ctx
* global (optional) - Labels that are defined for
* all resources
* local (optional) - Labels that are define only for
* the current resource
*/}}
{{- define "lib.metadata.mergeLabels" -}} {{- /* /define[0] */ -}}
{{- include "lib.error.noCtx" . -}}
{{ include "lib.chart.labels" (dict "ctx" .ctx) }}
{{- range $key, $val := .global }} {{- /* /range[1] */}}
{{ $key }}: {{ $val | quote }}
{{- end }} {{- /* /range[1] */}}
{{- range $key, $val := .local }} {{- /* /range[1] */}}
{{ $key }}: {{ $val | quote }}
{{- end }} {{- /* /range[1] */}}
{{- end -}} {{- /* /define[0] */ -}}

View File

@ -0,0 +1,5 @@
# @schema
# type: string
# @schema
# -- helm-docs description here
test: test

View File

@ -0,0 +1,6 @@
{{ include "lib.component.workload" (dict "ctx" .)}}
{{ include "lib.component.service" (dict "ctx" .) }}
{{ include "lib.component.ingress" (dict "ctx" .) }}
{{ include "lib.component.environment" (dict "ctx" .) }}
{{ include "lib.component.storage" (dict "ctx" .) }}
{{ include "lib.component.templates" (dict "ctx" .) }}

63
helm/values.yaml Normal file
View File

@ -0,0 +1,63 @@
---
shortcuts:
hostname: xray-docs.badhouseplants.net
base:
workload:
kind: Deployment
strategy:
type: RollingUpdate
containers:
xray-docs:
image:
registry: zot.badhouseplants.net
repository: badhouseplants/xray-docs
tag: latest
pullPolicy: Always
ports:
main:
- http
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
ingress:
main:
enabled: true
class: traefik
rules:
- host: "{{ .Values.shortcuts.hostname }}"
http:
paths:
- backend:
service:
name: '{{ include "chart.fullname" $ }}-main'
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- "{{ .Values.shortcuts.hostname }}"
secretName: "{{ .Values.shortcuts.hostname }}"
extraVolumes:
logs:
emptyDir: {}
services:
main:
enabled: true
type: ClusterIP
ports:
http:
port: 80
targetPort: 80
protocol: TCP