feat(common): Merge common library into this repo (#27272)

**Description**
This PR moves the common-library charts back into this repo.

**⚙️ Type of change**

- [ ] ⚙️ Feature/App addition
- [ ] 🪛 Bugfix
- [ ] ⚠️ Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] 🔃 Refactor of current code

**🧪 How Has This Been Tested?**
<!--
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration
-->

**📃 Notes:**
<!-- Please enter any other relevant information here -->

**✔️ Checklist:**

- [ ] ⚖️ My code follows the style guidelines of this project
- [ ] 👀 I have performed a self-review of my own code
- [ ] #️⃣ I have commented my code, particularly in hard-to-understand
areas
- [ ] 📄 I have made corresponding changes to the documentation
- [ ] ⚠️ My changes generate no new warnings
- [ ] 🧪 I have added tests to this description that prove my fix is
effective or that my feature works
- [ ] ⬆️ I increased versions for any altered app according to semantic
versioning
- [ ] I made sure the title starts with `feat(chart-name):`,
`fix(chart-name):` or `chore(chart-name):`

** App addition**

If this PR is an app addition please make sure you have done the
following.

- [ ] 🖼️ I have added an icon in the Chart's root directory called
`icon.png`

---

_Please don't blindly check all the boxes. Read them and only check
those that apply.
Those checkboxes are there for the reviewer to see what is this all
about and
the status of this PR with a quick glance._

---------

Signed-off-by: TrueCharts-Bot <bot@truecharts.org>
Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com>
Co-authored-by: TrueCharts-Admin <bot@truecharts.org>
Co-authored-by: Kjeld Schouten <kjeld@schouten-lebbing.nl>
Co-authored-by: Stavros kois <s.kois@outlook.com>
Co-authored-by: ばか雪 <165359296+bakayukii@users.noreply.github.com>
Co-authored-by: Tete17 <miguel_tete17@hotmail.com>
Co-authored-by: Matthew Salazar <matthew@mtslzr.io>
This commit is contained in:
Kjeld Schouten
2024-10-04 12:51:08 +02:00
committed by GitHub
co-authored by Stavros Kois TrueCharts-Admin Kjeld Schouten Stavros kois ばか雪 Tete17 Matthew Salazar
parent 859b00cf28
commit 2d0dd14947
500 changed files with 52613 additions and 0 deletions
+23
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/
+24
View File
@@ -0,0 +1,24 @@
apiVersion: v2
appVersion: "latest"
description: Function library for TrueCharts
home: https://github.com/truecharts/apps/tree/master/charts/common
icon: https://avatars.githubusercontent.com/u/76400755
keywords:
- truecharts
- library-chart
- common
kubeVersion: ">=1.24.0-0"
maintainers:
- email: info@truecharts.org
name: TrueCharts
url: https://truecharts.org
name: common
sources: null
type: library
version: 25.0.0
annotations:
artifacthub.io/category: "integration-delivery"
artifacthub.io/license: "BUSL-1.1"
artifacthub.io/links: |
- name: support
url: https://discord.com/invite/tVsPTHWTtr
+106
View File
@@ -0,0 +1,106 @@
Business Source License 1.1
Parameters
Licensor: The TrueCharts Project, it's owner and it's contributors
Licensed Work: The TrueCharts "Common" Helm Chart
Additional Use Grant: You may use the licensed work in production, as long
as it is directly sourced from a TrueCharts provided
official repository, catalog or source. You may also make private
modification to the directly sourced licenced work,
when used in production.
The following cases are, due to their nature, also
defined as 'production use' and explicitly prohibited:
- Bundling, including or displaying the licensed work
with(in) another work intended for production use,
with the apparent intend of facilitating and/or
promoting production use by third parties in
violation of this license.
Change Date: 2050-01-01
Change License: 3-clause BSD license
For information about alternative licensing arrangements for the Software,
please contact: legal@truecharts.org
Notice
The Business Source License (this document, or the “License”) is not an Open
Source license. However, the Licensed Work will eventually be made available
under an Open Source License, as stated in this License.
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
“Business Source License” is a trademark of MariaDB Corporation Ab.
-----------------------------------------------------------------------------
Business Source License 1.1
Terms
The Licensor hereby grants you the right to copy, modify, create derivative
works, redistribute, and make non-production use of the Licensed Work. The
Licensor may make an Additional Use Grant, above, permitting limited
production use.
Effective on the Change Date, or the fourth anniversary of the first publicly
available distribution of a specific version of the Licensed Work under this
License, whichever comes first, the Licensor hereby grants you rights under
the terms of the Change License, and the rights granted in the paragraph
above terminate.
If your use of the Licensed Work does not comply with the requirements
currently in effect as described in this License, you must purchase a
commercial license from the Licensor, its affiliated entities, or authorized
resellers, or you must refrain from using the Licensed Work.
All copies of the original and modified Licensed Work, and derivative works
of the Licensed Work, are subject to this License. This License applies
separately for each version of the Licensed Work and the Change Date may vary
for each version of the Licensed Work released by Licensor.
You must conspicuously display this License on each original or modified copy
of the Licensed Work. If you receive the Licensed Work in original or
modified form from a third party, the terms and conditions set forth in this
License apply to your use of that work.
Any use of the Licensed Work in violation of this License will automatically
terminate your rights under this License for the current and all other
versions of the Licensed Work.
This License does not grant you any right in any trademark or logo of
Licensor or its affiliates (provided that you may use a trademark or logo of
Licensor as expressly required by this License).
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
TITLE.
MariaDB hereby grants you permission to use this Licenses text to license
your works, and to refer to it using the trademark “Business Source License”,
as long as you comply with the Covenants of Licensor below.
Covenants of Licensor
In consideration of the right to use this Licenses text and the “Business
Source License” name and trademark, Licensor covenants to MariaDB, and to all
other recipients of the licensed work to be provided by Licensor:
1. To specify as the Change License the GPL Version 2.0 or any later version,
or a license that is compatible with GPL Version 2.0 or a later version,
where “compatible” means that software provided under the Change License can
be included in a program with software provided under GPL Version 2.0 or a
later version. Licensor may specify additional Change Licenses without
limitation.
2. To either: (a) specify an additional grant of rights to use that does not
impose any additional restriction on the right granted in this License, as
the Additional Use Grant; or (b) insert the text “None”.
3. To specify a Change Date.
4. Not to modify this License in any other way.
+22
View File
@@ -0,0 +1,22 @@
# Common Library
## Naming Scheme
- ServiceAccount:
- Primary: `$FullName`
- Others: `$FullName-$ServiceAccountName`
- RBAC:
- Primary: `$FullName`
- Others: `$FullName-$RBACName`
- Service:
- Primary: `$FullName`
- Others: `$FullName-$ServiceName`
- Pods:
- Primary: `$FullName`
- Others: `$FullName-$PodName`
- Containers: `$ContainerName`
- ConfigMap: `$FullName-$ConfigMapName`
- Secret: `$FullName-$SecretName`
> Full name -> `$ReleaseName-$ChartName`
> Any name that exceeds 63 characters, will throw an error
@@ -0,0 +1,72 @@
{{/*
Template to render code-server addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "tc.v1.common.addon.codeserver" -}}
{{- $targetSelector := "main" -}}
{{- if $.Values.addons.codeserver.targetSelector -}}
{{- $targetSelector = $.Values.addons.codeserver.targetSelector -}}
{{- end -}}
{{- if .Values.addons.codeserver.enabled -}}
{{/* Append the code-server container to the workloads */}}
{{- $container := include "tc.v1.common.addon.codeserver.container" . | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload $targetSelector -}}
{{- $_ := set $workload.podSpec.containers "codeserver" $container -}}
{{- end -}}
{{- $hasPrimaryService := false -}}
{{- range $svcName, $svcValues := .Values.service -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $ "objectData" $svcValues
"name" $svcName "caller" "Code Server Service"
"key" "addons.codeserver.service")) -}}
{{- if eq $enabled "true" -}}
{{- if $svcValues.primary -}}
{{- $hasPrimaryService = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Add the code-server service */}}
{{- if .Values.addons.codeserver.service.enabled -}}
{{- $serviceValues := .Values.addons.codeserver.service -}}
{{- $_ := set $serviceValues "targetSelector" $targetSelector -}}
{{- if not $hasPrimaryService -}}
{{- $_ := set $serviceValues "primary" true -}}
{{- end -}}
{{- $_ := set .Values.service "codeserver" $serviceValues -}}
{{- end -}}
{{/* Add the code-server ingress */}}
{{- if .Values.addons.codeserver.ingress.enabled -}}
{{- $ingressValues := .Values.addons.codeserver.ingress -}}
{{- if not $ingressValues.targetSelector -}}
{{/* Assumes that both service and port are named codeserver */}}
{{- $_ := set $ingressValues "targetSelector" (dict "codeserver" "codeserver") -}}
{{- end -}}
{{- $hasPrimaryIngress := false -}}
{{- range $ingName, $ingValues := $.Values.ingress -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $ "objectData" $ingValues
"name" $ingName "caller" "Code Server Ingress"
"key" "addons.codeserver.ingress")) -}}
{{- if eq $enabled "true" -}}
{{- if $ingValues.primary -}}
{{- $hasPrimaryIngress = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $hasPrimaryIngress -}}
{{- $_ := set $ingressValues "primary" true -}}
{{- end -}}
{{/* Let spawner handle the rest */}}
{{- $_ := set $.Values.ingress "codeserver" $ingressValues -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,48 @@
{{/*
The code-server sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.codeserver.container" -}}
enabled: true
probes:
liveness:
enabled: true
port: {{ .Values.addons.codeserver.service.ports.codeserver.port }}
path: "/"
readiness:
enabled: true
port: {{ .Values.addons.codeserver.service.ports.codeserver.port }}
path: "/"
startup:
enabled: true
port: {{ .Values.addons.codeserver.service.ports.codeserver.port }}
path: "/"
imageSelector: "codeserverImage"
imagePullPolicy: {{ .Values.codeserverImage.pullPolicy }}
resources:
excludeExtra: true
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
env:
{{- range $envList := .Values.addons.codeserver.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else }}
{{- fail "Please specify name/value for codeserver environment variable" -}}
{{- end -}}
{{- end -}}
{{- with .Values.addons.codeserver.env -}}
{{- range $k, $v := . }}
{{ $k }}: {{ $v | quote }}
{{- end -}}
{{- end }}
args:
{{- range .Values.addons.codeserver.args }}
- {{ . | quote }}
{{- end }}
- "--port"
- "{{ .Values.addons.codeserver.service.ports.codeserver.port }}"
- {{ .Values.addons.codeserver.workingDir | default "/" }}
{{- end -}}
@@ -0,0 +1,46 @@
{{/*
The code-server sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.netshoot.container" -}}
enabled: true
command:
- /bin/sh
- -c
- sleep infinity
probes:
liveness:
enabled: false
readiness:
enabled: false
startup:
enabled: false
imageSelector: "netshootImage"
resources:
excludeExtra: true
securityContext:
runAsUser: 0
runAsGroup: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
env:
{{- range $envList := $.Values.addons.netshoot.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else }}
{{- fail "Please specify name/value for netshoot environment variable" -}}
{{- end -}}
{{- end -}}
{{- with $.Values.addons.netshoot.env -}}
{{- range $k, $v := . }}
{{ $k }}: {{ $v | quote }}
{{- end -}}
{{- end }}
args:
{{- range $.Values.addons.netshoot.args }}
- {{ . | quote }}
{{- end }}
{{- end -}}
@@ -0,0 +1,15 @@
{{/*
Template to render code-server addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "tc.v1.common.addon.netshoot" -}}
{{- $targetSelector := "main" -}}
{{- if .Values.addons.netshoot.enabled -}}
{{/* Append the code-server container to the workloads */}}
{{- $container := include "tc.v1.common.addon.netshoot.container" . | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload $targetSelector -}}
{{- $_ := set $workload.podSpec.containers "netshoot" $container -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,16 @@
{{/*
The VPN config and scripts to be included.
*/}}
{{- define "tc.v1.common.addon.vpn.configmap" -}}
enabled: true
data:
{{- with .Values.addons.vpn.scripts.up }}
up.sh: |-
{{- . | nindent 4 }}
{{- end -}}
{{- with .Values.addons.vpn.scripts.down }}
down.sh: |-
{{- . | nindent 4 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,73 @@
{{/*
The gluetun sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.vpn.gluetun.container" -}}
enabled: true
imageSelector: gluetunImage
probes:
{{- if $.Values.addons.vpn.livenessProbe }}
liveness:
{{- toYaml . | nindent 2 }}
{{- else }}
liveness:
enabled: false
{{- end }}
readiness:
enabled: false
startup:
enabled: false
resources:
excludeExtra: true
securityContext:
runAsUser: 0
runAsNonRoot: false
readOnlyRootFilesystem: false
runAsGroup: 568
capabilities:
add:
- NET_ADMIN
- NET_RAW
- MKNOD
env:
DNS_KEEP_NAMESERVER: "on"
DOT: "off"
{{- if $.Values.addons.vpn.killSwitch }}
{{- $excludednetworks := (printf "%v,%v" $.Values.chartContext.podCIDR $.Values.chartContext.svcCIDR) -}}
{{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}}
{{- $excludednetworks = (printf "%v,%v" $excludednetworks .) -}}
{{- end }}
{{- range $.Values.addons.vpn.excludedNetworks_IPv6 -}}
{{- $excludednetworksv6 = (printf "%v,%v" $excludednetworks .) -}}
{{- end }}
FIREWALL: "on"
FIREWALL_OUTBOUND_SUBNETS: {{ $excludednetworks | quote }}
{{- $inputPorts := list -}}
{{- if and
$.Values.service $.Values.service.main $.Values.service.main.ports
$.Values.service.main.ports.main $.Values.service.main.ports.main.port -}}
{{- $inputPorts = list $.Values.service.main.ports.main.port -}}
{{- end -}}
{{- $inputPorts = concat $inputPorts $.Values.addons.vpn.inputPorts | mustUniq }}
FIREWALL_INPUT_PORTS: {{ join "," $inputPorts }}
{{- else }}
FIREWALL: "off"
{{- end }}
{{- with $.Values.addons.vpn.env }}
{{- . | toYaml | nindent 2 }}
{{- end -}}
{{- range $envList := $.Values.addons.vpn.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else -}}
{{- fail "Please specify name/value for VPN environment variable" -}}
{{- end -}}
{{- end -}}
{{- with $.Values.addons.vpn.args }}
args:
{{- . | toYaml | nindent 2 }}
{{- end }}
{{- end -}}
@@ -0,0 +1,75 @@
{{/*
The gluetun sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.vpn.openvpn.container" -}}
enabled: true
imageSelector: openvpnImage
probes:
{{- if $.Values.addons.vpn.livenessProbe }}
liveness:
{{- toYaml . | nindent 2 }}
{{- else }}
liveness:
enabled: false
{{- end }}
readiness:
enabled: false
startup:
enabled: false
resources:
excludeExtra: true
securityContext:
runAsUser: 0
runAsGroup: 0
capabilities:
add:
- NET_ADMIN
- NET_RAW
- MKNOD
- SYS_MODULE
env:
{{- with $.Values.addons.vpn.env }}
{{- . | toYaml | nindent 2 }}
{{- end }}
{{- if and $.Values.addons.vpn.openvpn.username $.Values.addons.vpn.openvpn.password }}
VPN_AUTH: {{ (printf "%v;%v" $.Values.addons.vpn.openvpn.username $.Values.addons.vpn.openvpn.password) }}
{{- end -}}
{{- if $.Values.addons.vpn.killSwitch }}
{{- $ipv4list := $.Values.addons.vpn.excludedNetworks_IPv4 }}
{{- if $.Values.chartContext.podCIDR }}
{{- $ipv4list = append $ipv4list $.Values.chartContext.podCIDR }}
{{- end }}
{{- if $.Values.chartContext.svcCIDR }}
{{- $ipv4list = append $ipv4list $.Values.chartContext.svcCIDR }}
{{- end }}
FIREWALL: "ON"
{{- range $index, $value := $ipv4list }}
ROUTE_{{ add $index 1 }}: {{ $value | quote }}
{{- end }}
{{- if $.Values.addons.vpn.excludedNetworks_IPv6 }}
{{- $excludednetworksv6 := "" -}}
{{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}}
{{- $excludednetworksv6 = ( printf "%v;%v" $excludednetworksv6 . ) -}}
{{- end }}
{{- range $index, $value := $.Values.addons.vpn.excludedNetworks_IPv6 }}
ROUTE6_{{ add $index 1 }}: {{ $value | quote }}
{{- end }}
{{- end }}
{{- end -}}
{{- range $envList := $.Values.addons.vpn.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else -}}
{{- fail "Please specify name/value for VPN environment variable" -}}
{{- end -}}
{{- end -}}
{{- with $.Values.addons.vpn.args }}
args:
{{- . | toYaml | nindent 2 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,9 @@
{{/*
The OpenVPN config secret to be included.
*/}}
{{- define "tc.v1.common.addon.vpn.secret" -}}
enabled: true
data:
vpn.conf: |-
{{- .Values.addons.vpn.config | nindent 4 }}
{{- end -}}
@@ -0,0 +1,89 @@
{{/*
The Tailscale sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.vpn.tailscale.container" -}}
enabled: true
imageSelector: "tailscaleImage"
probes:
{{- if $.Values.addons.vpn.livenessProbe }}
liveness:
{{- toYaml . | nindent 2 }}
{{- else }}
liveness:
enabled: false
{{- end }}
readiness:
enabled: false
startup:
enabled: false
command:
- /usr/local/bin/containerboot
resources:
excludeExtra: true
securityContext:
{{- if $.Values.addons.vpn.tailscale.userspace }}
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: false
readOnlyRootFilesystem: true
{{- else }}
runAsUser: 0
runAsGroup: 0
runAsNonRoot: true
readOnlyRootFilesystem: false
{{- end }}
capabilities:
add:
- NET_ADMIN
- NET_RAW
{{/*
Set KUBE_SECRET to empty string to force tailscale
to use the filesystem for state tracking.
With secret for state tracking you can't always
know if the app that uses this sidecard will
use a custom ServiceAccount and will lead to falure.
*/}}
env:
TS_KUBE_SECRET: ""
TS_SOCKET: /var/run/tailscale/tailscaled.sock
TS_STATE_DIR: /var/lib/tailscale/state
TS_AUTH_ONCE: {{ $.Values.addons.vpn.tailscale.auth_once | quote }}
TS_USERSPACE: {{ $.Values.addons.vpn.tailscale.userspace | quote }}
TS_ACCEPT_DNS: {{ $.Values.addons.vpn.tailscale.accept_dns | quote }}
{{- with $.Values.addons.vpn.tailscale.outbound_http_proxy_listen }}
TS_OUTBOUND_HTTP_PROXY_LISTEN: {{ . }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.routes }}
TS_ROUTES: {{ . }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.dest_ip }}
TS_DEST_IP: {{ . }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.sock5_server }}
TS_SOCKS5_SERVER: {{ . }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.extra_args }}
TS_EXTRA_ARGS: {{ . | quote }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.daemon_extra_args }}
TS_TAILSCALED_EXTRA_ARGS: {{ . | quote }}
{{- end -}}
{{- with $.Values.addons.vpn.tailscale.authkey }}
TS_AUTH_KEY: {{ . }}
{{- end }}
{{- range $envList := $.Values.addons.vpn.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else -}}
{{- fail "Please specify name/value for VPN environment variable" -}}
{{- end -}}
{{- end -}}
{{- with $.Values.addons.vpn.env -}}
{{- range $k, $v := . }}
{{ $k }}: {{ $v | quote }}
{{- end -}}
{{- end }}
{{- end -}}
@@ -0,0 +1,112 @@
{{/*
The volume (referencing VPN scripts) to be inserted into persistence.
*/}}
{{- define "tc.v1.common.addon.vpn.volume.scripts" -}}
{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }}
enabled: true
type: configmap
objectName: vpnscripts
expandObjectName: false
defaultMode: "0777"
items:
{{- if .Values.addons.vpn.scripts.up }}
- key: up.sh
path: up.sh
{{- end -}}
{{- if .Values.addons.vpn.scripts.down }}
- key: down.sh
path: down.sh
{{- end }}
targetSelector:
{{- range .Values.addons.vpn.targetSelector }}
{{ . }}:
vpn:
mountPath: {{ $basePath }}
{{- end -}}
{{- end -}}
{{/*
The volume (referencing VPN config) to be inserted into persistence.
*/}}
{{- define "tc.v1.common.addon.vpn.volume.config" -}}
{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }}
{{- $mountPath := $basePath }}
enabled: true
{{- if or .Values.addons.vpn.config .Values.addons.vpn.existingSecret }}
type: secret
defaultMode: "0777"
items:
- key: vpn.conf
path: vpn.conf
{{- if .Values.addons.vpn.existingSecret }}
objectName: {{ .Values.addons.vpn.existingSecret }}
expandObjectName: false
{{- else }}
objectName: vpnconfig
expandObjectName: true
{{- end -}}
{{- else }}
{{- $mountPath = (printf "%s/vpn.conf" $basePath) }}
type: hostPath
hostPath: {{ .Values.addons.vpn.configFile | default "/vpn" }}
hostPathType: "File"
autoPermissions:
enabled: true
chown: true
user: 568
group: 568
{{- end }}
targetSelector:
{{- range .Values.addons.vpn.targetSelector }}
{{ . }}:
vpn:
mountPath: {{ $mountPath }}
{{- end -}}
{{- end -}}
{{/*
The volume (referencing VPN config folder) to be inserted into persistence.
*/}}
{{- define "tc.v1.common.addon.vpn.volume.folder" -}}
{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }}
enabled: true
type: hostPath
hostPath: {{ .Values.addons.vpn.configFolder | quote }}
autoPermissions:
enabled: true
chown: true
user: 568
group: 568
targetSelector:
{{- range .Values.addons.vpn.targetSelector }}
{{ . }}:
vpn:
mountPath: {{ $basePath }}
{{- end -}}
{{- end -}}
{{/*
The empty tailscale folder
*/}}
{{- define "tc.v1.common.addon.vpn.volume.tailscale" -}}
enabled: true
type: emptyDir
targetSelector:
{{- range .Values.addons.vpn.targetSelector }}
{{ . }}:
tailscale:
mountPath: /var/lib/tailscale
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.addon.vpn.volume.basePath" -}}
{{- $basePath := "/vpn" -}} {{/* Base Path for OVPN */}}
{{- if eq .Values.addons.vpn.type "wireguard" -}}
{{- $basePath = "/etc/wireguard" -}} {{/* Base Path for Wireguard */}}
{{- else if eq .Values.addons.vpn.type "gluetun" -}}
{{- $basePath = "/gluetun" -}} {{/* Base Path for Gluetun */}}
{{- end -}}
{{- $basePath -}}
{{- end -}}
@@ -0,0 +1,94 @@
{{/*
Template to render VPN addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "tc.v1.common.addon.vpn" -}}
{{- if ne "disabled" .Values.addons.vpn.type -}}
{{- if .Values.addons.vpn.config -}}
{{/* Append the vpn config secret to the secrets */}}
{{- $secret := include "tc.v1.common.addon.vpn.secret" . | fromYaml -}}
{{- if $secret -}}
{{- $_ := set .Values.secret "vpnconfig" $secret -}}
{{- end -}}
{{- end }}
{{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down -}}
{{/* Append the vpn up/down scripts to the configmaps */}}
{{- $configmap := include "tc.v1.common.addon.vpn.configmap" . | fromYaml -}}
{{- if $configmap -}}
{{- $_ := set .Values.configmap "vpnscripts" $configmap -}}
{{- end -}}
{{- end }}
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.config .Values.addons.vpn.existingSecret -}}
{{/* Append the vpn config to the persistence */}}
{{- $configper := include "tc.v1.common.addon.vpn.volume.config" . | fromYaml -}}
{{- if $configper -}}
{{- $_ := set .Values.persistence "vpnconfig" $configper -}}
{{- end -}}
{{- end -}}
{{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down -}}
{{/* Append the vpn scripts to the persistence */}}
{{- $scriptsper := include "tc.v1.common.addon.vpn.volume.scripts" . | fromYaml -}}
{{- if $scriptsper -}}
{{- $_ := set .Values.persistence "vpnscripts" $scriptsper -}}
{{- end -}}
{{- end -}}
{{- if .Values.addons.vpn.configFolder -}}
{{/* Append the vpn folder to the persistence */}}
{{- $folderper := include "tc.v1.common.addon.vpn.volume.folder" . | fromYaml -}}
{{- if $folderper -}}
{{- $_ := set .Values.persistence "vpnfolder" $folderper -}}
{{- end -}}
{{- end -}}
{{/* Ensure target Selector defaults to main pod even if unset */}}
{{- $targetSelector := list "main" -}}
{{- if $.Values.addons.codeserver.targetSelector -}}
{{- $targetSelector = $.Values.addons.codeserver.targetSelector -}}
{{- end -}}
{{/* Append the vpn container to the containers */}}
{{- range $targetSelector -}}
{{- if eq "gluetun" $.Values.addons.vpn.type -}}
{{- $container := include "tc.v1.common.addon.vpn.gluetun.container" $ | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload . -}}
{{- $_ := set $workload.podSpec.containers "vpn" $container -}}
{{- end -}}
{{- else if eq "tailscale" $.Values.addons.vpn.type -}}
{{/* FIXME: https://github.com/tailscale/tailscale/issues/8188 */}}
{{- $_ := set $.Values.podOptions "automountServiceAccountToken" true -}}
{{- $container := include "tc.v1.common.addon.vpn.tailscale.container" $ | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload . -}}
{{- $_ := set $workload.podSpec.containers "tailscale" $container -}}
{{- end -}}
{{- else if eq "openvpn" $.Values.addons.vpn.type -}}
{{- $container := include "tc.v1.common.addon.vpn.openvpn.container" $ | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload . -}}
{{- $_ := set $workload.podSpec.containers "vpn" $container -}}
{{- end -}}
{{- else if eq "wireguard" $.Values.addons.vpn.type -}}
{{- $container := include "tc.v1.common.addon.vpn.wireguard.container" $ | fromYaml -}}
{{- if $container -}}
{{- $workload := get $.Values.workload . -}}
{{- $_ := set $workload.podSpec.containers "vpn" $container -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq "tailscale" $.Values.addons.vpn.type -}}
{{/* Append the empty tailscale folder to the persistence */}}
{{- $tailscaledir := include "tc.v1.common.addon.vpn.volume.tailscale" . | fromYaml -}}
{{- if $tailscaledir -}}
{{- $_ := set .Values.persistence "tailscalestate" $tailscaledir -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,68 @@
{{/*
The gluetun sidecar container to be inserted.
*/}}
{{- define "tc.v1.common.addon.vpn.wireguard.container" -}}
enabled: true
imageSelector: wireguardImage
probes:
{{- if $.Values.addons.vpn.livenessProbe }}
liveness:
{{- toYaml . | nindent 2 }}
{{- else }}
liveness:
enabled: false
{{- end }}
readiness:
enabled: false
startup:
enabled: false
resources:
excludeExtra: true
securityContext:
runAsUser: 568
runAsGroup: 568
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
capabilities:
add:
- AUDIT_WRITE
- NET_ADMIN
- SETUID
- SETGID
- SYS_MODULE
env:
{{- with $.Values.addons.vpn.env }}
{{- . | toYaml | nindent 2 }}
{{- end }}
SEPARATOR: ";"
IPTABLES_BACKEND: "nft"
{{- if $.Values.addons.vpn.killSwitch }}
KILLSWITCH: "true"
{{- $excludednetworksv4 := ( printf "%v;%v" $.Values.chartContext.podCIDR $.Values.chartContext.svcCIDR ) -}}
{{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}}
{{- $excludednetworksv4 = ( printf "%v;%v" $excludednetworksv4 . ) -}}
{{- end }}
KILLSWITCH_EXCLUDEDNETWORKS_IPV4: {{ $excludednetworksv4 | quote }}
{{- if $.Values.addons.vpn.excludedNetworks_IPv6 -}}
{{- $excludednetworksv6 := "" -}}
{{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}}
{{- $excludednetworksv6 = ( printf "%v;%v" $excludednetworksv6 . ) -}}
{{- end }}
KILLSWITCH_EXCLUDEDNETWORKS_IPV6: {{ $.Values.addons.vpn.excludedNetworks_IPv6 | quote }}
{{- end -}}
{{- end -}}
{{- range $envList := $.Values.addons.vpn.envList -}}
{{- if and $envList.name $envList.value }}
{{ $envList.name }}: {{ $envList.value | quote }}
{{- else -}}
{{- fail "Please specify name/value for VPN environment variable" -}}
{{- end -}}
{{- end -}}
{{- with $.Values.addons.vpn.args }}
args:
{{- . | toYaml | nindent 2 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,37 @@
{{/* Configmap Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.configmap" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the configmap.
labels: The labels of the configmap.
annotations: The annotations of the configmap.
data: The data of the configmap.
namespace: The namespace of the configmap. (Optional)
*/}}
{{- define "tc.v1.common.class.configmap" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Configmap") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
data:
{{- tpl (toYaml $objectData.data) $rootCtx | nindent 2 }}
{{/* This comment is here to add a new line */}}
{{- end -}}
@@ -0,0 +1,51 @@
{{/* CronJob Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.cronjob" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the CronJob.
*/}}
{{- define "tc.v1.common.class.cronjob" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- include "tc.v1.common.lib.workload.cronjobValidation" (dict "objectData" $objectData) }}
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CronJob") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.cronjobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }}
template:
metadata:
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 12 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict)
(include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 12 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 10 }}
{{- end -}}
@@ -0,0 +1,54 @@
{{/* DaemonSet Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the DaemonSet.
*/}}
{{- define "tc.v1.common.class.daemonset" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- include "tc.v1.common.lib.workload.daemonsetValidation" (dict "objectData" $objectData) }}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "DaemonSet") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.daemonsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }}
selector:
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }}
template:
metadata:
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 8 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict)
(include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 8 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
{{- end -}}
@@ -0,0 +1,54 @@
{{/* Deployment Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the Deployment.
*/}}
{{- define "tc.v1.common.class.deployment" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- include "tc.v1.common.lib.workload.deploymentValidation" (dict "objectData" $objectData) }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Deployment") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.deploymentSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }}
selector:
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }}
template:
metadata:
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 8 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict)
(include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 8 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
{{- end -}}
@@ -0,0 +1,33 @@
{{/* Endpoint Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.endpoint" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The service data, that will be used to render the Service object.
*/}}
{{- define "tc.v1.common.class.endpoint" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: v1
kind: Endpoints
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Endpoint") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
subsets:
- addresses:
{{- include "tc.v1.common.lib.endpoint.addresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
ports:
{{- include "tc.v1.common.lib.endpoint.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
{{- end -}}
@@ -0,0 +1,45 @@
{{/* EndpointSlice Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.endpointSlice" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The service data, that will be used to render the Service object.
*/}}
{{- define "tc.v1.common.class.endpointSlice" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $addressType := $objectData.addressType | default "IPv4" -}}
{{- if $objectData.addressType -}}
{{- $addressType = tpl $addressType $rootCtx -}}
{{- $validTypes := (list "IPv4" "IPv6" "FQDN") -}}
{{- if not (mustHas $addressType $validTypes) -}}
{{- fail (printf "EndpointSlice - Expected [addressType] to be one of [%s], but got [%s]" (join ", " $validTypes) $addressType) -}}
{{- end -}}
{{- end }}
---
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Endpoint Slice") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- $_ := set $labels "kubernetes.io/service-name" $objectData.name -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
addressType: {{ $addressType }}
ports:
{{- include "tc.v1.common.lib.endpointslice.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
endpoints:
{{- include "tc.v1.common.lib.endpointslice.endpoints" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- end -}}
@@ -0,0 +1,58 @@
{{/*
This template serves as a blueprint for horizontal pod autoscaler objects that are created
using the common library.
*/}}
{{- define "tc.v1.common.class.hpa" -}}
{{- $targetName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $hpaName := $fullName -}}
{{- $values := .Values.hpa -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.hpa -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $hpaLabels := $values.labels -}}
{{- $hpaAnnotations := $values.annotations -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $hpaName = printf "%v-%v" $hpaName $values.nameOverride -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.hpa.apiVersion" $ }}
kind: HorizontalPodAutoscaler
metadata:
name: {{ $hpaName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($hpaLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($hpaAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end -}}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: {{ $values.targetKind | default ( include "tc.v1.common.names.controllerType" . ) }}
name: {{ $values.target | default $targetName }}
minReplicas: {{ $values.minReplicas | default 1 }}
maxReplicas: {{ $values.maxReplicas | default 3 }}
metrics:
{{- if $values.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ $values.targetCPUUtilizationPercentage }}
{{- end -}}
{{- if $values.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ $values.targetMemoryUtilizationPercentage }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,108 @@
{{/* Ingress Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.ingress" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the Ingress.
*/}}
{{- define "tc.v1.common.class.ingress" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $svcData := (include "tc.v1.common.lib.ingress.targetSelector" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) -}}
{{- $_ := set $objectData "selectedService" $svcData -}}
{{- if not (hasKey $objectData "integrations") -}}
{{- $_ := set $objectData "integrations" dict -}}
{{- end -}}
{{- if not (hasKey $objectData "annotations") -}}
{{- $_ := set $objectData "annotations" dict -}}
{{- end -}}
{{- $ingressClassName := "" -}}
{{- if $objectData.ingressClassName -}}
{{- $ingressClassName = (tpl $objectData.ingressClassName $rootCtx) -}}
{{- end -}}
{{/* When Stop All is set, force ingressClass "stopped"
to yeet ingress from the ingresscontroller */}}
{{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $ingressClassName = "tc-stopped" -}}
{{- end -}}
{{- include "tc.v1.common.lib.ingress.integration.certManager" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.lib.ingress.integration.traefik" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- if ne $ingressClassName "tc-stopped" -}}{{/* If is stopped, dont render homepage annotations */}}
{{- include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- end }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Ingress") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end }}
annotations:
checksum/secrets: {{ toJson $rootCtx.Values.secret | sha256sum }}
checksum/services: {{ toJson $rootCtx.Values.service | sha256sum }}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ $ingressClassName | default nil }}
rules:
{{- range $h := $objectData.hosts }}
- host: {{ (tpl $h.host $rootCtx) | quote }}
http:
paths:
{{- if not $h.paths -}} {{/* If no paths given, default to "/" */}}
{{- $_ := set $h "paths" (list (dict "path" "/")) -}}
{{- end -}}
{{- range $p := $h.paths -}}
{{- $newSvcData := (include "tc.v1.common.lib.ingress.backend.data" (dict
"rootCtx" $rootCtx "svcData" $svcData "override" $p.overrideService)) | fromYaml
}}
- path: {{ tpl ($p.path | default "/") $rootCtx }}
pathType: {{ tpl ($p.pathType | default "Prefix") $rootCtx }}
backend:
service:
name: {{ $newSvcData.name }}
port:
number: {{ $newSvcData.port }}
{{- end -}}
{{- end -}}
{{/* If a certificateIssuer is defined in the whole ingress, use that */}}
{{- if and $objectData.integrations.certManager $objectData.integrations.certManager.enabled }}
tls:
{{- range $idx, $h := $objectData.hosts }}
- secretName: {{ printf "%s-tls-%d" $objectData.name ($idx | int) }}
hosts:
- {{ (tpl $h.host $rootCtx) | quote }}
{{- end -}}
{{/* else if a tls section is defined use the configuration from there */}}
{{- else if $objectData.tls }}
tls:
{{- range $idx, $t := $objectData.tls -}}
{{- $secretName := "" -}}
{{- if $t.secretName -}}
{{- $secretName = tpl $t.secretName $rootCtx -}}
{{- else if $t.certificateIssuer -}}
{{- $secretName = printf "%s-tls-%d" $objectData.name ($idx | int) -}}
{{- else if $t.clusterCertificate -}}
{{- $secretName = printf "certificate-issuer-%s" (tpl $t.clusterCertificate $rootCtx) -}}
{{- end }}
- secretName: {{ $secretName }}
hosts:
{{- range $h := $t.hosts }}
- {{ (tpl $h $rootCtx) | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,51 @@
{{/* Job Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.job" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the Job.
*/}}
{{- define "tc.v1.common.class.job" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- include "tc.v1.common.lib.workload.jobValidation" (dict "objectData" $objectData) }}
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Job") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.jobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }}
template:
metadata:
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 8 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict)
(include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 8 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
{{- end -}}
@@ -0,0 +1,38 @@
{{/* MutatingWebhookConfiguration Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.mutatingWebhookConfiguration" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the MutatingWebhookConfiguration.
labels: The labels of the MutatingWebhookConfiguration.
annotations: The annotations of the MutatingWebhookConfiguration.
data: The data of the MutatingWebhookConfiguration.
namespace: The namespace of the MutatingWebhookConfiguration. (Optional)
*/}}
{{- define "tc.v1.common.class.mutatingWebhookConfiguration" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Webhook") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
webhooks:
{{- range $webhook := $objectData.webhooks -}}
{{- include "tc.v1.common.lib.webhook" (dict "webhook" $webhook "rootCtx" $rootCtx) | trim | nindent 4 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,35 @@
{{/* Network Attachment Definition Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.networkAttachmentDefinition" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the Network Attachment Definition.
labels: The labels of the Network Attachment Definition.
annotations: The annotations of the Network Attachment Definition.
config: The config of the interface
*/}}
{{- define "tc.v1.common.class.networkAttachmentDefinition" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Network Attachment Definition") }}
{{- $labels := (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) | default dict -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) | default dict -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
config: {{ $objectData.config | squote }}
{{- end -}}
@@ -0,0 +1,185 @@
{{/*
Blueprint for the NetworkPolicy object
*/}}
{{- define "tc.v1.common.class.networkpolicy" -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $networkPolicyName := $fullName -}}
{{- $values := .Values.networkPolicy -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.networkPolicy -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $networkpolicyLabels := $values.labels -}}
{{- $networkpolicyAnnotations := $values.annotations -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $networkPolicyName = printf "%v-%v" $networkPolicyName $values.nameOverride -}}
{{- end }}
---
kind: NetworkPolicy
apiVersion: {{ include "tc.v1.common.capabilities.networkpolicy.apiVersion" $ }}
metadata:
name: {{ $networkPolicyName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($networkpolicyLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($networkpolicyAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
podSelector:
{{- if $values.podSelector }}
{{- tpl (toYaml $values.podSelector) $ | nindent 4 }}
{{- else if $values.targetSelector }}
{{- $objectData := dict "targetSelector" $values.targetSelector }}
{{- $selectedPod := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $ "objectData" $objectData)) }}
{{- $selectedPodName := $selectedPod.shortName }}
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "pod" "objectName" $selectedPodName) | indent 8 }}
{{- else }}
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "" "objectName" "") | indent 8 }}
{{- end }}
{{- if $values.policyType }}
{{- if eq $values.policyType "ingress" }}
policyTypes: ["Ingress"]
{{- else if eq $values.policyType "egress" }}
policyTypes: ["Egress"]
{{- else if eq $values.policyType "ingress-egress" }}
policyTypes: ["Ingress", "Egress"]
{{- end -}}
{{- end -}}
{{- if $values.egress }}
egress:
{{- range $values.egress }}
- to:
{{- range .to -}}
{{- $nss := false -}}
{{- $ipb := false -}}
{{- if .ipBlock -}}
{{- if .ipBlock.cidr -}}
{{- $ipb = true }}
- ipBlock:
cidr: {{ .ipBlock.cidr }}
{{- if .ipBlock.except }}
except:
{{- range .ipBlock.except }}
- {{ . }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and ( .namespaceSelector ) ( not $ipb ) -}}
{{- if or ( .namespaceSelector.matchLabels ) ( .namespaceSelector.matchExpressions ) -}}
{{- $nss = true }}
- namespaceSelector:
{{- if .namespaceSelector.matchLabels }}
matchLabels:
{{- .namespaceSelector.matchLabels | toYaml | nindent 12 }}
{{- end -}}
{{- if .namespaceSelector.matchExpressions }}
matchExpressions:
{{- .namespaceSelector.matchExpressions | toYaml | nindent 12 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and ( .podSelector ) ( not $ipb ) -}}
{{- if or ( .podSelector.matchLabels ) ( .podSelector.matchExpressions ) -}}
{{- if $nss }}
podSelector:
{{- else }}
- podSelector:
{{- end -}}
{{- if .podSelector.matchLabels }}
matchLabels:
{{- .podSelector.matchLabels | toYaml | nindent 12 }}
{{- end -}}
{{- if .podSelector.matchExpressions }}
matchExpressions:
{{- .podSelector.matchExpressions | toYaml | nindent 12 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- with .ports }}
ports:
{{- . | toYaml | nindent 6 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $values.ingress }}
ingress:
{{- range $values.ingress }}
- from:
{{- range .from -}}
{{- $nss := false -}}
{{- $ipb := false -}}
{{- if .ipBlock -}}
{{- if .ipBlock.cidr -}}
{{- $ipb = true }}
- ipBlock:
cidr: {{ .ipBlock.cidr }}
{{- if .ipBlock.except }}
except:
{{- range .ipBlock.except }}
- {{ . }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and ( .namespaceSelector ) ( not $ipb ) -}}
{{- if or ( .namespaceSelector.matchLabels ) ( .namespaceSelector.matchExpressions ) -}}
{{- $nss = true }}
- namespaceSelector:
{{- if .namespaceSelector.matchLabels }}
matchLabels:
{{- .namespaceSelector.matchLabels | toYaml | nindent 12 }}
{{- end -}}
{{- if .namespaceSelector.matchExpressions }}
matchExpressions:
{{- .namespaceSelector.matchExpressions | toYaml | nindent 12 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and ( .podSelector ) ( not $ipb ) -}}
{{- if or ( .podSelector.matchLabels ) ( .podSelector.matchExpressions ) -}}
{{- if $nss }}
podSelector:
{{- else }}
- podSelector:
{{- end }}
{{- if .podSelector.matchLabels }}
matchLabels:
{{- .podSelector.matchLabels | toYaml | nindent 12 }}
{{- end -}}
{{- if .podSelector.matchExpressions }}
matchExpressions:
{{- .podSelector.matchExpressions | toYaml | nindent 12 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- with .ports }}
ports:
{{- . | toYaml | nindent 6 }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,75 @@
{{/* PersistentVolume Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.pv" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the PV.
labels: The labels of the PV.
annotations: The annotations of the PV.
provisioner: The provisioner to use for the PersistentVolume.
driver: The driver to use for the csi
retain: Whether to retain the PV after deletion. (Default: false)
size: The size of the PersistentVolume. (Default: 1Gi)
*/}}
{{- define "tc.v1.common.class.pv" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $retain := $rootCtx.Values.global.fallbackDefaults.pvcRetain -}}
{{- if not (kindIs "invalid" $objectData.retain) -}}
{{- $retain = $objectData.retain -}}
{{- end -}}
{{- $reclaimPolicy := ternary "Retain" "Delete" $retain -}}
{{- $pvcSize := $rootCtx.Values.global.fallbackDefaults.pvcSize -}}
{{- with $objectData.size -}}
{{- $pvcSize = tpl . $rootCtx -}}
{{- end }}
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ $objectData.name }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- if $retain -}}
{{- $_ := set $annotations "\"helm.sh/resource-policy\"" "keep" -}}
{{- end -}}
{{- $_ := set $annotations "pv.kubernetes.io/provisioned-by" $objectData.provisioner -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
capacity:
storage: {{ $pvcSize }}
persistentVolumeReclaimPolicy: {{ $reclaimPolicy }}
storageClassName: {{ $objectData.name }}
accessModes:
{{- include "tc.v1.common.lib.pvc.accessModes" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Persistent Volume") | trim | nindent 4 -}}
{{- if $objectData.mountOptions }}
mountOptions:
{{- range $opt := $objectData.mountOptions -}}
{{- if $opt.value }}
- {{ printf "%s=%s" (tpl $opt.key $rootCtx) (tpl (include "tc.v1.common.helper.makeIntOrNoop" $opt.value) $rootCtx) }}
{{- else }}
- {{ tpl $opt.key $rootCtx }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $objectData.static -}}
{{- if eq "smb" $objectData.static.mode -}}
{{- include "tc.v1.common.lib.storage.smbCSI" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- else if eq "nfs" $objectData.static.mode -}}
{{- include "tc.v1.common.lib.storage.nfsCSI" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,54 @@
{{/* poddisruptionbudget Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.podDisruptionBudget" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the podDisruptionBudget.
labels: The labels of the podDisruptionBudget.
annotations: The annotations of the podDisruptionBudget.
data: The data of the podDisruptionBudget.
namespace: The namespace of the podDisruptionBudget. (Optional)
*/}}
{{- define "tc.v1.common.class.podDisruptionBudget" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Pod Disruption Budget") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- if $objectData.customLabels -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $objectData.customLabels) | trim) }}
{{- . | nindent 6 }}
{{- end -}}
{{- else -}}
{{- $selectedPod := fromJson (include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Pod Disruption Budget")) }}
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $selectedPod.shortName) | nindent 6 }}
{{- end -}}
{{- if hasKey $objectData "minAvailable" }}
minAvailable: {{ tpl (toString $objectData.minAvailable) $rootCtx }}
{{- end -}}
{{- if hasKey $objectData "maxUnavailable" }}
maxUnavailable: {{ tpl (toString $objectData.maxUnavailable) $rootCtx }}
{{- end -}}
{{- with $objectData.unhealthyPodEvictionPolicy }}
unhealthyPodEvictionPolicy: {{ tpl . $rootCtx }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,40 @@
{{/* priorityclass Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.priorityclass" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the priorityclass.
labels: The labels of the priorityclass.
annotations: The annotations of the priorityclass.
*/}}
{{- define "tc.v1.common.class.priorityclass" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $globalDefault := false -}}
{{- if not (kindIs "invalid" $objectData.globalDefault) -}}
{{- $globalDefault = $objectData.globalDefault -}}
{{- end }}
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Priority Class") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
value: {{ $objectData.value | default 1000000 }}
preemptionPolicy: {{ $objectData.preemptionPolicy | default "PreemptLowerPriority" }}
globalDefault: {{ $globalDefault }}
description: {{ $objectData.description | default "No description given" }}
{{- end -}}
@@ -0,0 +1,51 @@
{{/* PersistentVolumeClaim Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.pvc" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the PVC.
labels: The labels of the PVC.
annotations: The annotations of the PVC.
size: The size of the PVC. (Default: 1Gi)
volumeName: The name of the volume to bind to. (Default: "")
retain: Whether to retain the PVC after deletion. (Default: false)
storageClass: The storage class to use. (Absent)
*/}}
{{- define "tc.v1.common.class.pvc" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $pvcRetain := $rootCtx.Values.global.fallbackDefaults.pvcRetain -}}
{{- if (kindIs "bool" $objectData.retain) -}}
{{- $pvcRetain = $objectData.retain -}}
{{- end -}}
{{- $pvcSize := $rootCtx.Values.global.fallbackDefaults.pvcSize -}}
{{- with $objectData.size -}}
{{- $pvcSize = tpl . $rootCtx -}}
{{- end }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Persistent Volume Claim") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- if $pvcRetain -}}
{{- $_ := set $annotations "\"helm.sh/resource-policy\"" "keep" -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- end -}}
@@ -0,0 +1,64 @@
{{/* RBAC Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.rbac" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the rbac.
labels: The labels of the rbac.
annotations: The annotations of the rbac.
clusterWide: Whether the rbac is cluster wide or not.
rules: The rules of the rbac.
subjects: The subjects of the rbac.
*/}}
{{- define "tc.v1.common.class.rbac" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }}
metadata:
name: {{ $objectData.name }}
{{- if not $objectData.clusterWide }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "RBAC") }}
{{- end }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
rules:
{{- include "tc.v1.common.lib.rbac.rules" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{ ternary "ClusterRoleBinding" "RoleBinding" $objectData.clusterWide }}
metadata:
name: {{ $objectData.name }}
{{- if not $objectData.clusterWide }}
namespace: {{ $rootCtx.Release.Namespace }}
{{- end }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }}
name: {{ $objectData.name }}
subjects:
{{- include "tc.v1.common.lib.rbac.serviceAccount" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- include "tc.v1.common.lib.rbac.subjects" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }}
{{- end -}}
@@ -0,0 +1,87 @@
{{/*
This template serves as a blueprint for all Route objects that are created
within the common library.
*/}}
{{- define "tc.v1.common.class.route" -}}
{{- $values := .Values.route -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.route -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $routeLabels := $values.labels -}}
{{- $routeAnnotations := $values.annotations -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $fullName = printf "%v-%v" $fullName $values.nameOverride -}}
{{- end -}}
{{- $routeKind := $values.kind | default "HTTPRoute" -}}
{{/* Get the name of the primary service, if any */}}
{{- $primaryServiceName := (include "tc.v1.common.lib.util.service.primary" (dict "rootCtx" $)) -}}
{{/* Get service values of the primary service, if any */}}
{{- $primaryService := get $.Values.service $primaryServiceName -}}
{{- $defaultServiceName := $fullName -}}
{{- if and (hasKey $primaryService "nameOverride") $primaryService.nameOverride -}}
{{- $defaultServiceName = printf "%v-%v" $defaultServiceName $primaryService.nameOverride -}}
{{- end -}}
{{- $defaultServicePort := get $primaryService.ports (include "tc.v1.common.lib.util.service.ports.primary" (dict "svcValues" $primaryService "rootCtx" $)) }}
---
apiVersion: gateway.networking.k8s.io/v1alpha2
{{- if and (ne $routeKind "GRPCRoute") (ne $routeKind "HTTPRoute") (ne $routeKind "TCPRoute") (ne $routeKind "TLSRoute") (ne $routeKind "UDPRoute") -}}
{{- fail (printf "Not a valid route kind (%s)" $routeKind) -}}
{{- end }}
kind: {{ $routeKind }}
metadata:
name: {{ $fullName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($routeLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($routeAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) }}
annotations:
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
parentRefs:
{{- range $values.parentRefs }}
- group: {{ default "gateway.networking.k8s.io" .group }}
kind: {{ default "Gateway" .kind }}
name: {{ required (printf "parentRef name is required for %v %v" $routeKind $fullName) .name }}
namespace: {{ required (printf "parentRef namespace is required for %v %v" $routeKind $fullName) .namespace }}
{{- if .sectionName }}
sectionName: {{ .sectionName | quote }}
{{- end }}
{{- end }}
{{- if and (ne $routeKind "TCPRoute") (ne $routeKind "UDPRoute") $values.hostnames }}
hostnames:
{{- with $values.hostnames }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
rules:
{{- range $values.rules }}
- backendRefs:
{{- range .backendRefs }}
- group: {{ default "" .group | quote}}
kind: {{ default "Service" .kind }}
name: {{ default $defaultServiceName .name }}
namespace: {{ default $.Release.Namespace .namespace }}
port: {{ default $defaultServicePort.port .port }}
weight: {{ default 1 .weight }}
{{- end }}
{{- if (eq $routeKind "HTTPRoute") }}
{{- with .matches }}
matches:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,58 @@
{{/* Secret Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the secret.
labels: The labels of the secret.
annotations: The annotations of the secret.
type: The type of the secret.
data: The data of the secret.
namespace: The namespace of the secret. (Optional)
*/}}
{{- define "tc.v1.common.class.secret" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $secretType := "Opaque" -}}
{{- if eq $objectData.type "certificate" -}}
{{- $secretType = "kubernetes.io/tls" -}}
{{- else if eq $objectData.type "imagePullSecret" -}}
{{- $secretType = "kubernetes.io/dockerconfigjson" -}}
{{- else if $objectData.type -}}
{{- $secretType = $objectData.type -}}
{{- end }}
---
apiVersion: v1
kind: Secret
type: {{ $secretType }}
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Secret") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end -}}
{{- if (mustHas $objectData.type (list "certificate" "imagePullSecret")) }}
data:
{{- if eq $objectData.type "certificate" }}
tls.crt: {{ $objectData.data.certificate | trim | b64enc }}
tls.key: {{ $objectData.data.privatekey | trim | b64enc }}
{{- else if eq $objectData.type "imagePullSecret" }}
.dockerconfigjson: {{ $objectData.data | trim | b64enc }}
{{- end -}}
{{- else }}
stringData:
{{- tpl (toYaml $objectData.data) $rootCtx | nindent 2 }}
{{/* This comment is here to add a new line */}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,119 @@
{{/* Service Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.service" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The service data, that will be used to render the Service object.
*/}}
{{- define "tc.v1.common.class.service" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $svcType := $objectData.type | default $rootCtx.Values.global.fallbackDefaults.serviceType -}}
{{/* Init variables */}}
{{- $hasHTTPSPort := false -}}
{{- $hasHostPort := false -}}
{{- $hostNetwork := false -}}
{{- $podValues := dict -}}
{{- range $portName, $port := $objectData.ports -}}
{{- if $port.enabled -}}
{{- if eq (tpl ($port.protocol | default "") $rootCtx) "https" -}}
{{- $hasHTTPSPort = true -}}
{{- end -}}
{{- if and (hasKey $port "hostPort") $port.hostPort -}}
{{- $hasHostPort = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $specialTypes := (list "ExternalName" "ExternalIP") -}}
{{/* External Name / External IP does not rely on any pod values */}}
{{- if not (mustHas $svcType $specialTypes) -}}
{{/* Get Pod Values based on the selector (or the absence of it) */}}
{{- $podValues = fromJson (include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service")) -}}
{{- if $podValues -}}
{{/* Get Pod hostNetwork configuration */}}
{{- $hostNetwork = include "tc.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $podValues) -}}
{{/* When hostNetwork is set on the pod, force ClusterIP, so services wont try to bind the same ports on the host */}}
{{- if or (and (kindIs "bool" $hostNetwork) $hostNetwork) (and (kindIs "string" $hostNetwork) (eq $hostNetwork "true")) -}}
{{- $svcType = "ClusterIP" -}}
{{- end -}}
{{- end -}}
{{/* When hostPort is defined, force ClusterIP aswell */}}
{{- if $hasHostPort -}}
{{- $svcType = "ClusterIP" -}}
{{- end -}}
{{- end -}}
{{/* When Stop All is set, force ClusterIP as well */}}
{{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $svcType = "ClusterIP" -}}
{{- end -}}
{{- $_ := set $objectData "type" $svcType }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "service" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- if eq $objectData.type "LoadBalancer" -}}
{{- include "tc.v1.common.lib.service.metalLBAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData "annotations" $annotations) -}}
{{- end -}}
{{- if $hasHTTPSPort -}}
{{- include "tc.v1.common.lib.service.traefikAnnotations" (dict "rootCtx" $rootCtx "annotations" $annotations) -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- if eq $objectData.type "ClusterIP" -}}
{{- include "tc.v1.common.lib.service.spec.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- else if eq $objectData.type "LoadBalancer" -}}
{{- include "tc.v1.common.lib.service.spec.loadBalancer" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- else if eq $objectData.type "NodePort" -}}
{{- include "tc.v1.common.lib.service.spec.nodePort" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- else if eq $objectData.type "ExternalName" -}}
{{- include "tc.v1.common.lib.service.spec.externalName" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- else if eq $objectData.type "ExternalIP" -}}
{{- include "tc.v1.common.lib.service.spec.externalIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.service.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
ports:
{{- . | nindent 4 }}
{{- end -}}
{{- if not (mustHas $objectData.type $specialTypes) }}
selector:
{{- if $objectData.selectorLabels }}
{{- tpl (toYaml $objectData.selectorLabels) $rootCtx | nindent 4 }}
{{- else }}
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $podValues.shortName) | trim | nindent 4 -}}
{{- end }}
{{- end -}}
{{- if eq $objectData.type "ExternalIP" -}}
{{- $useSlice := true -}}
{{- if kindIs "bool" $objectData.useSlice -}}
{{- $useSlice = $objectData.useSlice -}}
{{- end -}}
{{- if $useSlice -}}
{{- include "tc.v1.common.class.endpointSlice" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }}
{{- else -}}
{{- include "tc.v1.common.class.endpoint" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,34 @@
{{/* Service Account Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the serviceAccount.
labels: The labels of the serviceAccount.
annotations: The annotations of the serviceAccount.
autoMountToken: Whether to mount the ServiceAccount token or not.
*/}}
{{- define "tc.v1.common.class.serviceAccount" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service Account") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ $objectData.automountServiceAccountToken | default false }}
{{- end -}}
@@ -0,0 +1,58 @@
{{/* StatefulSet Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the StatefulSet.
*/}}
{{- define "tc.v1.common.class.statefulset" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- include "tc.v1.common.lib.workload.statefulsetValidation" (dict "objectData" $objectData) }}
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "StatefulSet") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.statefulsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }}
selector:
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }}
template:
metadata:
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 8 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict)
(include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)
(include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 8 }}
{{- end }}
spec:
{{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }}
{{- with (include "tc.v1.common.lib.storage.volumeClaimTemplates" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
volumeClaimTemplates:
{{- . | nindent 4 }}
{{- end }}
{{- end -}}
@@ -0,0 +1,59 @@
{{/* Configmap Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.storageclass" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the storageclass.
labels: The labels of the storageclass.
annotations: The annotations of the storageclass.
*/}}
{{- define "tc.v1.common.class.storageclass" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $isDefaultClass := false -}}
{{- if (hasKey $objectData "isDefault") -}}
{{- $isDefaultClass = $objectData.isDefault -}}
{{- end -}}
{{- $allowVolExpand := true -}}
{{- if not (kindIs "invalid" $objectData.allowVolumeExpansion) -}}
{{- $allowVolExpand = $objectData.allowVolumeExpansion -}}
{{- end }}
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: {{ $objectData.name }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- $_ := set $annotations "storageclass.kubernetes.io/is-default-class" ($isDefaultClass | toString) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
provisioner: {{ $objectData.provisioner }}
{{- with $objectData.parameters }}
parameters: {{/* TODO: */}}
{{- range $k, $v := . -}}
{{- $val := tpl $v $rootCtx }}
{{ $k }}: {{ include "tc.v1.common.helper.makeIntOrNoop" $val | quote }}
{{- end -}}
{{- end }}
reclaimPolicy: {{ $objectData.reclaimPolicy | default "Retain" }}
allowVolumeExpansion: {{ $allowVolExpand }}
{{- with $objectData.mountOptions }}
mountOptions:
{{- range $opt := . }}
- {{ tpl $opt $rootCtx }}
{{- end -}}
{{- end }}
volumeBindingMode: {{ $objectData.volumeBindingMode | default "Immediate" }}
{{- end -}}
@@ -0,0 +1,38 @@
{{/* ValidatingWebhookconfiguration Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.validatingWebhookconfiguration" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the validatingWebhookconfiguration.
labels: The labels of the validatingWebhookconfiguration.
annotations: The annotations of the validatingWebhookconfiguration.
data: The data of the validatingWebhookconfiguration.
namespace: The namespace of the validatingWebhookconfiguration. (Optional)
*/}}
{{- define "tc.v1.common.class.validatingWebhookconfiguration" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Webhook") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
webhooks:
{{- range $webhook := $objectData.webhooks -}}
{{- include "tc.v1.common.lib.webhook" (dict "webhook" $webhook "rootCtx" $rootCtx) | trim | nindent 4 }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,46 @@
{{/* volumesnapshot Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.volumesnapshot" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the volumesnapshot.
labels: The labels of the volumesnapshot.
annotations: The annotations of the volumesnapshot.
namespace: The namespace of the volumesnapshot. (Optional)
*/}}
{{- define "tc.v1.common.class.volumesnapshot" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "volumesnapshot") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
{{- with $objectData.volumeSnapshotClassName }}
volumeSnapshotClassName: {{ . }}
{{- end -}}
{{- if $objectData.source }}
source:
{{- with $objectData.source.persistentVolumeClaimName }}
persistentVolumeClaimName: {{ . }}
{{- end -}}
{{- with $objectData.source.volumeSnapshotContentName }}
volumeSnapshotContentName: {{ . }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,45 @@
{{/* volumesnapshotclass Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.volumesnapshotclass" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the volumesnapshotclass.
labels: The labels of the volumesnapshotclass.
annotations: The annotations of the volumesnapshotclass.
*/}}
{{- define "tc.v1.common.class.volumesnapshotclass" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $isDefault := false -}}
{{- if (kindIs "bool" $objectData.isDefault) -}}
{{- $isDefault = $objectData.isDefault -}}
{{- end }}
---
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: {{ $objectData.name }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) }}
annotations:
snapshot.storage.kubernetes.io/is-default-class: {{ $isDefault | quote }}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
driver: {{ tpl $objectData.driver $rootCtx }}
deletionPolicy: {{ $objectData.deletionPolicy | default "Retain" }}
{{- with $objectData.parameters }}
parameters:
{{- range $k, $v := . }}
{{ tpl $k $rootCtx }}: {{ (tpl ($v | toString) $rootCtx) | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,60 @@
{{/* Certificate Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.certificate" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the certificate.
labels: The labels of the certificate.
annotations: The annotations of the certificate.
namespace: The namespace of the certificate. (Optional)
*/}}
{{- define "tc.v1.common.class.certificate" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Cert Manager Certificate") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
secretName: {{ $objectData.name }}
dnsNames:
{{- range $h := $objectData.hosts }}
- {{ (tpl $h $rootCtx) | quote }}
{{- end }}
privateKey:
algorithm: ECDSA
size: 256
rotationPolicy: Always
issuerRef:
name: {{ tpl $objectData.certificateIssuer $rootCtx }}
kind: ClusterIssuer
group: cert-manager.io
{{- if $objectData.certificateSecretTemplate }}
secretTemplate:
{{- $labels := (mustMerge ($objectData.certificateSecretTemplate.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 6 }}
{{- end -}}
{{- $annotations := (mustMerge ($objectData.certificateSecretTemplate.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 6 }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,41 @@
{{- define "tc.v1.common.class.cnpg.backup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $backupName := printf "%v-backup-%v" $objectData.name $objectData.backupName -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $backupName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Backup") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $globalBackupLabels := $objectData.backups.labels | default dict -}}
{{- $backupLabels := $objectData.backupLabels | default dict -}}
{{- $backupLabels = mustMerge $backupLabels $objLabels $globalBackupLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $globalBackupAnnotations := $objectData.backups.annotations | default dict -}}
{{- $backupAnnotations := $objectData.backupAnnotations | default dict -}}
{{- $backupAnnotations = mustMerge $backupAnnotations $objAnnotations $globalBackupAnnotations }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Backup
metadata:
name: {{ $backupName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Backup") }}
labels:
cnpg.io/cluster: {{ $objectData.clusterName }}
{{- $labels := (mustMerge $backupLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge $backupAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
cluster:
name: {{ $objectData.clusterName }}
{{- end -}}
@@ -0,0 +1,250 @@
{{- define "tc.v1.common.class.cnpg.cluster" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectData.clusterName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Cluster") -}}
{{/* Initialize variables */}}
{{- $hibernation := "off" -}}
{{- $instances := 2 -}}
{{- $mode := "standalone" -}}
{{- $enableMonitoring := false -}}
{{- $disableDefaultQueries := false -}}
{{- $customQueries := list -}}
{{- $enableSuperUser := true -}}
{{- $inProgress := false -}}
{{- $reusePVC := true -}}
{{- $preloadLibraries := list -}}
{{- $walSize := $rootCtx.Values.global.fallbackDefaults.vctSize -}}
{{- $size := $rootCtx.Values.global.fallbackDefaults.vctSize -}}
{{- $primaryUpdateStrategy := "unsupervised" -}}
{{- $primaryUpdateMethod := "switchover" -}}
{{- $logLevel := "info" -}}
{{- $accessModes := $rootCtx.Values.global.fallbackDefaults.vctAccessModes -}}
{{- $walAccessModes := $rootCtx.Values.global.fallbackDefaults.vctAccessModes -}}
{{/* Make sure keys exist before try to access any sub keys */}}
{{- if not (hasKey $objectData "cluster") -}}
{{- $_ := set $objectData "cluster" dict -}}
{{- end -}}
{{- if not (hasKey $objectData "monitoring") -}}
{{- $_ := set $objectData "monitoring" dict -}}
{{- end -}}
{{- if not (hasKey $objectData "backups") -}}
{{- $_ := set $objectData "backups" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.cluster "storage") -}}
{{- $_ := set $objectData.cluster "storage" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.cluster "walStorage") -}}
{{- $_ := set $objectData.cluster "walStorage" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.cluster "resources") -}}
{{- $_ := set $objectData.cluster "resources" dict -}}
{{- end -}}
{{/* Exclude extra resources */}}
{{- $_ := set $objectData.cluster.resources "excludeExtra" true -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $clusterLabels := $objectData.cluster.labels | default dict -}}
{{- $clusterLabels = mustMerge $clusterLabels $objLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $clusterAnnotations := $objectData.cluster.annotations | default dict -}}
{{- $clusterAnnotations = mustMerge $clusterAnnotations $objAnnotations -}}
{{- with $objectData.cluster.instances -}}
{{- $instances = . -}}
{{- end -}}
{{/* Stop All */}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $hibernation = "on" -}}
{{- end -}}
{{/* General */}}
{{- with $objectData.mode -}}
{{- $mode = . -}}
{{- end -}}
{{- with $objectData.cluster.primaryUpdateStrategy -}}
{{- $primaryUpdateStrategy = . -}}
{{- end -}}
{{- with $objectData.cluster.primaryUpdateMethod -}}
{{- $primaryUpdateMethod = . -}}
{{- end -}}
{{- with $objectData.cluster.logLevel -}}
{{- $logLevel = . -}}
{{- end -}}
{{/* Monitoring */}}
{{- with $objectData.monitoring -}}
{{- if (kindIs "bool" .enablePodMonitor) -}}
{{- $enableMonitoring = .enablePodMonitor -}}
{{- end -}}
{{- if (kindIs "bool" .disableDefaultQueries) -}}
{{- $disableDefaultQueries = .disableDefaultQueries -}}
{{- end -}}
{{- with .customQueries -}}
{{- $customQueries = . -}}
{{- end -}}
{{- end -}}
{{/* Superuser */}}
{{- if (kindIs "bool" $objectData.cluster.enableSuperuserAccess) -}}
{{- $enableSuperUser = $objectData.cluster.enableSuperuserAccess -}}
{{- end -}}
{{/* Node Maintenance Window */}}
{{- if $objectData.cluster.singleNode -}}
{{- $inProgress = true -}}
{{- end -}}
{{- with $objectData.cluster.nodeMaintenanceWindow -}}
{{- if (kindIs "bool" .inProgress) -}}
{{ $inProgress = .inProgress -}}
{{- end -}}
{{- if (kindIs "bool" .reusePVC) -}}
{{ $reusePVC = .reusePVC -}}
{{- end -}}
{{- end -}}
{{/* Preload Libraries */}}
{{- if (kindIs "slice" $objectData.cluster.preloadLibraries) -}}
{{- $preloadLibraries = $objectData.cluster.preloadLibraries -}}
{{- end -}}
{{- if eq $objectData.type "timescaledb" -}}
{{- $preloadLibraries = mustAppend $preloadLibraries "timescaledb" -}}
{{- end -}}
{{- if eq $objectData.type "vectors" -}}
{{- $preloadLibraries = mustAppend $preloadLibraries "vectors.so" -}}
{{- end -}}
{{/* Storage */}}
{{- with $objectData.cluster.storage.size -}}
{{- $size = . -}}
{{- end -}}
{{- with $objectData.cluster.walStorage.size -}}
{{- $walSize = . -}}
{{- end -}}
{{- with $objectData.cluster.storage.accessModes -}}
{{- $accessModes = . -}}
{{- end -}}
{{- with $objectData.cluster.walStorage.accessModes -}}
{{- $walAccessModes = . -}}
{{- end -}}
{{- $imageName := $objectData.cluster.imageName -}}
{{- if not $imageName -}}
{{/* Ensure version and container tracking */}}
{{- $imageType := ($objectData.type | default "postgres") | camelcase | title -}}
{{- if eq $imageType "Postgres" -}}
{{- $imageType = "" -}}
{{- end -}}
{{/* Format is [postgresCustomNameVersionImage] */}}
{{- $imageKey := printf "postgres%s%sImage" $imageType $objectData.pgVersion -}}
{{- $imageValue := fromJson (include "tc.v1.common.lib.container.imageSelector" (dict "rootCtx" $rootCtx "objectData" (dict "imageSelector" $imageKey))) -}}
{{- $formatImage := printf "%s:%s" $imageValue.repository $imageValue.tag -}}
{{- $imageName = $formatImage -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: {{ $objectData.clusterName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Cluster") }}
labels:
cnpg.io/reload: "on"
{{- $labels := (mustMerge $clusterLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end }}
annotations:
cnpg.io/hibernation: {{ $hibernation | quote }}
checksum/secrets: {{ toJson $rootCtx.Values.secret | sha256sum }}
{{- $annotations := (mustMerge $clusterAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
imageName: {{ $imageName }}
enableSuperuserAccess: {{ $enableSuperUser }}
primaryUpdateStrategy: {{ $primaryUpdateStrategy }}
primaryUpdateMethod: {{ $primaryUpdateMethod }}
logLevel: {{ $logLevel }}
instances: {{ $instances }}
{{- if or $objectData.cluster.postgresql $preloadLibraries }}
postgresql:
{{- with $objectData.cluster.postgresql }}
parameters:
{{- range $k, $v := . }}
{{ $k }}: {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- with $preloadLibraries }}
shared_preload_libraries:
{{- range $lib := (. | mustUniq) }}
- {{ $lib | quote }}
{{- end -}}
{{- end -}}
{{- end }}
nodeMaintenanceWindow:
inProgress: {{ $inProgress }}
reusePVC: {{ $reusePVC }}
{{- with (include "tc.v1.common.lib.container.resources" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster) | trim) }}
resources:
{{- . | nindent 4 }}
{{- end }}
storage:
pvcTemplate:
{{- $_ := set $objectData.cluster.storage "size" $size -}}
{{- $_ := set $objectData.cluster.storage "accessModes" $accessModes -}}
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster.storage) | trim | nindent 6 }}
walStorage:
pvcTemplate:
{{- $_ := set $objectData.cluster.walStorage "size" $walSize -}}
{{- $_ := set $objectData.cluster.walStorage "accessModes" $walAccessModes -}}
{{- include "tc.v1.common.lib.storage.pvc.spec" (dict "rootCtx" $rootCtx "objectData" $objectData.cluster.walStorage) | trim | nindent 6 }}
{{- if $enableMonitoring }}
monitoring:
enablePodMonitor: {{ $enableMonitoring }}
disableDefaultQueries: {{ $disableDefaultQueries }}
{{- if $customQueries }}
customQueriesConfigMap:
{{- range $q := $customQueries }}
{{- $name := $q.name -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" $q
"name" $q.name "caller" "CNPG Cluster"
"key" "monitoring.customQueries")) -}}
{{- if eq $expandName "true" -}}
{{- $name = (printf "%s-cnpg-%s-%s" $fullname $objectData.shortName $q.name) -}}
{{- end }}
- name: {{ $name }}
key: {{ $q.key | default "custom-queries" }}
{{- end -}}
{{- end -}}
{{- end }}
bootstrap:
{{- if eq $mode "standalone" -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.standalone" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 4 -}}
{{- else if eq $mode "recovery" -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery" (dict "objectData" $objectData) | nindent 4 -}}
{{- include "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery.externalCluster" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 2 -}}
{{- end -}}
{{- if $objectData.backups.enabled }}
{{- include "tc.v1.common.lib.cnpg.cluster.backup" (dict "rootCtx" $rootCtx "objectData" $objectData) | nindent 2 -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,57 @@
{{- define "tc.v1.common.class.cnpg.pooler" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $poolerName := printf "%s-pooler-%s" $objectData.name $objectData.pooler.type -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $poolerName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Pooler") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $poolerLabels := $objectData.pooler.labels | default dict -}}
{{- $poolerLabels = mustMerge $poolerLabels $objLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $poolerAnnotations := $objectData.pooler.annotations | default dict -}}
{{- $poolerAnnotations = mustMerge $poolerAnnotations $objAnnotations -}}
{{- $instances := $objectData.pooler.instances | default 2 -}}
{{/* Stop All */}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $instances = 0 -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: Pooler
metadata:
name: {{ $poolerName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Pooler") }}
labels:
cnpg.io/reload: "on"
{{- $labels := (mustMerge $poolerLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end }}
annotations:
checksum/secrets: {{ toJson $rootCtx.Values.secret | sha256sum }}
{{- $annotations := (mustMerge $poolerAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
cluster:
name: {{ $objectData.clusterName }}
instances: {{ $instances }}
type: {{ $objectData.pooler.type }}
pgbouncer:
poolMode: {{ $objectData.pooler.poolMode | default "session" }}
{{/* https://cloudnative-pg.io/documentation/1.15/connection_pooling/#pgbouncer-configuration-options */}}
{{- with $objectData.pooler.parameters }}
parameters:
{{- range $key, $value := . }}
{{ $key }}: {{ tpl $value $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,58 @@
{{- define "tc.v1.common.class.cnpg.scheduledbackup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Naming */}}
{{- $backupName := printf "%v-sched-backup-%v" $objectData.name $objectData.backupName -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $backupName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "CNPG Scheduled Backup") -}}
{{/* Metadata */}}
{{- $objLabels := $objectData.labels | default dict -}}
{{- $globalBackupLabels := $objectData.backups.labels | default dict -}}
{{- $backupLabels := $objectData.backupLabels | default dict -}}
{{- $backupLabels = mustMerge $backupLabels $objLabels $globalBackupLabels -}}
{{- $objAnnotations := $objectData.annotations | default dict -}}
{{- $globalBackupAnnotations := $objectData.backups.annotations | default dict -}}
{{- $backupAnnotations := $objectData.backupAnnotations | default dict -}}
{{- $backupAnnotations = mustMerge $backupAnnotations $objAnnotations $globalBackupAnnotations -}}
{{/* Data */}}
{{- $suspend := false -}}
{{- if (hasKey $objectData.schedData "suspend") -}}
{{- $suspend = $objectData.schedData.suspend -}}
{{- end -}}
{{- if or $objectData.hibernate (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}}
{{- $suspend = true -}}
{{- end -}}
{{- $immediate := false -}}
{{- if (hasKey $objectData.schedData "immediate") -}}
{{- $immediate = $objectData.schedData.immediate -}}
{{- end }}
---
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: {{ $backupName }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CNPG Scheduled Backup") }}
labels:
cnpg.io/cluster: {{ $objectData.clusterName }}
{{- $labels := (mustMerge $backupLabels (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge $backupAnnotations (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
schedule: {{ $objectData.schedData.schedule }}
backupOwnerReference: {{ $objectData.schedData.backupOwnerReference | default "none" }}
suspend: {{ $suspend }}
immediate: {{ $immediate }}
cluster:
name: {{ $objectData.clusterName }}
{{- end -}}
@@ -0,0 +1,48 @@
{{- define "tc.v1.common.class.podmonitor" -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $podmonitorName := $fullName -}}
{{- $values := .Values.podmonitor -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.metrics -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $podmonitorLabels := $values.labels -}}
{{- $podmonitorAnnotations := $values.annotations -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $podmonitorName = printf "%v-%v" $podmonitorName $values.nameOverride -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.podmonitor.apiVersion" $ }}
kind: PodMonitor
metadata:
name: {{ $podmonitorName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($podmonitorLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end }}
{{- $annotations := (mustMerge ($podmonitorAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
jobLabel: app.kubernetes.io/name
selector:
{{- if $values.selector }}
{{- tpl (toYaml $values.selector) $ | nindent 4 }}
{{- else }}
{{- $objectData := dict "targetSelector" $values.targetSelector }}
{{- $selectedPod := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $ "objectData" $objectData)) }}
{{- $selectedPodName := $selectedPod.shortName }}
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "pod" "objectName" $selectedPodName) | indent 6 }}
{{- end }}
podMetricsEndpoints:
{{- tpl (toYaml $values.endpoints) $ | nindent 4 }}
{{- end -}}
@@ -0,0 +1,56 @@
{{- define "tc.v1.common.class.prometheusrule" -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $prometheusruleName := $fullName -}}
{{- $values := .Values.prometheusrule -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.metrics -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $prometheusruleLabels := $values.labels -}}
{{- $prometheusruleAnnotations := $values.annotations -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $prometheusruleName = printf "%v-%v" $prometheusruleName $values.nameOverride -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.prometheusrule.apiVersion" $ }}
kind: PrometheusRule
metadata:
name: {{ $prometheusruleName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($prometheusruleLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end }}
{{- $annotations := (mustMerge ($prometheusruleAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
groups:
{{- range $name, $groupValues := .groups }}
- name: {{ $prometheusruleName }}-{{ $name }}
rules:
{{- with $groupValues.rules }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with $groupValues.additionalrules }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- range $id, $groupValues := .additionalgroups }}
- name: {{ $prometheusruleName }}-{{ if $groupValues.name }}{{ $groupValues.name }}{{ else }}{{ $id }}{{ end }}
rules:
{{- with $groupValues.rules }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with $groupValues.additionalrules }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- end -}}
@@ -0,0 +1,48 @@
{{- define "tc.v1.common.class.servicemonitor" -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $servicemonitorName := $fullName -}}
{{- $values := .Values.servicemonitor -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.metrics -}}
{{- $values = . -}}
{{- end -}}
{{- end -}}
{{- $servicemonitorLabels := $values.labels -}}
{{- $servicemonitorAnnotations := $values.annotations -}}
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
{{- $servicemonitorName = printf "%v-%v" $servicemonitorName $values.nameOverride -}}
{{- end }}
---
apiVersion: {{ include "tc.v1.common.capabilities.servicemonitor.apiVersion" $ }}
kind: ServiceMonitor
metadata:
name: {{ $servicemonitorName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($servicemonitorLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end }}
{{- $annotations := (mustMerge ($servicemonitorAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
jobLabel: app.kubernetes.io/name
selector:
{{- if $values.selector }}
{{- tpl (toYaml $values.selector) $ | nindent 4 }}
{{- else }}
{{- $objectData := dict "targetSelector" $values.targetSelector }}
{{- $selectedService := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $ "objectData" $objectData)) }}
{{- $selectedServiceName := $selectedService.shortName }}
matchLabels:
{{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "service" "objectName" $selectedServiceName) | indent 6 }}
{{- end }}
endpoints:
{{- tpl (toYaml $values.endpoints) $ | nindent 4 }}
{{- end -}}
@@ -0,0 +1,53 @@
{{/* replicationdestination Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.replicationdestination" (dict "rootCtx" $ "objectData" $objectData "volsyncData" $volsyncData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the replicationdestination.
labels: The labels of the replicationdestination.
annotations: The annotations of the replicationdestination.
data: The data of the replicationdestination.
namespace: The namespace of the replicationdestination. (Optional)
*/}}
{{- define "tc.v1.common.class.replicationdestination" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $volsyncData := .volsyncData -}}
{{- $capacity := $rootCtx.Values.global.fallbackDefaults.pvcSize -}}
{{- if $objectData.size -}}
{{- $capacity = $objectData.size -}}
{{- end -}}
{{- if $volsyncData.dest.capacity -}}
{{- $capacity = $volsyncData.dest.capacity -}}
{{- end }}
---
apiVersion: volsync.backube/v1alpha1
kind: ReplicationDestination
metadata:
name: {{ printf "%s-%s-dest" $objectData.name $volsyncData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Replication Destination") }}
{{- $labels := (mustMerge ($volsyncData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($volsyncData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
trigger:
manual: restore-once
{{ $volsyncData.type }}:
repository: {{ $volsyncData.repository }}
copyMethod: {{ $volsyncData.copyMethod | default "Snapshot"}}
capacity: {{ $capacity }}
{{- include "tc.v1.common.lib.volsync.storage" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "dest") | trim | nindent 4 }}
{{- include "tc.v1.common.lib.volsync.cache" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "dest") | trim | nindent 4 }}
{{- include "tc.v1.common.lib.volsync.moversecuritycontext" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "dest") | trim | nindent 4 }}
{{- end -}}
@@ -0,0 +1,66 @@
{{/* replicationsource Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.replicationsource" (dict "rootCtx" $ "objectData" $objectData "volsyncData" $volsyncData) }}
rootCtx: The root context of the chart.
objectData:
name: The name of the replicationsource.
labels: The labels of the replicationsource.
annotations: The annotations of the replicationsource.
data: The data of the replicationsource.
namespace: The namespace of the replicationsource. (Optional)
*/}}
{{- define "tc.v1.common.class.replicationsource" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $volsyncData := .volsyncData -}}
{{- $schedule := "0 0 * * *" -}}
{{- if and $volsyncData.src.trigger $volsyncData.src.trigger.schedule -}}
{{- $schedule = $volsyncData.src.trigger.schedule -}}
{{- end }}
{{- $retain := dict "hourly" 24 "daily" 7 "weekly" 5 -}}
{{- if $volsyncData.src.retain -}}
{{- $items := list "hourly" "daily" "weekly" -}}
{{- range $item := $items -}}
{{- with get $volsyncData.src.retain $item -}}
{{- $_ := set $retain $item . -}}
{{- end -}}
{{- end -}}
{{- end }}
---
apiVersion: volsync.backube/v1alpha1
kind: ReplicationSource
metadata:
name: {{ printf "%s-%s" $objectData.name $volsyncData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Replication Source") }}
{{- $labels := (mustMerge ($volsyncData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($volsyncData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
sourcePVC: {{ $objectData.name }}
trigger:
schedule: {{ $schedule }}
{{ $volsyncData.type }}:
repository: {{ $volsyncData.repository }}
copyMethod: {{ $volsyncData.copyMethod | default "Snapshot" }}
pruneIntervalDays: {{ $volsyncData.src.pruneIntervalDays | default 7 }}
unlock: {{ now | date "20060102150405" | quote }}
retain:
hourly: {{ $retain.hourly }}
daily: {{ $retain.daily }}
weekly: {{ $retain.weekly }}
{{- include "tc.v1.common.lib.volsync.storage" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "src") | trim | nindent 4 }}
{{- include "tc.v1.common.lib.volsync.cache" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "src") | trim | nindent 4 }}
{{- include "tc.v1.common.lib.volsync.moversecuritycontext" (dict "rootCtx" $rootCtx "objectData" $objectData "volsyncData" $volsyncData "target" "src") | trim | nindent 4 }}
{{- end }}
@@ -0,0 +1,23 @@
{{/* Check Env for Duplicates */}}
{{/* Call this template:
{{ include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $ "objectData" $objectData "source" $source "key" $key) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.helper.container.envDupeCheck" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $source := .source -}}
{{- $type := .type -}}
{{- $key := .key -}}
{{- $dupeEnv := (get $objectData.envDupe $key) -}}
{{- if $dupeEnv -}}
{{- fail (printf "Container - Environment Variable [%s] in [%s] tried to override the Environment Variable that is already defined in [%s]" $key $source $dupeEnv.source) -}}
{{- end -}}
{{- $_ := set $objectData.envDupe $key (dict "source" $source) -}}
{{- end -}}
@@ -0,0 +1,59 @@
{{/* Returns Lowest and Highest ports assigned to the any container in the pod */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.helpers.securityContext.getPortRange" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the Pod.
*/}}
{{- define "tc.v1.common.lib.helpers.securityContext.getPortRange" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{ $portRange := (dict "high" 0 "low" 0) }}
{{- range $name, $service := $rootCtx.Values.service -}}
{{- $selected := false -}}
{{/* If service is enabled... */}}
{{- if $service.enabled -}}
{{/* If there is a selector */}}
{{- if $service.targetSelector -}}
{{/* And pod is selected */}}
{{- if eq $service.targetSelector $objectData.shortName -}}
{{- $selected = true -}}
{{- end -}}
{{- else -}}
{{/* If no selector is defined but pod is primary */}}
{{- if $objectData.primary -}}
{{- $selected = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $selected -}}
{{- range $name, $portValues := $service.ports -}}
{{- if $portValues.enabled -}}
{{- $portToCheck := ($portValues.targetPort | default $portValues.port) -}}
{{- if kindIs "string" $portToCheck -}}
{{- $portToCheck = (tpl $portToCheck $rootCtx) | int -}}
{{- end -}}
{{- if or (not $portRange.low) (lt ($portToCheck | int) ($portRange.low | int)) -}}
{{- $_ := set $portRange "low" $portToCheck -}}
{{- end -}}
{{- if or (not $portRange.high) (gt ($portToCheck | int) ($portRange.high | int)) -}}
{{- $_ := set $portRange "high" $portToCheck -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $portRange | toJson -}}
{{- end -}}
@@ -0,0 +1,47 @@
{{/* Service - Get Selected Pod */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
objectData: The object data of the service
rootCtx: The root context of the chart.
*/}}
{{- define "tc.v1.common.lib.helpers.getSelectedPodValues" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- $podValues := dict -}}
{{- with $objectData.targetSelector -}}
{{- $podValues = mustDeepCopy (get $rootCtx.Values.workload .) -}}
{{- if not $podValues -}}
{{- fail (printf "%s - Selected pod [%s] is not defined" $caller .) -}}
{{- end -}}
{{- if not $podValues.enabled -}}
{{- fail (printf "%s - Selected pod [%s] is not enabled" $caller .) -}}
{{- end -}}
{{/* While we know the shortName from targetSelector, let's set it explicitly
So service can reference this directly, to match the behaviour of a service
without targetSelector defined (assumes "use primary") */}}
{{- $_ := set $podValues "shortName" . -}}
{{- else -}}
{{/* If no targetSelector is defined, we assume the service is using the primary pod */}}
{{/* Also no need to check for multiple primaries here, it's already done on the workload validation */}}
{{- range $podName, $pod := $rootCtx.Values.workload -}}
{{- if $pod.enabled -}}
{{- if $pod.primary -}}
{{- $podValues = mustDeepCopy $pod -}}
{{/* Set the shortName so service can use this on selector */}}
{{- $_ := set $podValues "shortName" $podName -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Return values in Json, to preserve types */}}
{{ $podValues | toJson }}
{{- end -}}
@@ -0,0 +1,47 @@
{{/* Service - Get Selected Service */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
objectData: The object data of the service
rootCtx: The root context of the chart.
*/}}
{{- define "tc.v1.common.lib.helpers.getSelectedServiceValues" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- $serviceValues := dict -}}
{{- with $objectData.targetSelector -}}
{{- $serviceValues = mustDeepCopy (get $rootCtx.Values.service .) -}}
{{- if not $serviceValues -}}
{{- fail (printf "%s - Selected service [%s] is not defined" $caller .) -}}
{{- end -}}
{{- if not $serviceValues.enabled -}}
{{- fail (printf "%s - Selected service [%s] is not enabled" $caller .) -}}
{{- end -}}
{{/* While we know the shortName from targetSelector, let's set it explicitly
So service can reference this directly, to match the behaviour of a service
without targetSelector defined (assumes "use primary") */}}
{{- $_ := set $serviceValues "shortName" . -}}
{{- else -}}
{{/* If no targetSelector is defined, we assume the service is using the primary service */}}
{{/* Also no need to check for multiple primaries here, it's already done on the service validation */}}
{{- range $serviceName, $service := $rootCtx.Values.service -}}
{{- if $service.enabled -}}
{{- if $service.primary -}}
{{- $serviceValues = mustDeepCopy $service -}}
{{/* Set the shortName so service can use this on selector */}}
{{- $_ := set $serviceValues "shortName" $serviceName -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Return values in Json, to preserve types */}}
{{ $serviceValues | toJson }}
{{- end -}}
@@ -0,0 +1,21 @@
{{- define "tc.v1.common.helper.makeIntOrNoop" -}}
{{- $value := . -}}
{{/*
- Ints in Helm can be either int, int64 or float64.
- Values that start with zero should not be converted
to int again as this will strip leading zeros.
- Numbers converted to E notation by Helm will
always contain the "e" character. So we only
convert those.
*/}}
{{- if and
(mustHas (kindOf $value) (list "int" "int64" "float64"))
(not (hasPrefix "0" ($value | toString)))
(contains "e" ($value | toString | lower))
-}}
{{- $value | int -}}
{{- else -}}
{{- $value -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,24 @@
{{/* Return the appropriate apiVersion for PodMonitor */}}
{{- define "tc.v1.common.capabilities.podmonitor.apiVersion" -}}
{{- print "monitoring.coreos.com/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for ServiceMonitor */}}
{{- define "tc.v1.common.capabilities.servicemonitor.apiVersion" -}}
{{- print "monitoring.coreos.com/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for PrometheusRule */}}
{{- define "tc.v1.common.capabilities.prometheusrule.apiVersion" -}}
{{- print "monitoring.coreos.com/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for NetworkPolicy*/}}
{{- define "tc.v1.common.capabilities.networkpolicy.apiVersion" -}}
{{- print "networking.k8s.io/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for HorizontalPodAutoscaler aka HPA*/}}
{{- define "tc.v1.common.capabilities.hpa.apiVersion" -}}
{{- print "autoscaling/v2" -}}
{{- end -}}
@@ -0,0 +1,49 @@
{{/* Certificate Validation */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.certificate.validation" (dict "rootCtx" $ "objectData" $objectData) -}}
objectData:
rootCtx: The root context of the chart.
objectData: The Certificate object.
*/}}
{{- define "tc.v1.common.lib.certificate.validation" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.certificateIssuer -}}
{{- fail "Cert Manager Certificate - Expected non-empty [certificateIssuer]" -}}
{{- end -}}
{{- if not $objectData.hosts -}}
{{- fail "Cert Manager Certificate - Expected non-empty [hosts]" -}}
{{- end -}}
{{- if not (kindIs "slice" $objectData.hosts) -}}
{{- fail (printf "Cert Manager Certificate - Expected [hosts] to be a [slice], but got [%s]" (kindOf $objectData.hosts)) -}}
{{- end -}}
{{- range $h := $objectData.hosts -}}
{{- if not $h -}}
{{- fail "Cert Manager Certificate - Expected non-empty entry in [hosts]" -}}
{{- end -}}
{{- $host := tpl $h $rootCtx -}}
{{- if (hasPrefix "http://" $host) -}}
{{- fail (printf "Cert Manager Certificate - Expected entry in [hosts] to not start with [http://], but got [%s]" $host) -}}
{{- end -}}
{{- if (hasPrefix "https://" $host) -}}
{{- fail (printf "Cert Manager Certificate - Expected entry in [hosts] to not start with [https://], but got [%s]" $host) -}}
{{- end -}}
{{- if (contains ":" $host) -}}
{{- fail (printf "Cert Manager Certificate - Expected entry in [hosts] to not contain [:], but got [%s]" $host) -}}
{{- end -}}
{{- with $objectData.certificateSecretTemplate -}}
{{- if and (not .labels) (not .annotations) -}}
{{- fail "Cert Manager Certificate - Expected [certificateSecretTemplate] to have at least one of [labels, annotations]" -}}
{{- end -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData.certificateSecretTemplate "caller" "Cert Manager Certificate (certificateSecretTemplate)") -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,16 @@
{{- define "tc.v1.common.check.capabilities" -}}
{{- $helmVersion := semver .Capabilities.HelmVersion.Version -}}
{{- $helmMinVer := semver "3.9.4" -}}
{{- if .Chart.Annotations -}}
{{- $min := index .Chart.Annotations "truecharts.org/min_helm_version" -}}
{{- if $min -}}
{{/* Apply a relaxed version check */}}
{{- $helmMinVer = semver $min -}}
{{- end -}}
{{- end -}}
{{- if eq -1 ($helmMinVer | $helmVersion.Compare) -}}
{{- fail (printf "Expected minimum helm version [%s], but found [%s]. Upgrade helm cli tool." $helmMinVer $helmVersion) -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,52 @@
{{/* Contains functions for generating names */}}
{{/* Returns the name of the Chart */}}
{{- define "tc.v1.common.lib.chart.names.name" -}}
{{- .Chart.Name | lower | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Returns the fullname of the Chart */}}
{{- define "tc.v1.common.lib.chart.names.fullname" -}}
{{- $name := include "tc.v1.common.lib.chart.names.name" . -}}
{{- if contains $name .Release.Name -}}
{{- $name = .Release.Name -}}
{{- else -}}
{{- $name = printf "%s-%s" .Release.Name $name -}}
{{- end -}}
{{- $name | lower | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Returns the fqdn of the Chart */}}
{{- define "tc.v1.common.lib.chart.names.fqdn" -}}
{{- printf "%s.%s" (include "tc.v1.common.lib.chart.names.fullname" .) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/* Validates names */}}
{{- define "tc.v1.common.lib.chart.names.validation" -}}
{{- $name := .name -}}
{{- $length := .length -}}
{{- if not $length -}}
{{- $length = 63 -}}
{{- end -}}
{{- if not (and (mustRegexMatch "^[a-z0-9]((-?[a-z0-9]-?)*[a-z0-9])?$" $name) (le (len $name) $length)) -}}
{{- fail (printf "Name [%s] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most %v characters." $name $length) -}}
{{- end -}}
{{- end -}}
{{/* Create chart name and version as used by the chart label */}}
{{- define "tc.v1.common.lib.chart.names.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
@@ -0,0 +1,38 @@
{{- define "tc.v1.common.lib.chart.notes" -}}
{{- include "tc.v1.common.lib.chart.header" . -}}
{{- include "tc.v1.common.lib.chart.custom" . -}}
{{- include "tc.v1.common.lib.chart.footer" . -}}
{{- include "tc.v1.common.lib.chart.warnings" . -}}
{{- end -}}
{{- define "tc.v1.common.lib.chart.header" -}}
{{- tpl $.Values.notes.header $ | nindent 0 }}
{{- end -}}
{{- define "tc.v1.common.lib.chart.custom" -}}
{{- tpl $.Values.notes.custom $ | nindent 0 }}
{{- end -}}
{{- define "tc.v1.common.lib.chart.footer" -}}
{{- tpl $.Values.notes.footer $ | nindent 0 }}
{{- end -}}
{{- define "tc.v1.common.lib.chart.warnings" -}}
{{- range $w := $.Values.notes.warnings }}
{{- tpl $w $ | nindent 0 }}
{{- end }}
{{- end -}}
{{- define "add.warning" -}}
{{- $rootCtx := .rootCtx -}}
{{- $warn := .warn -}}
{{- $newWarns := $rootCtx.Values.notes.warnings -}}
{{- $newWarns = mustAppend $newWarns $warn -}}
{{- $_ := set $rootCtx.Values.notes "warnings" $newWarns -}}
{{- end -}}
@@ -0,0 +1,102 @@
{{- define "tc.v1.common.lib.cnpg.db.credentials.secrets" -}}
{{- $objectData := .objectData -}}
{{- $cnpg := .cnpg -}}
{{- $rootCtx := .rootCtx -}}
{{- $dbPass := $objectData.password -}}
{{- $auth := printf "%s:%s" $objectData.user $dbPass -}}
{{/* Double "%" to escape the interpolation and use the template on another printf */}}
{{- $stdTmpl := printf "postgresql://%s@%s-%%s:5432/%s" $auth $objectData.name $objectData.database -}}
{{- $nosslTmpl := printf "postgresql://%s@%s-%%s:5432/%s?sslmode=disable" $auth $objectData.name $objectData.database -}}
{{- $portHostTmpl := printf "%s-%%s:5432" $objectData.name -}}
{{- $hostTmpl := printf "%s-%%s" $objectData.name -}}
{{- $jdbcTmpl := printf "jdbc:postgresql://%s-%%s:5432/%s" $objectData.name $objectData.database -}}
{{- $rwString := "rw" -}}
{{- $roString := "ro" -}}
{{- $poolEnabled := false -}}
{{- if and $objectData.pooler $objectData.pooler.enabled -}}
{{- $poolEnabled = true -}}
{{- $rwString = "pooler-rw" -}}
{{- $roString = "pooler-ro" -}}
{{- end -}}
{{- $creds := (dict
"std" (printf $stdTmpl $rwString)
"nossl" (printf $nosslTmpl $rwString)
"portHost" (printf $portHostTmpl $rwString)
"host" (printf $hostTmpl $rwString)
"jdbc" (printf $jdbcTmpl $rwString)
) -}}
{{- $credsRO := dict -}}
{{- if and $poolEnabled $objectData.pooler.createRO -}}
{{- $credsRO = (dict
"std" (printf $stdTmpl $roString)
"nossl" (printf $nosslTmpl $roString)
"portHost" (printf $portHostTmpl $roString)
"host" (printf $hostTmpl $roString)
"jdbc" (printf $jdbcTmpl $roString)
) -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.cnpg.secret.user" (dict "user" $objectData.user "pass" $dbPass) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-user" $objectData.shortName) . -}}
{{- end -}}
{{- with (include "tc.v1.common.lib.cnpg.secret.urls" (dict "creds" $creds "credsRO" $credsRO) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-urls" $objectData.shortName) . -}}
{{- end -}}
{{/* We need to mutate the actual (cnpg) values here not the copy */}}
{{- if not (hasKey $cnpg "creds") -}}
{{- $_ := set $cnpg "creds" dict -}}
{{- end -}}
{{- $_ := set $cnpg.creds "password" $dbPass -}}
{{- $_ := set $cnpg.creds "std" $creds.std -}}
{{- $_ := set $cnpg.creds "nossl" $creds.nossl -}}
{{- $_ := set $cnpg.creds "porthost" $creds.portHost -}}
{{- $_ := set $cnpg.creds "host" $creds.host -}}
{{- $_ := set $cnpg.creds "jdbc" $creds.jdbc -}}
{{- if and $poolEnabled $objectData.pooler.createRO -}}
{{- $_ := set $cnpg.creds "stdRO" $credsRO.std -}}
{{- $_ := set $cnpg.creds "nosslRO" $credsRO.nossl -}}
{{- $_ := set $cnpg.creds "porthostRO" $credsRO.portHost -}}
{{- $_ := set $cnpg.creds "hostRO" $credsRO.host -}}
{{- $_ := set $cnpg.creds "jdbcRO" $credsRO.jdbc -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.secret.urls" -}}
{{- $creds := .creds -}}
{{- $credsRO := .credsRO }}
enabled: true
data:
std: {{ $creds.std }}
nossl: {{ $creds.nossl }}
porthost: {{ $creds.portHost }}
host: {{ $creds.host }}
jdbc: {{ $creds.jdbc }}
{{- if $credsRO }}
stdRO: {{ $credsRO.std }}
nosslRO: {{ $credsRO.nossl }}
porthostRO: {{ $credsRO.portHost }}
hostRO: {{ $credsRO.host }}
jdbcRO: {{ $credsRO.jdbc }}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.cnpg.secret.user" -}}
{{- $user := .user -}}
{{- $pass := .pass }}
enabled: true
type: kubernetes.io/basic-auth
data:
username: {{ $user }}
password: {{ $pass }}
{{- end -}}
@@ -0,0 +1,10 @@
{{- define "tc.v1.common.lib.cnpg.metrics.pooler" -}}
{{- $poolerName := .poolerName }}
enabled: true
type: podmonitor
selector:
matchLabels:
cnpg.io/poolerName: {{ $poolerName }}
endpoints:
- port: metrics
{{- end -}}
@@ -0,0 +1,14 @@
{{- define "tc.v1.common.lib.cnpg.spawner.backups" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $backup := $objectData.backups.manualBackups -}}
{{- $_ := set $objectData "backupName" $backup.name -}}
{{- $_ := set $objectData "backupLabels" $backup.labels -}}
{{- $_ := set $objectData "backupAnnotations" $backup.annotations -}}
{{- include "tc.v1.common.lib.cnpg.backup.validation" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.class.cnpg.backup" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,7 @@
{{- define "tc.v1.common.lib.cnpg.backup.validation" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.backupName -}}
{{- fail "CNPG Backup - Expected non-empty [name] in [backups.manualBackups] entry" -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,48 @@
{{- define "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.getData" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $type := .type -}}
{{- $serverName := $objectData.clusterName -}}
{{- $endpointURL := "" -}}
{{- $destinationPath := "" -}}
{{- $creds := dict -}}
{{- $key := "" -}}
{{- if eq $type "recovery" -}}
{{- $creds = (get $rootCtx.Values.credentials $objectData.recovery.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG BarmanObjectStore" "credName" $objectData.recovery.credentials) -}}
{{- $destinationPath = $objectData.recovery.destinationPath -}}
{{- $key = "recovery" -}}
{{- if $objectData.recovery.serverName -}}
{{- $serverName = $objectData.recovery.serverName -}}
{{- end -}}
{{- if $objectData.recovery.revision -}}
{{- $serverName = printf "%s-r%s" $serverName $objectData.recovery.revision -}}
{{- end -}}
{{- else if eq $type "backup" -}}
{{- $creds = (get $rootCtx.Values.credentials $objectData.backups.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG BarmanObjectStore" "credName" $objectData.backups.credentials) -}}
{{- $destinationPath = $objectData.backups.destinationPath -}}
{{- $key = "backups" -}}
{{- if $objectData.backups.serverName -}}
{{- $serverName = $objectData.backups.serverName -}}
{{- end -}}
{{- if $objectData.backups.revision -}}
{{- $serverName = printf "%s-r%s" $serverName $objectData.backups.revision -}}
{{- end -}}
{{- end -}}
{{- $data := (dict
"serverName" $serverName
"endpointURL" $endpointURL
"destinationPath" $destinationPath
"creds" $creds
"key" $key
) -}}
{{- $data | toYaml -}}
{{- end -}}
@@ -0,0 +1,38 @@
{{- define "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.s3" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $type := .type -}}
{{- $data := .data -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- $secretName := (printf "%s-cnpg-%s-provider-%s-s3-creds" $fullname $objectData.shortName $type) -}}
{{- $calcData := include "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.getData" (dict
"rootCtx" $rootCtx "objectData" $objectData "type" $type) | fromYaml
-}}
{{- $serverName := $calcData.serverName -}}
{{- $destinationPath := $calcData.destinationPath -}}
{{- $endpointURL := $calcData.creds.url -}}
{{- $bucket := $calcData.creds.bucket -}}
{{- $path := $calcData.creds.path -}}
{{- $key := $calcData.key -}}
{{- if not $destinationPath -}}
{{- if $path -}}
{{- $destinationPath = (printf "s3://%s/%s/%s/cnpg" $bucket ($path | trimSuffix "/") $rootCtx.Release.Name) -}}
{{- else -}}
{{- $destinationPath = (printf "s3://%s/%s/cnpg" $bucket $rootCtx.Release.Name) -}}
{{- end -}}
{{- end }}
endpointURL: {{ $endpointURL }}
destinationPath: {{ $destinationPath }}
serverName: {{ $serverName }}
s3Credentials:
accessKeyId:
name: {{ $secretName }}
key: ACCESS_KEY_ID
secretAccessKey:
name: {{ $secretName }}
key: ACCESS_SECRET_KEY
{{- end -}}
@@ -0,0 +1,25 @@
{{- define "tc.v1.common.lib.cnpg.cluster.backup" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
backup:
{{- with $objectData.backups.target }}
target: {{ . }}
{{- end }}
retentionPolicy: {{ $objectData.backups.retentionPolicy }}
barmanObjectStore:
data:
jobs: {{ $objectData.backups.jobs | default 2 }}
{{- if and $objectData.backups.encryption $objectData.backups.encryption.enabled }}
compression: "gzip"
encryption: "AES256"
wal:
compression: "gzip"
encryption: "AES256"
{{- end -}}
{{/* Fetch provider data */}}
{{/* Get the creds defined in backup.$provider */}}
{{- $creds := (get $rootCtx.Values.credentials $objectData.backups.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG Backup" "credName" $objectData.backups.credentials) -}}
{{- include (printf "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.%s" $creds.type) (dict "rootCtx" $rootCtx "objectData" $objectData "data" $creds "type" "backup") | nindent 4 -}}
{{- end -}}
@@ -0,0 +1,25 @@
{{/* Recovery Template, called when mode is recovery */}}
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery" }}
{{- $objectData := .objectData }}
recovery:
secret:
name: {{ printf "%s-user" $objectData.clusterName }}
database: {{ $objectData.database }}
owner: {{ $objectData.user }}
{{- if eq $objectData.recovery.method "backup" }}
backup:
name: {{ $objectData.recovery.backupName }}
{{- else if eq $objectData.recovery.method "object_store" -}}
{{- $serverName := $objectData.recovery.serverName | default $objectData.clusterName -}}
{{- if $objectData.recovery.revision -}}
{{- $serverName = printf "%s-r%s" $serverName $objectData.recovery.revision -}}
{{- end }}
source: {{ $serverName }}
{{- end -}}
{{- if $objectData.recovery.pitrTarget -}}
{{- with $objectData.recovery.pitrTarget.time }}
recoveryTarget:
targetTime: {{ . | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,22 @@
{{/* Recovery from externalClusters Template, called when mode is recovery */}}
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.recovery.externalCluster" }}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if eq $objectData.recovery.method "object_store" }}
externalClusters:
{{- $serverName := $objectData.recovery.serverName | default $objectData.clusterName -}}
{{- if $objectData.recovery.revision -}}
{{- $serverName = printf "%s-r%s" $serverName $objectData.recovery.revision -}}
{{- end }}
- name: {{ $serverName }}
barmanObjectStore:
{{/* Fetch provider data */}}
{{/* Get the creds defined in backup.$provider */}}
{{- $creds := (get $rootCtx.Values.credentials $objectData.recovery.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG Recovery External Cluster" "credName" $objectData.recovery.credentials) -}}
{{- include (printf "tc.v1.common.lib.cnpg.cluster.barmanObjectStoreConfig.%s" $creds.type) (dict "rootCtx" $rootCtx "objectData" $objectData "data" $creds "type" "recovery") | nindent 6 -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,78 @@
{{- define "tc.v1.common.lib.cnpg.cluster.bootstrap.standalone" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $initdb := dict -}}
{{- $postInitSQL := list -}}
{{- $postInitTemplateSQL := list -}}
{{- $postInitApplicationSQL := list -}}
{{- $dataChecksums := true -}}
{{- if not (hasKey $objectData.cluster "initdb") -}}
{{- $_ := set $objectData.cluster "initdb" dict -}}
{{- end -}}
{{- if (kindIs "bool" $objectData.cluster.initdb.dataChecksums) -}}
{{- $dataChecksums = $objectData.cluster.initdb.dataChecksums -}}
{{- end -}}
{{/* PostInitApplicationSQL */}}
{{- if eq $objectData.type "timescaledb" -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL (list
"CREATE EXTENSION IF NOT EXISTS timescaledb;") -}}
{{- end -}}
{{- if eq $objectData.type "postgis" -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL (list
"CREATE EXTENSION IF NOT EXISTS postgis;"
"CREATE EXTENSION IF NOT EXISTS postgis_topology;"
"CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;"
"CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;") -}}
{{- end }}
{{- if eq $objectData.type "vectors" -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL (list
"CREATE EXTENSION IF NOT EXISTS vectors;") -}}
{{- end -}}
{{- if $objectData.cluster.initdb -}}
{{- $postInitApplicationSQL = concat $postInitApplicationSQL ( $objectData.cluster.initdb.postInitApplicationSQL | default list ) -}}
{{- $postInitSQL = concat $postInitSQL ( $objectData.cluster.initdb.postInitSQL | default list ) -}}
{{- $postInitTemplateSQL = concat $postInitTemplateSQL ( $objectData.cluster.initdb.postInitTemplateSQL | default list ) -}}
{{- end -}}
initdb:
secret:
name: {{ printf "%s-user" $objectData.clusterName }}
database: {{ $objectData.database }}
owner: {{ $objectData.user }}
dataChecksums: {{ $dataChecksums }}
{{- with $objectData.cluster.initdb.encoding }}
encoding: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.localeCollate }}
localeCollate: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.localeCtype }}
localeCtype: {{ . }}
{{- end -}}
{{- with $objectData.cluster.initdb.walSegmentSize }}
walSegmentSize: {{ . }}
{{- end -}}
{{- if $postInitApplicationSQL }}
postInitApplicationSQL:
{{- range $v := $postInitApplicationSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- if $postInitSQL }}
postInitSQL:
{{- range $v := $postInitSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- if $postInitTemplateSQL }}
postInitTemplateSQL:
{{- range $v := $postInitTemplateSQL }}
- {{ tpl $v $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,146 @@
{{- define "tc.v1.common.lib.cnpg.cluster.validation" -}}
{{- $objectData := .objectData -}}
{{- $requiredKeys := (list "database" "user" "password") -}}
{{- range $key := $requiredKeys -}}
{{- if not (get $objectData $key) -}}
{{- fail (printf "CNPG - Expected a non-empty [%s] key" $key) -}}
{{- end -}}
{{- end -}}
{{/* Kinda imposibble to happen, as we explicitly set it to string on the spawner */}}
{{- if not (kindIs "string" $objectData.pgVersion) -}}
{{/* We must ensure that this is a string, as it is used in image selector that require a string */}}
{{- fail (printf "CNPG - Expected [pgVersion] to be a string, but got [%s]" (kindOf $objectData.pgVersion)) -}}
{{- end -}}
{{- $validVersions := (list "15" "16") -}}
{{- if not (mustHas $objectData.pgVersion $validVersions) -}}
{{- fail (printf "CNPG - Expected [pgVersion] to be one of [%s], but got [%s]" (join ", " $validVersions) $objectData.pgVersion) -}}
{{- end -}}
{{- if (hasKey $objectData "hibernate") -}}
{{- if not (kindIs "bool" $objectData.hibernate) -}}
{{- fail (printf "CNPG - Expected [hibernate] to be a boolean, but got [%s]" (kindOf $objectData.hibernate)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "instances") -}}
{{- if lt ($objectData.instances | int) 1 -}}
{{- fail (printf "CNPG - Expected [instances] to be greater than 0, but got [%d]" ($objectData.instances | int)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "mode") -}}
{{- $validModes := (list "standalone" "replica" "recovery") -}}
{{- if not (mustHas $objectData.mode $validModes) -}}
{{- fail (printf "CNPG Cluster - Expected [mode] to be one of [%s], but got [%s]" (join ", " $validModes) $objectData.mode) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "type") -}}
{{- $validTypes := (list "postgres" "postgis" "timescaledb" "vectors") -}}
{{- if not (mustHas $objectData.type $validTypes) -}}
{{- fail (printf "CNPG Cluster - Expected [type] to be one of [%s], but got [%s]" (join ", " $validTypes) $objectData.type) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "cluster") -}}
{{- if (hasKey $objectData.cluster "logLevel") -}}
{{- $validLevels := (list "error" "warning" "info" "debug" "trace") -}}
{{- if not (mustHas $objectData.cluster.logLevel $validLevels) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.logLevel] to be one of [%s], but got [%s]" (join ", " $validLevels) $objectData.cluster.logLevel) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "primaryUpdateStrategy") -}}
{{- $validStrategies := (list "supervised" "unsupervised") -}}
{{- if not (mustHas $objectData.cluster.primaryUpdateStrategy $validStrategies) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.primaryUpdateStrategy] to be one of [%s], but got [%s]" (join ", " $validStrategies) $objectData.cluster.primaryUpdateStrategy) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "primaryUpdateMethod") -}}
{{- $validMethods := (list "switchover" "restart") -}}
{{- if not (mustHas $objectData.cluster.primaryUpdateMethod $validMethods) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.primaryUpdateMethod] to be one of [%s], but got [%s]" (join ", " $validMethods) $objectData.cluster.primaryUpdateMethod) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.cluster "initdb") -}}
{{- with $objectData.cluster.initdb.walSegmentSize -}}
{{- if not (mustHas (kindOf .) (list "int" "int64" "float64")) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be an integer, but got [%s]" (kindOf .)) -}}
{{- end -}}
{{- if or (lt (. | int) 1) (gt (. | int) 1024) -}}
{{- fail (printf "CNPG Cluster - Expected [cluster.initdb.walSegmentSize] to be between 1 and 1024, but got [%d]" (. | int)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if eq $objectData.mode "recovery" -}}
{{- if not $objectData.recovery -}}
{{- fail "CNPG Recovery - Expected a non-empty [recovery] key" -}}
{{- end -}}
{{- $validMethods := (list "backup" "object_store" "pg_basebackup") -}}
{{- if not (mustHas $objectData.recovery.method $validMethods) -}}
{{- fail (printf "CNPG Recovery - Expected [recovery.method] to be one of [%s], but got [%s]" (join ", " $validMethods) $objectData.recovery.method) -}}
{{- end -}}
{{- if eq $objectData.recovery.method "backup" -}}
{{- if not $objectData.recovery.backupName -}}
{{- fail "CNPG Recovery - Expected a non-empty [recovery.backupName] key" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and $objectData.recovery $objectData.recovery.revision -}}
{{- if not (kindIs "string" $objectData.recovery.revision) -}}
{{- fail (printf "CNPG Recovery - Expected [recovery.revision] to be a string, got [%s]" (kindOf $objectData.recovery.revision)) -}}
{{- end -}}
{{- end -}}
{{- if and $objectData.backups $objectData.backups.revision -}}
{{- if not (kindIs "string" $objectData.backups.revision) -}}
{{- fail (printf "CNPG Backup - Expected [backups.revision] to be a string, got [%s]" (kindOf $objectData.backups.revision)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData "backups") -}}
{{- if and $objectData.backups.enabled $objectData.backups.target -}}
{{- $validTargets := (list "primary" "prefer-standby") -}}
{{- if not (mustHas $objectData.backups.target $validTargets) -}}
{{- fail (printf "CNPG Backup - Expected [backups.target] to be one of [%s], but got [%s]" (join ", " $validTargets) $objectData.backups.target) -}}
{{- end -}}
{{- $regexPolicy := "^[1-9][0-9]*[dwm]$" -}} {{/* Copied from upstream */}}
{{- if not (mustRegexMatch $regexPolicy $objectData.backups.retentionPolicy) -}}
{{- fail (printf "CNPG Backup - Expected [backups.retentionPolicy] to match regex [%s], got [%s]" $regexPolicy $objectData.backups.retentionPolicy) -}}
{{- end -}}
{{- if eq $objectData.mode "recovery" -}}
{{- $serverNameBackup := $objectData.backups.serverName | default $objectData.clusterName -}}
{{- $serverNameRecovery := $objectData.recovery.serverName | default $objectData.clusterName -}}
{{- if $objectData.backups.revision -}}
{{- $serverNameBackup = printf "%s-r%s" $serverNameBackup $objectData.backups.revision -}}
{{- end -}}
{{- if $objectData.recovery.revision -}}
{{- $serverNameRecovery = printf "%s-r%s" $serverNameRecovery $objectData.recovery.revision -}}
{{- end -}}
{{- if eq $serverNameBackup $serverNameRecovery -}}
{{- if $objectData.backups.serverName -}}
{{- fail (printf "CNPG Backup/Recovery - [backups.serverName] and [backups.revision] cannot match [recovery.serverName] and [recovery.revision] when in recovery mode and backup is enabled, for CNPG cluster [%s]" $objectData.clusterName) -}}
{{- else -}}
{{- fail (printf "CNPG Backup/Recovery - [backups.revision] cannot match [recovery.revision] when in recovery mode and backup is enabled, for CNPG cluster [%s]" $objectData.clusterName) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,41 @@
{{- define "tc.v1.common.lib.cnpg.spawner.pooler" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if not (hasKey $objectData "pooler") -}}
{{- $_ := set $objectData "pooler" dict -}}
{{- end -}}
{{- $monitoring := false -}}
{{- if (hasKey $objectData "monitoring") -}}
{{- if (kindIs "bool" $objectData.monitoring.enablePodMonitor) -}}
{{- $monitoring := $objectData.monitoring.enablePodMonitor -}}
{{- end -}}
{{- end -}}
{{- $_ := set $objectData.pooler "type" "rw" -}}
{{/* Validate Pooler */}}
{{- include "tc.v1.common.lib.cnpg.pooler.validation" (dict "objectData" $objectData) -}}
{{/* Create the RW Pooler object */}}
{{- include "tc.v1.common.class.cnpg.pooler" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- if $monitoring -}} {{/* TODO: Unit tests for Pooler Metrics */}}
{{- $poolerMetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" (printf "%s-rw" $objectData.name)) | fromYaml -}}
{{- $_ := set $.Values.metrics (printf "cnpg-%s-rw" $objectData.shortName) $poolerMetrics -}}
{{- end -}}
{{- if $objectData.pooler.createRO -}}
{{- $_ := set $objectData.pooler "type" "ro" -}}
{{/* Validate Pooler */}}
{{- include "tc.v1.common.lib.cnpg.pooler.validation" (dict "objectData" $objectData) -}}
{{/* Create the RO Pooler object */}}
{{- include "tc.v1.common.class.cnpg.pooler" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- if $monitoring -}} {{/* TODO: Unit tests for Pooler Metrics */}}
{{- $poolerMetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" (printf "%s-rw" $objectData.name)) | fromYaml -}}
{{- $_ := set $.Values.metrics (printf "cnpg-%s-ro" $objectData.shortName) $poolerMetrics -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,21 @@
{{- define "tc.v1.common.lib.cnpg.pooler.validation" -}}
{{- $objectData := .objectData -}}
{{- $validTypes := (list "rw" "ro") -}}
{{- if not (mustHas $objectData.pooler.type $validTypes) -}}
{{- fail (printf "CNPG Pooler - Expected [type] to be one one of [%s], but got [%s]" (join ", " $validTypes) $objectData.pooler.type) -}}
{{- end -}}
{{- if (hasKey $objectData.pooler "instances") -}}
{{- if lt ($objectData.pooler.instances | int) 1 -}}
{{- fail (printf "CNPG Pooler - Expected [instances] to be greater than 0, but got [%d]" ($objectData.instances | int)) -}}
{{- end -}}
{{- end -}}
{{- $validPgModes := (list "session" "transaction") -}}
{{- if $objectData.pooler.poolMode -}}
{{- if not (mustHas $objectData.pooler.poolMode $validPgModes) -}}
{{- fail (printf "CNPG Pooler - Expected [poolMode] to be one of [%s], but got [%s]" (join ", " $validPgModes) $objectData.pooler.poolMode) -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,33 @@
{{- define "tc.v1.common.lib.cnpg.provider.secret.spawner" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $type := .type -}}
{{- if not $type -}}
{{- fail "CNPG Provider Secret Spawner - No [type] was given" -}}
{{- end -}}
{{- $provider := "" -}}
{{- $creds := dict -}}
{{- if eq $type "backup" -}}
{{- if not $objectData.backups.credentials -}}
{{- fail "CNPG Recovery Provider Secret Spawner - Expected [backups.credentials] to be defined on [backup] mode" -}}
{{- end -}}
{{/* Get the creds defined in backup.$provider */}}
{{- $creds = (get $rootCtx.Values.credentials $objectData.backups.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG Backup" "credName" $objectData.backups.credentials) -}}
{{- $provider = $creds.type -}}
{{- else if eq $type "recovery" -}}
{{- if not $objectData.recovery.credentials -}}
{{- fail "CNPG Recovery Provider Secret Spawner - Expected [recovery.credentials] to be defined on [recovery] mode" -}}
{{- end -}}
{{/* Get the creds defined in recovery.$provider */}}
{{- $creds = (get $rootCtx.Values.credentials $objectData.recovery.credentials) -}}
{{- include "tc.v1.common.lib.credentials.validation" (dict "rootCtx" $rootCtx "caller" "CNPG Backup" "credName" $objectData.recovery.credentials) -}}
{{- $provider = $creds.type -}}
{{- end -}}
{{- with (include (printf "tc.v1.common.lib.cnpg.provider.%s.secret" $provider) (dict "creds" $creds) | fromYaml) -}}
{{- $_ := set $rootCtx.Values.secret (printf "cnpg-%s-provider-%s-%s-creds" $objectData.shortName $type $provider) . -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,7 @@
{{- define "tc.v1.common.lib.cnpg.provider.s3.secret" -}}
{{- $creds := .creds }}
enabled: true
data:
ACCESS_KEY_ID: {{ $creds.accessKey | default "" | quote }}
ACCESS_SECRET_KEY: {{ $creds.secretKey | default "" | quote }}
{{- end -}}
@@ -0,0 +1,18 @@
{{- define "tc.v1.common.lib.cnpg.spawner.scheduledBackups" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- range $schedBackup := $objectData.backups.scheduledBackups -}}
{{- $_ := set $objectData "backupName" $schedBackup.name -}}
{{- $_ := set $objectData "backupLabels" $schedBackup.labels -}}
{{- $_ := set $objectData "backupAnnotations" $schedBackup.annotations -}}
{{/* Make a copy of the objectData */}}
{{- $newObjectData := mustDeepCopy $objectData -}}
{{/* Add the scheduled backup data */}}
{{- $_ := set $newObjectData "schedData" $schedBackup -}}
{{- include "tc.v1.common.lib.cnpg.scheduledBackup.validation" (dict "objectData" $newObjectData) }}
{{- include "tc.v1.common.class.cnpg.scheduledbackup" (dict "rootCtx" $rootCtx "objectData" $newObjectData) -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,30 @@
{{- define "tc.v1.common.lib.cnpg.scheduledBackup.validation" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.backupName -}}
{{- fail "CNPG Scheduled Backup - Expected non-empty [name] in [backups.scheduledBackups] entry" -}}
{{- end -}}
{{- if not $objectData.schedData.schedule -}}
{{- fail "CNPG Scheduled Backup - Expected non-empty [schedule] in [backups.scheduledBackups] entry" -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "backupOwnerReference") -}}
{{- $validOwnerRefs := (list "none" "self" "cluster") -}}
{{- if not (mustHas $objectData.schedData.backupOwnerReference $validOwnerRefs) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [backupOwnerReference] in [backups.scheduledBackups] entry to be one of [%s], but got [%s]" (join ", " $validOwnerRefs) $objectData.schedData.backupOwnerReference) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "immediate") -}}
{{- if not (kindIs "bool" $objectData.schedData.immediate) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [immediate] in [backups.scheduledBackups] entry to be a boolean, but got [%s]" (kindOf $objectData.schedData.immediate)) -}}
{{- end -}}
{{- end -}}
{{- if (hasKey $objectData.schedData "suspend") -}}
{{- if not (kindIs "bool" $objectData.schedData.suspend) -}}
{{- fail (printf "CNPG Scheduled Backup - Expected [suspend] in [backups.scheduledBackups] entry to be a boolean, but got [%s]" (kindOf $objectData.schedData.suspend)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,21 @@
{{/* Configmap Validation */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.configmap.validation" (dict "objectData" $objectData) -}}
objectData:
labels: The labels of the configmap.
annotations: The annotations of the configmap.
data: The data of the configmap.
*/}}
{{- define "tc.v1.common.lib.configmap.validation" -}}
{{- $objectData := .objectData -}}
{{- if not $objectData.data -}}
{{- fail "ConfigMap - Expected non-empty [data]" -}}
{{- end -}}
{{- if not (kindIs "map" $objectData.data) -}}
{{- fail (printf "ConfigMap - Expected [data] to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,22 @@
{{/* Returns args list */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.args" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.args" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $key := (list "args" "extraArgs") -}}
{{- with (get $objectData $key) -}}
{{- if kindIs "string" . }}
- {{ tpl . $rootCtx | quote }}
{{- else if kindIs "slice" . -}}
{{- range $arg := . }}
- {{ tpl $arg $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,18 @@
{{/* Returns command list */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.command" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.command" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if kindIs "string" $objectData.command }}
- {{ tpl $objectData.command $rootCtx | quote }}
{{- else if kindIs "slice" $objectData.command -}}
{{- range $objectData.command }}
- {{ tpl . $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,93 @@
{{/* Returns Env */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.env" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.env" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $k, $v := $objectData.env -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "env" "key" $k) }}
- name: {{ $k | quote }}
{{- if not (kindIs "map" $v) -}}
{{- $value := "" -}}
{{- if not (kindIs "invalid" $v) -}} {{/* Only tpl non-empty values */}}
{{- $value = $v -}}
{{- if kindIs "string" $v -}}
{{- $value = tpl $v $rootCtx -}}
{{- end -}}
{{- end }}
value: {{ include "tc.v1.common.helper.makeIntOrNoop" $value | quote }}
{{- else if kindIs "map" $v }}
valueFrom:
{{- $refs := (list "configMapKeyRef" "secretKeyRef" "fieldRef") -}}
{{- if or (ne (len ($v | keys)) 1) (not (mustHas ($v | keys | first) $refs)) -}}
{{- fail (printf "Container - Expected [env] with a ref to have one of [%s], but got [%s]" (join ", " $refs) (join ", " ($v | keys | sortAlpha))) -}}
{{- end -}}
{{- $name := "" -}}
{{- range $key := (list "configMapKeyRef" "secretKeyRef") -}}
{{- if hasKey $v $key }}
{{ $key }}:
{{- $obj := get $v $key -}}
{{- if not $obj.name -}}
{{- fail (printf "Container - Expected non-empty [env.%s.name]" $key) -}}
{{- end -}}
{{- if not $obj.key -}}
{{- fail (printf "Container - Expected non-empty [env.%s.key]" $key) -}}
{{- end }}
key: {{ $obj.key | quote }}
{{- $name = tpl $obj.name $rootCtx -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" $obj
"name" $k "caller" "Container"
"key" "env")) -}}
{{- if eq $expandName "true" -}}
{{- $item := ($key | trimSuffix "KeyRef" | lower) -}}
{{- $data := (get $rootCtx.Values $item) -}}
{{- $data = (get $data $name) -}}
{{- if not $data -}}
{{- fail (printf "Container - Expected in [env] the referenced %s [%s] to be defined" ($item | camelcase | title) $name) -}}
{{- end -}}
{{- $found := false -}}
{{- range $k, $v := $data.data -}}
{{- if eq $k $obj.key -}}
{{- $found = true -}}
{{- end -}}
{{- end -}}
{{- if not $found -}}
{{- fail (printf "Container - Expected in [env] the referenced key [%s] in %s [%s] to be defined" $obj.key ($item | camelcase | title) $name) -}}
{{- end -}}
{{- $name = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}}
{{- end }}
name: {{ $name | quote }}
{{- end -}}
{{- end -}}
{{- if hasKey $v "fieldRef" }}
fieldRef:
{{- if not $v.fieldRef.fieldPath -}}
{{- fail "Container - Expected non-empty [env.fieldRef.fieldPath]" -}}
{{- end }}
fieldPath: {{ $v.fieldRef.fieldPath | quote }}
{{- if $v.fieldRef.apiVersion }}
apiVersion: {{ $v.fieldRef.apiVersion | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,59 @@
{{/* Returns Env From */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.envFrom" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.envFrom" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $refs := (list "configMapRef" "secretRef") -}}
{{- range $envFrom := $objectData.envFrom -}}
{{- if and (not $envFrom.secretRef) (not $envFrom.configMapRef) -}}
{{- fail (printf "Container - Expected [envFrom] entry to have one of [%s]" (join ", " $refs)) -}}
{{- end -}}
{{- if and $envFrom.secretRef $envFrom.configMapRef -}}
{{- fail (printf "Container - Expected [envFrom] entry to have only one of [%s], but got both" (join ", " $refs)) -}}
{{- end -}}
{{- range $ref := $refs -}}
{{- with (get $envFrom $ref) -}}
{{- if not .name -}}
{{- fail (printf "Container - Expected non-empty [envFrom.%s.name]" $ref) -}}
{{- end -}}
{{- $objectName := tpl .name $rootCtx -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" .
"name" $ref "caller" "Container"
"key" "envFrom")) -}}
{{- if eq $expandName "true" -}}
{{- $object := dict -}}
{{- $source := "" -}}
{{- if eq $ref "configMapRef" -}}
{{- $object = (get $rootCtx.Values.configmap $objectName) -}}
{{- $source = "ConfigMap" -}}
{{- else if eq $ref "secretRef" -}}
{{- $object = (get $rootCtx.Values.secret $objectName) -}}
{{- $source = "Secret" -}}
{{- end -}}
{{- if not $object -}}
{{- fail (printf "Container - Expected %s [%s] defined in [envFrom] to exist" $source $objectName) -}}
{{- end -}}
{{- range $k, $v := $object.data -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s - %s" $source $objectName) "key" $k) -}}
{{- end -}}
{{- $objectName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectName) -}}
{{- end }}
- {{ $ref }}:
name: {{ $objectName | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,23 @@
{{/* Returns Env List */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.envList" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.envList" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $env := $objectData.envList -}}
{{- if not $env.name -}}
{{- fail "Container - Expected non-empty [envList.name]" -}}
{{- end -}} {{/* Empty value is valid */}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "envList" "key" $env.name) -}}
{{- $value := $env.value -}}
{{- if kindIs "string" $env.value -}}
{{- $value = tpl $env.value $rootCtx -}}
{{- end }}
- name: {{ $env.name | quote }}
value: {{ include "tc.v1.common.helper.makeIntOrNoop" $value | quote }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,97 @@
{{/* Returns Fixed Env */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.fixedEnv" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.fixedEnv" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Avoid nil pointers */}}
{{- if not (hasKey $objectData "fixedEnv") -}}
{{- $_ := set $objectData "fixedEnv" dict -}}
{{- end -}}
{{- $nvidiaCaps := $rootCtx.Values.containerOptions.NVIDIA_CAPS -}}
{{- if $objectData.fixedEnv.NVIDIA_CAPS -}}
{{- $nvidiaCaps = $objectData.fixedEnv.NVIDIA_CAPS -}}
{{- end -}}
{{- if not (deepEqual $nvidiaCaps (mustUniq $nvidiaCaps)) -}}
{{- fail (printf "Container - Expected [fixedEnv.NVIDIA_CAPS] to have only unique values, but got [%s]" (join ", " $nvidiaCaps)) -}}
{{- end -}}
{{- $caps := (list "all" "compute" "utility" "graphics" "video") -}}
{{- range $cap := $nvidiaCaps -}}
{{- if not (mustHas $cap $caps) -}}
{{- fail (printf "Container - Expected [fixedEnv.NVIDIA_CAPS] entry to be one of [%s], but got [%s]" (join ", " $caps) $cap) -}}
{{- end -}}
{{- end -}}
{{- $secContext := fromJson (include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $rootCtx "objectData" $objectData)) -}}
{{- $fixed := list -}}
{{- $TZ := $objectData.fixedEnv.TZ | default $rootCtx.Values.TZ -}}
{{- $UMASK := $objectData.fixedEnv.UMASK | default $rootCtx.Values.securityContext.container.UMASK -}}
{{- $PUID := $objectData.fixedEnv.PUID | default $rootCtx.Values.securityContext.container.PUID -}}
{{- if and (not (kindIs "invalid" $objectData.fixedEnv.PUID)) (eq (int $objectData.fixedEnv.PUID) 0) -}}
{{- $PUID = $objectData.fixedEnv.PUID -}}
{{- end -}}
{{/* calculatedFSGroup is passed from the pod */}}
{{- $PGID := $objectData.calculatedFSGroup -}}
{{- $fixed = mustAppend $fixed (dict "k" "TZ" "v" $TZ) -}}
{{- $fixed = mustAppend $fixed (dict "k" "UMASK" "v" $UMASK) -}}
{{- $fixed = mustAppend $fixed (dict "k" "UMASK_SET" "v" $UMASK) -}}
{{- $nvidia := false -}}
{{- if eq (include "tc.v1.common.lib.container.resources.hasGPU" (dict "rootCtx" $rootCtx "objectData" $objectData "gpuType" "nvidia.com/gpu")) "true" -}}
{{- $nvidia = true -}}
{{- end -}}
{{- if and ($rootCtx.Values.resources) ($rootCtx.Values.resources.limits) -}}
{{- range $k, $v := $rootCtx.Values.resources.limits -}}
{{- if and (eq $k "nvidia.com/gpu") (gt ($v | int) 0) -}}
{{- $nvidia = true -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and ($objectData.resources) ($objectData.resources.limits) -}}
{{- range $k, $v := $objectData.resources.limits -}}
{{- if and (eq $k "nvidia.com/gpu") (gt ($v | int) 0) -}}
{{- $nvidia = true -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $nvidia -}}
{{- $fixed = mustAppend $fixed (dict "k" "NVIDIA_DRIVER_CAPABILITIES" "v" (join "," $nvidiaCaps)) -}}
{{- else -}}
{{- $fixed = mustAppend $fixed (dict "k" "NVIDIA_VISIBLE_DEVICES" "v" "void") -}}
{{- end -}}
{{/* If running as root and PUID is set (0 or greater), set related envs */}}
{{- if and (or (eq (int $secContext.runAsUser) 0) (eq (int $secContext.runAsGroup) 0)) (ge (int $PUID) 0) -}}
{{- $fixed = mustAppend $fixed (dict "k" "PUID" "v" $PUID) -}}
{{- $fixed = mustAppend $fixed (dict "k" "USER_ID" "v" $PUID) -}}
{{- $fixed = mustAppend $fixed (dict "k" "UID" "v" $PUID) -}}
{{- $fixed = mustAppend $fixed (dict "k" "PGID" "v" $PGID) -}}
{{- $fixed = mustAppend $fixed (dict "k" "GROUP_ID" "v" $PGID) -}}
{{- $fixed = mustAppend $fixed (dict "k" "GID" "v" $PGID) -}}
{{- end -}}
{{/* If rootFS is readOnly OR does not as root, let s6 containers to know that fs is readonly */}}
{{- if or $secContext.readOnlyRootFilesystem $secContext.runAsNonRoot -}}
{{- $fixed = mustAppend $fixed (dict "k" "S6_READ_ONLY_ROOT" "v" "1") -}}
{{- end -}}
{{- range $env := $fixed -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "fixedEnv" "key" $env.k) }}
- name: {{ $env.k | quote }}
value: {{ (include "tc.v1.common.helper.makeIntOrNoop" $env.v) | quote }}
{{- end -}}
{{- end -}}
@@ -0,0 +1,42 @@
{{/* Returns the image dictionary */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.imageSelector" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.imageSelector" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $imageObj := dict -}}
{{- $selector := "image" -}}
{{- with $objectData.imageSelector -}}
{{- $selector = tpl . $rootCtx -}}
{{- end -}}
{{- if hasKey $rootCtx.Values $selector -}}
{{- $imageObj = get $rootCtx.Values $selector -}}
{{- else -}}
{{- fail (printf "Container - Expected [.Values.%s] to exist" $selector) -}}
{{- end -}}
{{- if not $imageObj.repository -}}
{{- fail (printf "Container - Expected non-empty [.Values.%s.repository]" $selector) -}}
{{- end -}}
{{- if not $imageObj.tag -}}
{{- fail (printf "Container - Expected non-empty [.Values.%s.tag]" $selector) -}}
{{- end -}}
{{- if not $imageObj.pullPolicy -}}
{{- $_ := set $imageObj "pullPolicy" "IfNotPresent" -}}
{{- end -}}
{{- $policies := (list "IfNotPresent" "Always" "Never") -}}
{{- if not (mustHas $imageObj.pullPolicy $policies) -}}
{{- fail (printf "Container - Expected [.Values.%s.pullPolicy] to be one of [%s], but got [%s]" $selector (join ", " $policies) $imageObj.pullPolicy) -}}
{{- end -}}
{{- $imageObj | toJson -}}
{{- end -}}
@@ -0,0 +1,37 @@
{{/* Returns lifecycle */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.lifecycle" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.lifecycle" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $hooks := (list "preStop" "postStart") -}}
{{- $types := (list "exec" "http" "https") -}}
{{- with $objectData.lifecycle -}}
{{- range $hook, $hookValues := . -}}
{{- if not (mustHas $hook $hooks) -}}
{{- fail (printf "Container - Expected [lifecycle] [hook] to be one of [%s], but got [%s]" (join ", " $hooks) $hook) -}}
{{- end -}}
{{- if not $hookValues.type -}}
{{- fail "Container - Expected non-empty [lifecycle] [type]" -}}
{{- end -}}
{{- if not (mustHas $hookValues.type $types) -}}
{{- fail (printf "Container - Expected [lifecycle] [type] to be one of [%s], but got [%s]" (join ", " $types) $hookValues.type) -}}
{{- end }}
{{ $hook }}:
{{- if eq $hookValues.type "exec" -}}
{{- include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $rootCtx "objectData" $hookValues "caller" "lifecycle") | trim | nindent 2 -}}
{{- else if mustHas $hookValues.type (list "http" "https") -}}
{{- include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $rootCtx "objectData" $hookValues "caller" "lifecycle") | trim | nindent 2 -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,87 @@
{{/* Returns ports list */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.ports" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.ports" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- range $serviceName, $serviceValues := $rootCtx.Values.service -}}
{{- $podSelected := false -}}
{{/* If service is enabled... */}}
{{- if $serviceValues.enabled -}}
{{/* If there is a selector */}}
{{- if $serviceValues.targetSelector -}}
{{/* And pod is selected */}}
{{- if eq $serviceValues.targetSelector $objectData.podShortName -}}
{{- $podSelected = true -}}
{{- end -}}
{{- else -}}
{{/* If no selector is defined but pod is primary */}}
{{- if $objectData.podPrimary -}}
{{- $podSelected = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $podSelected -}}
{{- range $portName, $portValues := $serviceValues.ports -}}
{{- $containerSelected := false -}}
{{/* If service is enabled... */}}
{{- if $portValues.enabled -}}
{{/* If there is a selector */}}
{{- if $portValues.targetSelector -}}
{{/* And container is selected */}}
{{- if eq $portValues.targetSelector $objectData.shortName -}}
{{- $containerSelected = true -}}
{{- end -}}
{{- else -}}
{{/* If no selector is defined but container is primary */}}
{{- if $objectData.primary -}}
{{- $containerSelected = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* If the container is selected render port */}}
{{- if $containerSelected -}}
{{- $containerPort := $portValues.targetPort | default $portValues.port -}}
{{- if kindIs "string" $containerPort -}}
{{- $containerPort = (tpl $containerPort $rootCtx) -}}
{{- end -}}
{{- $tcpProtocols := (list "tcp" "http" "https") -}}
{{- $protocol := tpl ($portValues.protocol | default $rootCtx.Values.global.fallbackDefaults.serviceProtocol) $rootCtx -}}
{{- if mustHas $protocol $tcpProtocols -}}
{{- $protocol = "tcp" -}}
{{- end }}
- name: {{ $portName }}
containerPort: {{ $containerPort }}
protocol: {{ $protocol | upper }}
{{- with $portValues.hostPort }}
hostPort: {{ . }}
{{- else }}
hostPort: null
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Turning hostNetwork on, it creates hostPort automatically and turning it back off does not remove them. Setting hostPort explicitly to null will remove them.
There are still cases that hostPort is not removed, for example, if you have a TCP and UDP port with the same number. Only the TCPs hostPort will be removed.
Also note that setting hostPort to null always, it will NOT affect hostNetwork, as it will still create the hostPorts.
It only helps to remove them when hostNetwork is turned off.
*/}}
@@ -0,0 +1,40 @@
{{/* Containers Basic Validation */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.primaryValidation" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
*/}}
{{- define "tc.v1.common.lib.container.primaryValidation" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{/* Initialize values */}}
{{- $hasPrimary := false -}}
{{- $hasEnabled := false -}}
{{/* Go over the contaienrs */}}
{{- range $name, $container := $objectData.podSpec.containers -}}
{{/* If container is enabled */}}
{{- if $container.enabled -}}
{{- $hasEnabled = true -}}
{{/* And container is primary */}}
{{- if and (hasKey $container "primary") ($container.primary) -}}
{{/* Fail if there is already a primary container */}}
{{- if $hasPrimary -}}
{{- fail "Container - Only one container can be primary per workload" -}}
{{- end -}}
{{- $hasPrimary = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Require at least one primary container, if any enabled */}}
{{- if and $hasEnabled (not $hasPrimary) -}}
{{- fail "Container - At least one enabled container must be primary per workload" -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,105 @@
{{/* Returns Probes */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.probes" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.probes" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $probeNames := (list "liveness" "readiness" "startup") -}}
{{- $probeTypes := (list "http" "https" "tcp" "grpc" "exec") -}}
{{- if not $objectData.probes -}}
{{- fail "Container - Expected non-empty [probes]" -}}
{{- end -}}
{{- range $key := $probeNames -}}
{{- if not (get $objectData.probes $key) -}}
{{- fail (printf "Container - Expected [probes.%s] to be defined" $key) -}}
{{- end -}}
{{- end -}}
{{- $probes := $objectData.probes -}}
{{- $diagMode := eq (include "tc.v1.common.lib.util.diagnosticMode" (dict "rootCtx" $rootCtx)) "true" -}}
{{- if $diagMode -}}
{{- $probes = dict -}}
{{- end -}}
{{- range $probeName, $probe := $probes -}}
{{- if not (mustHas $probeName $probeNames) -}}
{{- fail (printf "Container - Expected probe to be one of [%s], but got [%s]" (join ", " $probeNames) $probeName) -}}
{{- end -}}
{{- $isEnabled := true -}}
{{- if kindIs "bool" $probe.enabled -}}
{{- $isEnabled = $probe.enabled -}}
{{- end -}}
{{- if $isEnabled -}}
{{- $probeType := $rootCtx.Values.global.fallbackDefaults.probeType -}}
{{- with $probe.type -}}
{{- $probeType = tpl . $rootCtx -}}
{{- end -}}
{{- if not (mustHas $probeType $probeTypes) -}}
{{- fail (printf "Container - Expected probe type to be one of [%s], but got [%s]" (join ", " $probeTypes) $probeType) -}}
{{- end }}
{{ $probeName }}Probe:
{{- if (mustHas $probeType (list "http" "https")) -}}
{{- include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}}
{{- else if eq $probeType "tcp" -}}
{{- include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}}
{{- else if eq $probeType "grpc" -}}
{{- include "tc.v1.common.lib.container.actions.grpc" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}}
{{- else if eq $probeType "exec" -}}
{{- include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}}
{{- end -}}
{{- include "tc.v1.common.lib.container.probeTimeouts" (dict "rootCtx" $rootCtx "objectData" $probe "probeName" $probeName) | trim | nindent 2 -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Returns Probe Timeouts */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.probeTimeouts" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.probeTimeouts" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $probeName := .probeName -}}
{{- $timeouts := mustDeepCopy (get $rootCtx.Values.global.fallbackDefaults.probeTimeouts $probeName) -}}
{{- if $objectData.spec -}} {{/* Overwrite with defined timeouts */}}
{{- $timeouts = mustMergeOverwrite $timeouts $objectData.spec -}}
{{- end -}}
{{- $keys := (list "initialDelaySeconds" "failureThreshold" "successThreshold" "timeoutSeconds" "periodSeconds") -}}
{{- range $key := $keys -}}
{{- $number := get $timeouts $key -}}
{{- if not (mustHas (kindOf $number) (list "float64" "int" "int64")) -}}
{{- fail (printf "Container - Expected [probes] [%s] to be a number, but got [%v]" $key $number) -}}
{{- end -}}
{{- end -}}
{{- if mustHas $probeName (list "liveness" "startup") -}}
{{- if ne (int $timeouts.successThreshold) 1 -}}
{{- fail (printf "Container - Expected [probes] [successThreshold] to be 1 on [%s] probe" $probeName) -}}
{{- end -}}
{{- end }}
initialDelaySeconds: {{ $timeouts.initialDelaySeconds }}
failureThreshold: {{ $timeouts.failureThreshold }}
successThreshold: {{ $timeouts.successThreshold }}
timeoutSeconds: {{ $timeouts.timeoutSeconds }}
periodSeconds: {{ $timeouts.periodSeconds }}
{{- end -}}
@@ -0,0 +1,151 @@
{{/* Returns Resources */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.resources" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.resources" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $resources := mustDeepCopy $rootCtx.Values.resources -}}
{{- if $objectData.resources -}}
{{- $resources = mustMergeOverwrite $resources $objectData.resources -}}
{{- end -}}
{{/* We use the objectData instead of $resources,
as we only allow this flag on the container level */}}
{{- if not (hasKey $objectData "resources") -}}
{{- $_ := set $objectData "resources" dict -}}
{{- end -}}
{{- if not (hasKey $objectData.resources "excludeExtra") -}}
{{- $_ := set $objectData.resources "excludeExtra" false -}}
{{- end -}}
{{- include "tc.v1.common.lib.container.resources.validation" (dict "resources" $resources) }}
requests:
cpu: {{ $resources.requests.cpu }}
memory: {{ $resources.requests.memory }}
{{- if $resources.limits }}
limits:
{{- with $resources.limits.cpu }} {{/* Passing 0, will not render it, meaning unlimited */}}
cpu: {{ . }}
{{- end -}}
{{- with $resources.limits.memory }} {{/* Passing 0, will not render it, meaning unlimited */}}
memory: {{ . }}
{{- end -}}
{{- if not $objectData.resources.excludeExtra -}}
{{- range $k, $v := (omit $resources.limits "cpu" "memory") }} {{/* Omit cpu and memory, as they are handled above */}}
{{- if or (not $v) (eq (toString $v) "0") -}}
{{ continue }}
{{- end }}
{{ $k }}: {{ $v }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Validates resources to match a pattern */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.resources.validation" (dict "resources" $resources) }}
rootCtx: The root context of the chart.
resources: The resources object
*/}}
{{- define "tc.v1.common.lib.container.resources.validation" -}}
{{- $resources := .resources -}}
{{/* CPU: https://regex101.com/r/D4HouI/1 */}}
{{/* MEM: https://regex101.com/r/NNPV2D/1 */}}
{{- $regex := (dict
"cpu" "^(0\\.[1-9]|[1-9][0-9]*)(\\.[0-9]|m?)$"
"memory" "^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$") -}}
{{- $errorMsg := (dict
"cpu" "(Plain Integer - eg. 1), (Float - eg. 0.5), (Milicpu - eg. 500m)"
"memory" "(Suffixed with E/P/T/G/M/K - eg. 1G), (Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi), (Plain Integer in bytes - eg. 1024), (Exponent - eg. 134e6)") -}}
{{- $resourceTypes := (list "cpu" "memory") -}}
{{- range $category := (list "requests") -}} {{/* We can also add "limits" here if we want to require them */}}
{{- if not (get $resources $category) -}}
{{- fail (printf "Container - Expected non-empty [resources.%s]" $category) -}}
{{- end -}}
{{- range $type := $resourceTypes -}}
{{- if not (get (get $resources $category) $type) -}}
{{- fail (printf "Container - Expected non-empty [resources.%s.%s]" $category $type) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- range $key := (list "requests" "limits") -}}
{{- $resourceCategory := (get $resources $key) -}}
{{- if $resourceCategory -}}
{{- range $type := $resourceTypes -}}
{{- $resourceValue := (get $resourceCategory $type) -}}
{{- if $resourceValue -}} {{/* Only try to match defined values */}}
{{- if not (mustRegexMatch (get $regex $type) (toString $resourceValue)) -}}
{{- fail (printf "Container - Expected [resources.%s.%s] to have one of the following formats [%s], but got [%s]" $key $type (get $errorMsg $type) $resourceValue) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.pod.resources.hasGPU" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $gpuType := .gpuType -}}
{{- $types := (list "nvidia.com/gpu" "amd.com/gpu" "gpu.intel.com/i915") -}}
{{- if $gpuType -}}
{{- $types = (list $gpuType) -}}
{{- end -}}
{{- $gpu := false -}}
{{- if and ($rootCtx.Values.resources) ($rootCtx.Values.resources.limits) -}}
{{- range $t := $types -}}
{{- if gt ((get $rootCtx.Values.resources.limits $t) | int) 0 -}}
{{- $gpu = true -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if $objectData.podSpec -}}
{{- range $k, $v := $objectData.podSpec.containers -}}
{{- if not $v.enabled -}}
{{- continue -}}
{{- end -}}
{{- range $t := $types -}}
{{- if eq (include "tc.v1.common.lib.container.resources.hasGPU" (dict "rootCtx" $rootCtx "objectData" $v "gpuType" $t)) "true" -}}
{{- $gpu = true -}}
{{- break -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $gpu | toString -}}
{{- end -}}
{{- define "tc.v1.common.lib.container.resources.hasGPU" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $gpuType := .gpuType -}}
{{- $gpu := false -}}
{{- if and ($objectData.resources) ($objectData.resources.limits) -}}
{{- if gt ((get $objectData.resources.limits $gpuType) | int) 0 -}}
{{- $gpu = true -}}
{{- end -}}
{{- end -}}
{{- $gpu | toString -}}
{{- end -}}
@@ -0,0 +1,185 @@
{{/* Returns Container Security Context */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.securityContext" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.securityContext" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Initialize from the "global" options */}}
{{- $secContext := fromJson (include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $rootCtx "objectData" $objectData)) }}
runAsNonRoot: {{ $secContext.runAsNonRoot }}
runAsUser: {{ $secContext.runAsUser }}
runAsGroup: {{ $secContext.runAsGroup }}
readOnlyRootFilesystem: {{ $secContext.readOnlyRootFilesystem }}
allowPrivilegeEscalation: {{ $secContext.allowPrivilegeEscalation }}
privileged: {{ $secContext.privileged }}
seccompProfile:
type: {{ $secContext.seccompProfile.type }}
{{- if eq $secContext.seccompProfile.type "Localhost" }}
localhostProfile: {{ $secContext.seccompProfile.profile }}
{{- end }}
capabilities:
{{- if $secContext.capabilities.add }}
add:
{{- range $secContext.capabilities.add }}
- {{ . }}
{{- end -}}
{{- else }}
add: []
{{- end -}}
{{- if $secContext.capabilities.drop }}
drop:
{{- range $secContext.capabilities.drop }}
- {{ . }}
{{- end -}}
{{- else }}
drop: []
{{- end -}}
{{- end -}}
{{/* Calculates Container Security Context */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.securityContext.calculate" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $mustPrivileged := false -}}
{{- range $persistenceName, $persistenceValues := $rootCtx.Values.persistence -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $rootCtx "objectData" $persistenceValues
"name" $persistenceName "caller" "Security Context"
"key" "persistence")) -}}
{{- if (eq $enabled "true") -}}
{{- if eq $persistenceValues.type "device" -}}
{{- $volume := (fromJson (include "tc.v1.common.lib.container.volumeMount.isSelected" (dict "persistenceName" $persistenceName "persistenceValues" $persistenceValues "objectData" $objectData "key" "persistence"))) -}}
{{- if $volume -}} {{/* If a volume is returned, it means that the container has an assigned device */}}
{{- $mustPrivileged = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $rootCtx.Values.securityContext.container -}}
{{- fail "Container - Expected non-empty [.Values.securityContext.container]" -}}
{{- end -}}
{{/* Initialize from the "global" options */}}
{{- $secContext := mustDeepCopy $rootCtx.Values.securityContext.container -}}
{{/* Override with containers options */}}
{{- with $objectData.securityContext -}}
{{- $secContext = mustMergeOverwrite $secContext . -}}
{{- end -}}
{{/* Validations, as we might endup with null values after merge */}}
{{- range $key := (list "runAsUser" "runAsGroup") -}}
{{- $value := (get $secContext $key) -}}
{{- if not (mustHas (kindOf $value) (list "float64" "int" "int64")) -}}
{{- fail (printf "Container - Expected [securityContext.%s] to be [int], but got [%v] of type [%s]" $key $value (kindOf $value)) -}}
{{- end -}}
{{- end -}}
{{- if or (eq (int $secContext.runAsUser) 0) (eq (int $secContext.runAsGroup) 0) -}}
{{- $_ := set $secContext "runAsNonRoot" false -}}
{{- else -}}
{{- $_ := set $secContext "runAsNonRoot" true -}}
{{- end -}}
{{- if $secContext.privileged -}} {{/* When privileged is true, allowPrivilegeEscalation is required */}}
{{- $_ := set $secContext "allowPrivilegeEscalation" true -}}
{{- end -}}
{{- if $mustPrivileged -}}
{{- $_ := set $secContext "privileged" true -}}
{{- $_ := set $secContext "allowPrivilegeEscalation" true -}}
{{- $_ := set $secContext "runAsNonRoot" false -}}
{{- $_ := set $secContext "runAsUser" 0 -}}
{{- $_ := set $secContext "runAsGroup" 0 -}}
{{- end -}}
{{- range $key := (list "privileged" "allowPrivilegeEscalation" "runAsNonRoot" "readOnlyRootFilesystem") -}}
{{- $value := (get $secContext $key) -}}
{{- if not (kindIs "bool" $value) -}}
{{- fail (printf "Container - Expected [securityContext.%s] to be [bool], but got [%s] of type [%s]" $key $value (kindOf $value)) -}}
{{- end -}}
{{- end -}}
{{- if not $secContext.seccompProfile -}}
{{- fail "Container - Expected [securityContext.seccompProfile] to be defined" -}}
{{- end -}}
{{- $profiles := (list "RuntimeDefault" "Localhost" "Unconfined") -}}
{{- if not (mustHas $secContext.seccompProfile.type $profiles) -}}
{{- fail (printf "Container - Expected [securityContext.seccompProfile] to be one of [%s], but got [%s]" (join ", " $profiles) $secContext.seccompProfile.type) -}}
{{- end -}}
{{- if eq $secContext.seccompProfile.type "Localhost" -}}
{{- if not $secContext.seccompProfile.profile -}}
{{- fail "Container - Expected [securityContext.seccompProfile.profile] to be defined on type [Localhost]" -}}
{{- end -}}
{{- end -}}
{{- if not $secContext.capabilities -}}
{{- fail "Container - Expected [securityContext.capabilities] to be defined" -}}
{{- end -}}
{{- $tempObjectData := (dict "shortName" $objectData.podShortName "primary" $objectData.podPrimary) -}}
{{- $portRange := fromJson (include "tc.v1.common.lib.helpers.securityContext.getPortRange" (dict "rootCtx" $rootCtx "objectData" $tempObjectData)) -}}
{{- if and $portRange.low (le (int $portRange.low) 1024) -}} {{/* If a container wants to bind a port <= 1024 add NET_BIND_SERVICE */}}
{{- $addCap := $secContext.capabilities.add -}}
{{- if not (mustHas "NET_BIND_SERIVCE" $addCap) -}}
{{- $addCap = mustAppend $addCap "NET_BIND_SERVICE" -}}
{{- end -}}
{{- $_ := set $secContext.capabilities "add" $addCap -}}
{{- end -}}
{{/*
Most containers that run as root, is because it has to chown
files before switching to another user.
Lets add automatically the CHOWN cap.
*/}}
{{- if eq (int $secContext.runAsUser) 0 -}}
{{- if not (kindIs "bool" $secContext.capabilities.disableS6Caps) -}}
{{- fail (printf "Container - Expected [securityContext.capabilities.disableS6Caps] to be [bool], but got [%s] of type [%s]" $secContext.capabilities.disableS6Caps (kindOf $secContext.capabilities.disableS6Caps)) -}}
{{- end -}}
{{- $addCap := $secContext.capabilities.add -}}
{{- if not $secContext.capabilities.disableS6Caps -}}
{{- $addCap = mustAppend $addCap "CHOWN" -}}
{{- $addCap = mustAppend $addCap "SETUID" -}}
{{- $addCap = mustAppend $addCap "SETGID" -}}
{{- $addCap = mustAppend $addCap "FOWNER" -}}
{{- $addCap = mustAppend $addCap "DAC_OVERRIDE" -}}
{{- end -}}
{{- $_ := set $secContext.capabilities "add" $addCap -}}
{{- end -}}
{{- range $key := (list "add" "drop") -}}
{{- $item := (get $secContext.capabilities $key) -}}
{{- if not (kindIs "slice" $item) -}}
{{- fail (printf "Container - Expected [securityContext.capabilities.%s] to be [list], but got [%s]" $key (kindOf $item)) -}}
{{- end -}}
{{- range $item -}}
{{- if not (kindIs "string" .) -}}
{{- fail (printf "Container - Expected items of [securityContext.capabilities.%s] to be [string], but got [%s]" $key (kindOf .)) -}}
{{- end -}}
{{- end -}}
{{- if not (deepEqual (mustUniq $item) $item) -}}
{{- fail (printf "Container - Expected items of [securityContext.capabilities.%s] to be unique, but got [%s]" $key (join ", " $item)) -}}
{{- end -}}
{{- end -}}
{{- $secContext | toJson -}}
{{- end -}}
@@ -0,0 +1,33 @@
{{/* Returns termination */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.termination" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.termination" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $termination := (dict "messagePath" "" "messagePolicy" "") -}}
{{- with $objectData.termination -}}
{{- with .messagePath -}}
{{- $_ := set $termination "messagePath" (tpl . $rootCtx) -}}
{{- end -}}
{{- with .messagePolicy -}}
{{- $policy := (tpl . $rootCtx) -}}
{{- $policies := (list "File" "FallbackToLogsOnError") -}}
{{- if not (mustHas $policy $policies) -}}
{{- fail (printf "Container - Expected [termination.messagePolicy] to be one of [%s], but got [%s]" (join ", " $policies) $policy) -}}
{{- end -}}
{{- $_ := set $termination "messagePolicy" $policy -}}
{{- end -}}
{{- end -}}
{{- $termination | toJson -}}
{{- end -}}
@@ -0,0 +1,156 @@
{{/* Returns volumeMount list */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.volumeMount" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.volumeMount" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $volMounts := list -}}
{{- $codeServerIgnoredTypes := (list "configmap" "secret" "vct") -}}
{{- range $persistenceName, $persistenceValues := $rootCtx.Values.persistence -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $rootCtx "objectData" $persistenceValues
"name" $persistenceName "caller" "Volume Mount"
"key" "persistence")) -}}
{{/* TLDR: Enabled + Not VCT without STS */}}
{{- if and (eq $enabled "true") (not (and (eq $persistenceValues.type "vct") (ne $objectData.podType "StatefulSet"))) -}}
{{/* Dont try to mount configmap/sercet/vct to codeserver */}}
{{- if not (and (eq $objectData.shortName "codeserver") (mustHas $persistenceValues.type $codeServerIgnoredTypes)) -}}
{{- $volMount := (include "tc.v1.common.lib.container.volumeMount.isSelected" (dict
"rootCtx" $rootCtx "persistenceName" $persistenceName "persistenceValues" $persistenceValues "objectData" $objectData
)) | fromJson -}}
{{- if $volMount -}}
{{- $volMounts = mustAppend $volMounts $volMount -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- range $volMount := $volMounts -}}
{{/* Expand values */}}
{{- $_ := set $volMount "mountPath" (tpl $volMount.mountPath $rootCtx) -}}
{{- $_ := set $volMount "subPath" (tpl $volMount.subPath $rootCtx) -}}
{{- $_ := set $volMount "mountPropagation" (tpl $volMount.mountPropagation $rootCtx) -}}
{{- if not $volMount.mountPath -}}
{{- fail (printf "Persistence - Expected non-empty [mountPath]") -}}
{{- end -}}
{{- if not (hasPrefix "/" $volMount.mountPath) -}}
{{- fail (printf "Persistence - Expected [mountPath] to start with a forward slash [/]") -}}
{{- end -}}
{{- $propagationTypes := (list "None" "HostToContainer" "Bidirectional") -}}
{{- if and $volMount.mountPropagation (not (mustHas $volMount.mountPropagation $propagationTypes)) -}}
{{- fail (printf "Persistence - Expected [mountPropagation] to be one of [%s], but got [%s]" (join ", " $propagationTypes) $volMount.mountPropagation) -}}
{{- end -}}
{{- if not (kindIs "bool" $volMount.readOnly) -}}
{{- fail (printf "Persistence - Expected [readOnly] to be [boolean], but got [%s]" (kindOf $volMount.readOnly)) -}}
{{- end }}
- name: {{ $volMount.name }}
mountPath: {{ $volMount.mountPath }}
readOnly: {{ $volMount.readOnly }}
{{- with $volMount.subPath }}
subPath: {{ . }}
{{- end -}}
{{- with $volMount.mountPropagation }}
mountPropagation: {{ . }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.container.volumeMount.isSelected" -}}
{{- $persistenceName := .persistenceName -}}
{{- $persistenceValues := .persistenceValues -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{/* Initialize from the default values */}}
{{- $volMount := dict -}}
{{- if eq $persistenceValues.type "vct" -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- $persistenceName = printf "%s-%s" $fullname $persistenceName -}}
{{- end -}}
{{- $_ := set $volMount "name" $persistenceName -}}
{{- if eq $persistenceValues.type "device" -}} {{/* On devices use the hostPath as default if mountpath is not defined */}}
{{- $_ := set $volMount "mountPath" ($persistenceValues.mountPath | default $persistenceValues.hostPath | default "") -}}
{{- else -}}
{{- $_ := set $volMount "mountPath" ($persistenceValues.mountPath | default "") -}}
{{- end -}}
{{- $_ := set $volMount "subPath" ($persistenceValues.subPath | default "") -}}
{{- $_ := set $volMount "readOnly" ($persistenceValues.readOnly | default false) -}}
{{- $_ := set $volMount "mountPropagation" ($persistenceValues.mountPropagation | default "") -}}
{{- $return := false -}}
{{/* If targetSelectAll is set, means all pods/containers */}} {{/* targetSelectAll does not make sense for vct */}}
{{- if and $persistenceValues.targetSelectAll (ne $persistenceValues.type "vct") -}}
{{- $return = true -}}
{{/* Set custom path on autopermissions container */}}
{{- if and (eq $objectData.shortName "autopermissions") $persistenceValues.autoPermissions -}}
{{- if $persistenceValues.autoPermissions.enabled -}}
{{- $return = true -}}
{{- $_ := set $volMount "mountPath" (printf "/mounts/%v" $persistenceName) -}}
{{- end -}}
{{- end -}}
{{/* If the container is the autopermission */}}
{{- else if (eq $objectData.shortName "autopermissions") -}}
{{- if $persistenceValues.autoPermissions -}}
{{- if $persistenceValues.autoPermissions.enabled -}}
{{- $return = true -}}
{{- $_ := set $volMount "mountPath" (printf "/mounts/%v" $persistenceName) -}}
{{- end -}}
{{- end -}}
{{/* Else if selector is defined */}}
{{- else if $persistenceValues.targetSelector -}}
{{- if not (kindIs "map" $persistenceValues.targetSelector) -}}
{{- fail (printf "Persistence - Expected [targetSelector] to be a [dict] but got [%s]" (kindOf $persistenceValues.targetSelector)) -}}
{{- end -}}
{{/* If pod is selected */}}
{{- if mustHas $objectData.podShortName ($persistenceValues.targetSelector | keys) -}}
{{- $selectorValues := (get $persistenceValues.targetSelector $objectData.podShortName) -}}
{{- if not (kindIs "map" $selectorValues) -}}
{{- fail (printf "Persistence - Expected [targetSelector.%s] to be a [dict], but got [%s]" $objectData.podShortName (kindOf $selectorValues)) -}}
{{- end -}}
{{- if not $selectorValues -}}
{{- fail (printf "Persistence - Expected non-empty [targetSelector.%s]" $objectData.podShortName) -}}
{{- end -}}
{{/* If container is selected */}}
{{- if or (mustHas $objectData.shortName ($selectorValues | keys)) (eq $objectData.shortName "codeserver") -}}
{{/* Merge with values that might be set for the specific container */}}
{{- $fetchedSelectorValues := (get $selectorValues $objectData.shortName) -}}
{{- if and (eq $objectData.shortName "codeserver") (not $fetchedSelectorValues) -}}
{{- $fetchedSelectorValues = (get $selectorValues ($selectorValues | keys | first)) -}}
{{- end -}}
{{- $volMount = mustMergeOverwrite $volMount $fetchedSelectorValues -}}
{{- $return = true -}}
{{- end -}}
{{- end -}}
{{/* if its the codeserver */}}
{{- else if (eq $objectData.shortName "codeserver") -}}
{{- $return = true -}}
{{/* Else if not selector, but pod and container is primary */}}
{{- else if and $objectData.podPrimary $objectData.primary -}}
{{- $return = true -}}
{{- end -}}
{{- if $return -}} {{/* If it's selected, return the volumeMount */}}
{{- $volMount | toJson -}}
{{- else -}} {{/* Else return an empty dict */}}
{{- dict | toJson -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,18 @@
{{/* Returns exec action */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.actions.exec" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- if not $objectData.command -}}
{{- fail (printf "Container - Expected non-empty [%s] [command] on [exec] type" $caller) -}}
{{- end }}
exec:
command:
{{- include "tc.v1.common.lib.container.command" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4}}
{{- end -}}
@@ -0,0 +1,23 @@
{{/* Returns grpc action */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.actions.grpc" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- if not $objectData.port -}}
{{- fail (printf "Container - Expected non-empty [%s] [port] on [grpc] type" $caller) -}}
{{- end -}}
{{- $port := $objectData.port -}}
{{- if kindIs "string" $port -}}
{{- $port = tpl $port $rootCtx -}}
{{- end }}
grpc:
port: {{ $port }}
{{- end -}}
@@ -0,0 +1,53 @@
{{/* Returns httpGet action */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.actions.httpGet" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- if not $objectData.port -}}
{{- fail (printf "Container - Expected non-empty [%s] [port] on [http] type" $caller) -}}
{{- end -}}
{{- $port := $objectData.port -}}
{{- $path := "/" -}}
{{- $scheme := "http" -}}
{{- if kindIs "string" $port -}}
{{- $port = tpl $port $rootCtx -}}
{{- end -}}
{{- with $objectData.path -}}
{{- $path = tpl . $rootCtx -}}
{{- end -}}
{{- if not (hasPrefix "/" $path) -}}
{{- fail (printf "Container - Expected [%s] [path] to start with a forward slash [/] on [http] type" $caller) -}}
{{- end -}}
{{- with $objectData.type -}}
{{- $scheme = tpl . $rootCtx -}}
{{- end }}
httpGet:
{{- with $objectData.host }}
host: {{ tpl . $rootCtx }}
{{- end }}
port: {{ $port }}
path: {{ $path }}
scheme: {{ $scheme | upper }}
{{- with $objectData.httpHeaders }}
httpHeaders:
{{- range $name, $value := . }}
{{- if not $value -}}
{{- fail "Container - Expected non-empty [value] on [httpHeaders]" -}}
{{- end }}
- name: {{ $name }}
value: {{ tpl (toString $value) $rootCtx | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -0,0 +1,23 @@
{{/* Returns tcpSocket action */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.actions.tcpSocket" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- if not $objectData.port -}}
{{- fail (printf "Container - Expected non-empty [%s] [port] on [tcp] type" $caller) -}}
{{- end -}}
{{- $port := $objectData.port -}}
{{- if kindIs "string" $port -}}
{{- $port = tpl $port $rootCtx -}}
{{- end }}
tcpSocket:
port: {{ $port }}
{{- end -}}
@@ -0,0 +1,25 @@
{{- define "tc.v1.common.lib.credentials.validation" -}}
{{- $rootCtx := .rootCtx -}}
{{- $caller := .caller -}}
{{- $credName := .credName -}}
{{- $credentials := get $rootCtx.Values.credentials $credName -}}
{{- if not $credentials -}}
{{- fail (printf "%s - Expected credentials [%s] to be defined in [credentials] which currently contains [%s] keys" $caller $credName (keys $rootCtx.Values.credentials | join ", ")) -}}
{{- end -}}
{{- $validCredTypes := list "s3" -}}
{{- if $credentials.type -}} {{/* Remove this if check if more types are supported in future */}}
{{- if not (mustHas $credentials.type $validCredTypes) -}}
{{- fail (printf "%s - Expected [type] in [credentials.%s] to be one of [%s], but got [%s]" $caller $credName (join ", " $validCredTypes) $credentials.type) -}}
{{- end -}}
{{- end -}}
{{- $reqFields := list "url" "bucket" "encrKey" "accessKey" "secretKey" -}}
{{- range $key := $reqFields -}}
{{- if not (get $credentials $key) -}}
{{- fail (printf "VolSync - Expected non-empty [%s] in [credentials.%s]" $key $credName) -}}
{{- end -}}
{{- end -}}
{{- end -}}

Some files were not shown because too many files have changed in this diff Show More