Major Common cleanup + services overhaul (#448)

* Major Common cleanup + services overhaul

* add resources test and scaleGPU support

* implement cleaner ingress, remove externalService and remove ingressRoute

* cleanup service test whoopsies

* fix some more test errors

* Fix ingress tests

* oops

* redesign ixcert system for ingress

* test multiple ixcert-secrets support

* increate tests versioning

* add test for pvc name override
This commit is contained in:
Kjeld Schouten-Lebbing
2021-05-10 14:13:17 +02:00
committed by GitHub
parent 30c996024f
commit 196d4d8327
51 changed files with 3260 additions and 2086 deletions

View File

@@ -142,7 +142,7 @@ jobs:
## TODO: Fix common-test
- name: Run chart-testing (install)
if: ${{ matrix.app != 'common' && matrix.app != '.gitkee' && matrix.app != 'common-test' }}
if: ${{ matrix.app != 'common' && matrix.app != '.gitkee' }}
run: ct install --config .github/ct-install.yaml --charts 'charts/${{ steps.prep-lint.outputs.train }}/${{ matrix.app }}'
app-tests-complete:

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
{
"recommendations": [
"ms-vscode-remote.remote-containers"
]
"recommendations": [
"ms-vscode-remote.remote-containers",
"rebornix.ruby"
]
}

2
.vscode/launch.json vendored
View File

@@ -27,7 +27,7 @@
"exec",
"m",
"-r",
"${workspaceFolder}/.tools/tests/charts"
"${workspaceFolder}/tests"
]
}
]

View File

@@ -1,7 +1,7 @@
apiVersion: v2
kubeVersion: ">=1.16.0-0"
name: common-test
version: 2.1.6
version: 3.0.0
# upstream_version:
appVersion: none
description: Helper chart to test different use cases of the common library

View File

@@ -1,80 +1,9 @@
image:
repository: b4bz/homer
tag: 21.03.2
tag: latest
pullPolicy: IfNotPresent
services:
main:
port:
port: 8080
test1:
enabled: true
type: ClusterIP
port:
port: 8081
name: tcp-test
protocol: TCP
targetPort: 8081
test2:
enabled: true
type: ClusterIP
port:
port: 8082
name: udp-test
protocol: UDP
targetPort: 8082
additionalServices:
- name: test3
enabled: true
type: ClusterIP
port:
port: 8083
name: extra-tcp-test
protocol: TCP
targetPort: 8083
- name: test4
enabled: true
type: ClusterIP
port:
port: 8084
name: extra-udp-test
protocol: UDP
targetPort: 8084
ingress:
test1:
enabled: true
test2:
certType: "plain"
additionalIngress:
- name: "test3"
enabled: true
- name: "test4"
enabled: true
# these values and names are set specifically with the unittests in mind.
deviceMounts:
test1:
enabled: true
emptyDir: true
devicePath: "/test1"
test2:
enabled: true
emptyDir: false
devicePath: "/test2"
# these values and names are set specifically with the unittests in mind.
customStorage:
- enabled: true
emptyDir: true
mountPath: "/test3"
hostPath: ""
- name: "test4"
enabled: true
emptyDir: false
setPermissions: true
mountPath: "/test4"
hostPath: "/tmp"

View File

@@ -19,4 +19,4 @@ name: common
sources:
- https://github.com/truecharts/apps/tree/master/library/common
type: library
version: 3.5.8
version: 4.0.0

View File

@@ -19,9 +19,14 @@ Main entrypoint for the common library chart. It will render all underlying temp
{{ else if eq .Values.controllerType "statefulset" }}
{{- include "common.statefulset" . | nindent 0 }}
{{- end -}}
{{ include "common.classes.hpa" . | nindent 0 }}
{{ include "common.services" . | nindent 0 }}
{{ include "common.ingress" . | nindent 0 }}
{{ include "common.resources.portal" . | nindent 0 }}
{{ include "common.storage.permissions" . | nindent 0 }}
{{- if .Values.secret -}}
{{- print "---" | nindent 0 -}}
{{ include "common.secret" . | nindent 0 }}
{{- end -}}
{{ include "common.classes.mountPermissions" . | nindent 0 }}
{{ include "common.classes.portal" . | nindent 0 }}
{{- end -}}

View File

@@ -5,118 +5,30 @@ of the main Ingress and any additionalIngresses.
{{- define "common.ingress" -}}
{{- /* Generate named ingresses as required */ -}}
{{- range $name, $ingress := .Values.ingress }}
{{- $certType := $ingress.certType | default "disabled" -}}
{{- $enabled := $ingress.enabled | default false -}}
{{- if or ( ne $certType "disabled" ) ( $ingress.enabled ) -}}
{{- print ("---") | nindent 0 -}}
{{- if $ingress.enabled -}}
{{- print ("---\n") | nindent 0 -}}
{{- $ingressValues := $ingress -}}
{{/* set defaults */}}
{{- if and (not $ingressValues.nameSuffix) ( ne $name "main" ) -}}
{{- if not $ingressValues.nameSuffix -}}
{{- $_ := set $ingressValues "nameSuffix" $name -}}
{{ end -}}
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
{{- if not $ingressValues.type -}}
{{- $_ := set $ingressValues "type" "HTTP" -}}
{{ end -}}
{{- if not $ingressValues.certType -}}
{{- $_ := set $ingressValues "certType" "" -}}
{{ end -}}
{{- if or ( eq $ingressValues.type "TCP" ) ( eq $ingressValues.type "UDP" ) ( eq $ingressValues.type "HTTP-IR" ) -}}
{{- include "common.classes.ingressRoute" $ -}}
{{- else -}}
{{- include "common.classes.ingress" $ -}}
{{ end -}}
{{- if eq $ingressValues.certType "ixcert" -}}
{{- $_ := set $ "ObjectValues" (dict "certHolder" $ingressValues) -}}
{{- print ("---") | nindent 0 -}}
{{- include "common.resources.cert.secret" $ }}
{{ end -}}
{{- end }}
{{- end }}
{{- include "common.classes.ingress" $ }}
{{- /* Generate additional ingresses as required */ -}}
{{- range $index, $additionalIngress := .Values.additionalIngress }}
{{- $certType := $additionalIngress.certType | default "disabled" -}}
{{- if or ( ne $certType "disabled" ) ( $additionalIngress.enabled ) -}}
{{- print ("---") | nindent 0 -}}
{{- $ingressValues := $additionalIngress -}}
{{/* set defaults */}}
{{- $name := $index -}}
{{- if $ingressValues.name -}}
{{- $name := $ingressValues.name -}}
{{- range $index, $tlsValues := $ingressValues.tls }}
{{- if .scaleCert }}
{{- $nameSuffix := ( printf "%v-%v-%v" $ingressValues.nameSuffix "tls" $index ) -}}
{{- $_ := set $tlsValues "nameSuffix" $nameSuffix -}}
{{- $_ := set $ "ObjectValues" (dict "certHolder" $tlsValues) -}}
{{- print ("---\n") | nindent 0 -}}
{{- include "common.cert.secret" $ -}}
{{- end }}
{{- end }}
{{- if or (not $ingressValues.nameSuffix) ( ne ( $name | quote ) "main" ) -}}
{{- $_ := set $ingressValues "nameSuffix" $name -}}
{{ end -}}
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
{{- if not $ingressValues.type -}}
{{- $_ := set $ingressValues "type" "HTTP" -}}
{{ end -}}
{{- if not $ingressValues.certType -}}
{{- $_ := set $ingressValues "certType" "" -}}
{{ end -}}
{{- if or ( eq $ingressValues.type "TCP" ) ( eq $ingressValues.type "UDP" ) ( eq $ingressValues.type "HTTP-IR" ) -}}
{{- include "common.classes.ingressRoute" $ -}}
{{- else -}}
{{- include "common.classes.ingress" $ -}}
{{ end -}}
{{- if eq $ingressValues.certType "ixcert" -}}
{{- $_ := set $ "ObjectValues" (dict "certHolder" $ingressValues) -}}
{{- print ("---") | nindent 0 -}}
{{- include "common.resources.cert.secret" $ }}
{{ end -}}
{{- end }}
{{- end }}
{{- /* Generate externalService ingresses as required */ -}}
{{- range $index, $externalService := .Values.externalServices }}
{{- $certType := $externalService.certType | default "disabled" -}}
{{- if or ( ne $certType "disabled" ) ( $externalService.enabled ) -}}
{{- print ("---") | nindent 0 -}}
{{- $ingressValues := $externalService -}}
{{/* set defaults */}}
{{- $name := $index -}}
{{- if $ingressValues.name -}}
{{- $name := $ingressValues.name -}}
{{- end }}
{{- $name = printf "%v-%v" "external" $name -}}
{{- if or (not $ingressValues.nameSuffix) -}}
{{- $_ := set $ingressValues "nameSuffix" $name -}}
{{ end -}}
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
{{- if not $ingressValues.type -}}
{{- $_ := set $ingressValues "type" "HTTP" -}}
{{ end -}}
{{- if not $ingressValues.certType -}}
{{- $_ := set $ingressValues "certType" "" -}}
{{ end -}}
{{- if or ( eq $ingressValues.type "TCP" ) ( eq $ingressValues.type "UDP" ) ( eq $ingressValues.type "HTTP-IR" ) -}}
{{- include "common.classes.ingressRoute" $ -}}
{{- else -}}
{{- include "common.classes.ingress" $ -}}
{{ end -}}
{{- print ("---") | nindent 0 -}}
{{- include "common.classes.externalService" $ }}
{{- if eq $ingressValues.certType "ixcert" -}}
{{- $_ := set $ "ObjectValues" (dict "certHolder" $ingressValues) -}}
{{- print ("---") | nindent 0 -}}
{{- include "common.resources.cert.secret" $ }}
{{ end -}}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -23,14 +23,21 @@ of all the entries of the persistence key.
{{- define "common.pvc" -}}
{{- /* Generate pvc as required */ -}}
{{- range $index, $PVC := .Values.persistence }}
{{- if and $PVC.enabled (not (or $PVC.emptyDir $PVC.existingClaim)) -}}
{{- $emptyDir := false -}}
{{- if $PVC.emptyDir -}}
{{- if $PVC.emptyDir.enabled -}}
{{- $emptyDir = true -}}
{{- end -}}
{{- end -}}
{{- if and $PVC.enabled (not (or $emptyDir $PVC.existingClaim)) -}}
{{- $persistenceValues := $PVC -}}
{{- if not $persistenceValues.nameSuffix -}}
{{- $_ := set $persistenceValues "nameSuffix" $index -}}
{{- end -}}
{{- $_ := set $ "ObjectValues" (dict "persistence" $persistenceValues) -}}
{{- print ("---") | nindent 0 -}}
{{- include "common.classes.pvc" $ -}}
{{- include "common.classes.pvc" $ | nindent 0 -}}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,16 @@
{{/*
The Secret object to be created.
*/}}
{{- define "common.secret" -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "common.names.fullname" . }}
labels:
{{- include "common.labels" . | nindent 4 }}
type: Opaque
{{- with .Values.secret }}
stringData:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}

View File

@@ -1,46 +1,21 @@
{{/*
Renders the Service objects required by the chart by returning a concatinated list
of the main Service and any additionalServices.
of the main Service and any additionalservice.
*/}}
{{- define "common.services" -}}
{{- if .Values.services -}}
{{- /* Add dict of primary services */ -}}
{{- range $name, $service := .Values.services }}
{{- if or ( $service.enabled ) ( eq $name "main" ) -}}
{{- print ("---") | nindent 0 -}}
{{- print ("\n") | nindent 0 -}}
{{- if $service.enabled -}}
{{- print ("---\n") | nindent 0 -}}
{{- $serviceValues := $service -}}
{{- /* Dont add name suffix for primary service named "main" */ -}}
{{- if and (not $serviceValues.nameSuffix) ( ne $name "main" ) -}}
{{- if $serviceValues.nameSuffix -}}
{{- $_ := set $serviceValues "nameSuffix" $name -}}
{{ end -}}
{{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}}
{{- include "common.classes.service" $ -}}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.additionalServices -}}
{{- /* Generate additional services as required */ -}}
{{- range $index, $extraService := .Values.additionalServices }}
{{- if $extraService.enabled -}}
{{- print ("---") | nindent 0 -}}
{{- $serviceValues := $extraService -}}
{{- $name := $index -}}
{{- if $serviceValues.name -}}
{{- $name := $serviceValues.name -}}
{{- end }}
{{- /* Dont add name suffix for primary service named "main" */ -}}
{{- if and (not $serviceValues.nameSuffix) ( ne ( $name | quote ) "main" ) -}}
{{- $_ := set $serviceValues "nameSuffix" $name -}}
{{ end -}}
{{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}}
{{- include "common.classes.service" $ -}}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,44 @@
{{/*
This template serves as a blueprint for horizontal pod autoscaler objects that are created
using the common library.
*/}}
{{- define "common.classes.hpa" -}}
{{- if .Values.autoscaling }}
{{- if .Values.autoscaling.enabled }}
{{- print "---" | nindent 0 -}}
{{- $hpaName := include "common.names.fullname" . -}}
{{- $targetName := include "common.names.fullname" . -}}
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: {{ $hpaName }}
labels:
{{- include "common.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
{{- if eq .Values.controllerType "statefulset" }}
kind: StatefulSet
{{- else }}
kind: Deployment
{{- end }}
name: {{ .Values.autoscaling.target | default $targetName }}
minReplicas: {{ .Values.autoscaling.minReplicas | default 1 }}
maxReplicas: {{ .Values.autoscaling.maxReplicas | default 3 }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,90 @@
{{/*
This template serves as a blueprint for all Ingress objects that are created
within the common library.
*/}}
{{- define "common.classes.ingress" -}}
{{- $ingressName := include "common.names.fullname" . -}}
{{- $values := index .Values.ingress (keys .Values.ingress | first) -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.ingress -}}
{{- $values = . -}}
{{- end -}}
{{ end -}}
{{- if hasKey $values "nameSuffix" -}}
{{- $ingressName = printf "%v-%v" $ingressName $values.nameSuffix -}}
{{ end -}}
{{- $svc := index .Values.services (keys .Values.services | first) -}}
{{- $svcName := $values.serviceName | default (include "common.names.fullname" .) -}}
{{- $svcPort := $values.servicePort | default $svc.port.port -}}
apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }}
kind: Ingress
metadata:
name: {{ $ingressName }}
labels:
{{- include "common.labels" . | nindent 4 }}
{{- with $values.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
{{- if $values.ingressClassName }}
ingressClassName: {{ $values.ingressClassName }}
{{- end }}
{{- end }}
{{- if $values.tls }}
tls:
{{- range $index, $tlsValues := $values.tls }}
- hosts:
{{- range $tlsValues.hosts }}
- {{ . | quote }}
{{- end }}
{{- range $tlsValues.hostsTpl }}
- {{ tpl . $ | quote }}
{{- end }}
{{- if or $tlsValues.secretNameTpl $tlsValues.secretName $tlsValues.scaleCert }}
{{- if $tlsValues.scaleCert }}
secretName: {{ ( printf "%v-%v-%v-%v-%v" $ingressName "tls" $index "ixcert" $tlsValues.scaleCert ) }}
{{- else if $tlsValues.secretNameTpl }}
secretName: {{ tpl $tlsValues.secretNameTpl $ | quote}}
{{- else }}
secretName: {{ $tlsValues.secretName }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
rules:
{{- range $values.hosts }}
{{- if .hostTpl }}
- host: {{ tpl .hostTpl $ | quote }}
{{- else }}
- host: {{ .host | quote }}
{{- end }}
http:
paths:
{{- range .paths }}
{{- if .pathTpl }}
- path: {{ tpl .pathTpl $ | quote }}
{{- else }}
- path: {{ .path | quote }}
{{- end }}
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
pathType: {{ default "Prefix" .pathType }}
{{- end }}
backend:
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
service:
name: {{ .serviceName | default $svcName }}
port:
number: {{ .servicePort | default $svcPort }}
{{- else }}
serviceName: {{ .serviceName | default $svcName }}
servicePort: {{ .servicePort | default $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,91 @@
{{/*
This template serves as the blueprint for the mountPermissions job that is run
before chart installation.
*/}}
{{- define "common.classes.mountPermissions" -}}
{{- if .Values.hostPathMounts -}}
{{- $jobName := include "common.names.fullname" . -}}
{{- $values := .Values -}}
{{- $user := 568 -}}
{{- $group := 568 -}}
{{- print "---" | nindent 0 -}}
{{- if $values.podSecurityContext }}
{{- if $values.podSecurityContext.runAsUser }}
{{- $user = $values.podSecurityContext.runAsUser -}}
{{- end -}}
{{- if $values.podSecurityContext.fsGroup -}}
{{- $group = $values.podSecurityContext.fsGroup -}}
{{- end -}}
{{- else if $values.env }}
{{- if $values.env.PUID }}
{{- $user = $values.env.PUID -}}
{{- end -}}
{{- if $values.env.PGID }}
{{- $group = $values.env.PGID -}}
{{- end -}}
{{- end -}}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $jobName }}-autopermissions
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-10"
"helm.sh/hook-delete-policy": hook-succeeded,hook-failed,before-hook-creation
spec:
template:
metadata:
spec:
restartPolicy: Never
containers:
- name: set-mount-permissions
image: "alpine:3.3"
command:
- /bin/sh
- -c
- | {{ range $index, $hpm := .Values.hostPathMounts}}{{ if and $hpm.enabled $hpm.setPermissions}}
chown -R {{ print $user }}:{{ print $group }} {{ print $hpm.mountPath }}{{ end }}{{ end }}
#args:
#
#securityContext:
#
volumeMounts:
{{ range $name, $hpmm := .Values.hostPathMounts }}
{{- if $hpmm.enabled -}}
{{- if $hpmm.setPermissions -}}
{{ if $hpmm.name }}
{{ $name = $hpmm.name }}
{{ end }}
- name: hostpathmounts-{{ $name }}
mountPath: {{ $hpmm.mountPath }}
{{ if $hpmm.subPath }}
subPath: {{ $hpmm.subPath }}
{{ end }}
{{- end -}}
{{- end -}}
{{ end }}
volumes:
{{- range $name, $hpm := .Values.hostPathMounts -}}
{{ if $hpm.enabled }}
{{ if $hpm.setPermissions }}
{{ if $hpm.name }}
{{ $name = $hpm.name }}
{{ end }}
- name: hostpathmounts-{{ $name }}
{{ if $hpm.emptyDir }}
emptyDir: {}
{{- else -}}
hostPath:
path: {{ required "hostPath not set" $hpm.hostPath }}
{{ end }}
{{ end }}
{{ end }}
{{- end -}}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,72 @@
{{- define "common.classes.portal" -}}
{{- if .Values.portal }}
{{- if .Values.portal.enabled }}
{{- $svc := index .Values.services (keys .Values.services | first) -}}
{{- $ingr := index .Values.ingress (keys .Values.ingress | first) -}}
{{- $host := "$node_ip" }}
{{- $port := 443 }}
{{- $protocol := "https" }}
{{- $portProtocol := "" }}
{{- $path := "/" }}
{{- if $ingr }}
{{- if $ingr.enabled }}
{{- range $ingr.hosts }}
{{- if .hostTpl }}
{{ $host = ( tpl .hostTpl $ ) }}
{{- else if .host }}
{{ $host = .host }}
{{- else }}
{{ $host = "$node_ip" }}
{{- end }}
{{- if .paths }}
{{- $path = (first .paths).path }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if and ( .Values.portal.ingressPort ) ( ne $host "$node_ip" ) }}
{{- $port = .Values.portal.ingressPort }}
{{- else if eq $host "$node_ip" }}
{{- if eq $svc.type "NodePort" }}
{{- $port = $svc.port.nodePort }}
{{- if or ( eq $svc.port.protocol "HTTP" ) ( eq $svc.port.protocol "HTTPS" ) }}
{{- $portProtocol = $svc.port.protocol }}
{{- end }}
{{- end }}
{{- end }}
{{- if and ( $portProtocol ) ( eq $host "$node_ip" ) }}
{{- $protocol = $portProtocol }}
{{- else if and ( ne $host "$node_ip" ) }}
{{- if $ingr.tls }}
{{- $protocol = "https" }}
{{- end }}
{{- end }}
{{- if and ( .Values.portal.host ) ( eq $host "$node_ip" ) }}
{{- $host = .Values.portal.host }}
{{- end }}
{{- if and ( .Values.portal.path ) }}
{{- $path = .Values.portal.path }}
{{- end }}
{{- print "---" | nindent 0 -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: portal
labels: {{ include "common.labels" . | nindent 4 }}
data:
protocol: {{ $protocol }}
host: {{ $host | quote }}
port: {{ $port | quote }}
path: {{ $path | quote }}
url: {{ ( printf "%v://%v:%v%v" $protocol $host $port $path ) | quote }}
{{- end }}
{{- end }}
{{- end -}}

View File

@@ -31,7 +31,9 @@ within the common library.
{{- if hasKey $values "nameOverride" -}}
{{- $pvcName = $values.nameOverride -}}
{{- else if hasKey $values "nameSuffix" -}}
{{- $pvcName = printf "%v-%v" $pvcName $values.nameSuffix -}}
{{- if not (eq $values.nameSuffix "-") -}}
{{- $pvcName = printf "%v-%v" $pvcName $values.nameSuffix -}}
{{ end -}}
{{ end -}}
kind: PersistentVolumeClaim
apiVersion: v1
@@ -55,8 +57,6 @@ spec:
requests:
storage: {{ required (printf "size is required for PVC %v" $pvcName) $values.size | quote }}
{{- if $values.storageClass }}
storageClassName: {{ include "common.storage.class" . }}
{{- else }}
storageClassName: {{ ( printf "%v-%v" "ix-storage-class" .Release.Name ) }}
storageClassName: {{ if (eq "-" $values.storageClass) }}""{{- else if (eq "SCALE-ZFS" $values.storageClass ) }}{{ ( printf "%v-%v" "ix-storage-class" .Release.Name ) }}{{- else }}{{ $values.storageClass | quote }}{{- end }}
{{- end }}
{{- end -}}

View File

@@ -21,27 +21,17 @@ This template serves as a blueprint for all Service objects that are created
within the common library.
*/}}
{{- define "common.classes.service" -}}
{{- $values := .Values.services.main -}}
{{- $values := index .Values.services (keys .Values.services | first) -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.service -}}
{{- $values = . -}}
{{- end -}}
{{ end -}}
{{- $serviceName := include "common.names.fullname" . -}}
{{- if hasKey $values "nameSuffix" -}}
{{- $serviceName = printf "%v-%v" $serviceName $values.nameSuffix -}}
{{ end -}}
{{- $svcType := $values.type | default "" -}}
{{- $portProtocol := $values.port.protocol -}}
{{- if or ( eq $values.port.protocol "HTTP" ) ( eq $values.port.protocol "HTTPS" ) ( eq $values.port.protocol "TCP" ) -}}
{{- $portProtocol = "TCP" -}}
{{- else if eq $values.port.protocol "UDP" }}
{{- $portProtocol = "UDP" -}}
{{- end }}
apiVersion: v1
kind: Service
metadata:
@@ -52,7 +42,7 @@ metadata:
{{ toYaml $values.labels | nindent 4 }}
{{- end }}
annotations:
{{- if eq $values.port.protocol "HTTPS" }}
{{- if eq ( $values.port.protocol | default "" ) "HTTPS" }}
traefik.ingress.kubernetes.io/service.serversscheme: https
{{- end }}
{{- with $values.annotations }}

View File

@@ -29,15 +29,17 @@ Render all the ports and additionalPorts for a Service object.
{{- if $ports -}}
ports:
{{- range $_ := $ports }}
{{- $protocol := "" -}}
{{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) }}
{{- $protocol = "TCP" -}}
{{- else }}
{{- $protocol = .protocol | default "TCP" -}}
{{- end }}
- port: {{ .port }}
targetPort: {{ .targetPort | default .name | default "http" }}
protocol: {{ $protocol | default "TCP" }}
{{- if .protocol }}
{{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) ( eq .protocol "TCP" ) }}
protocol: TCP
{{- else }}
protocol: {{ .protocol }}
{{- end }}
{{- else }}
protocol: TCP
{{- end }}
name: {{ .name | default "http" }}
{{- if (and (eq $.svcType "NodePort") (not (empty .nodePort))) }}
nodePort: {{ .nodePort }}

View File

@@ -1,63 +0,0 @@
{{- define "common.classes.externalService" -}}
{{- $serviceName := include "common.names.fullname" . -}}
{{- $values := .Values -}}
{{- $svcPort := 80 }}
{{- $ingressService := $.Values }}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.ingress -}}
{{- $values = . -}}
{{- end -}}
{{ end -}}
{{- if hasKey $values "nameSuffix" -}}
{{- $serviceName = printf "%v-%v" $serviceName $values.nameSuffix -}}
{{ end -}}
{{- $svcName := $values.serviceName | default $serviceName -}}
{{- if $values.servicePort }}
{{- $svcPort = $values.servicePort -}}
{{- end }}
apiVersion: v1
kind: Service
metadata:
name: {{ $svcName }}
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
{{- if eq ( $values.serviceType | default "" ) "HTTPS" }}
traefik.ingress.kubernetes.io/service.serversscheme: https
{{- end }}
{{- with $values.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ports:
{{- if eq $values.type "UDP"}}
- protocol: UDP
port: {{ $values.servicePort }}
targetPort: {{ $values.servicePort }}
{{- else }}
- protocol: TCP
port: {{ $values.servicePort }}
targetPort: {{ $values.servicePort }}
{{- end }}
---
apiVersion: v1
kind: Endpoints
metadata:
name: {{ $svcName }}
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
{{- with $values.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
subsets:
- addresses:
- ip: {{ $values.serviceTarget }}
ports:
- port: {{ $values.servicePort }}
{{- end }}

View File

@@ -1,143 +0,0 @@
{{/*
This template serves as a blueprint for all Ingress objects that are created
within the common library.
*/}}
{{- define "common.classes.ingress" -}}
{{- $ingressName := include "common.names.fullname" . -}}
{{- $values := .Values -}}
{{- $svcPort := 80 -}}
{{- $portProtocol := "" -}}
{{- $ingressService := $.Values -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.ingress -}}
{{- $values = . -}}
{{- end -}}
{{ end -}}
{{- if hasKey $values "nameSuffix" -}}
{{- $ingressName = printf "%v-%v" $ingressName $values.nameSuffix -}}
{{- if and ( $.Values.services ) ( not $values.servicePort ) }}
{{- $ingressService := index $.Values.services ( $values.nameSuffix | quote ) }}
{{- $svcPort = $ingressService.port.port -}}
{{- $portProtocol = $ingressService.port.protocol | default "" }}
{{ end -}}
{{- else if and ( $.Values.services ) ( not $values.servicePort ) }}
{{- $svcPort = $.Values.services.main.port.port -}}
{{- $portProtocol = $.Values.services.main.port.protocol | default "" -}}
{{ end -}}
{{- $authForwardName := ( printf "%v-%v" $ingressName "auth-forward" ) -}}
{{- $svcName := $values.serviceName | default $ingressName -}}
{{- if $values.dynamicServiceName }}
{{- $dynamicServiceName := printf "%v-%v" .Release.Name $values.dynamicServiceName -}}
{{- $svcName = $dynamicServiceName -}}
{{- end }}
{{- if $values.servicePort }}
{{- $svcPort = $values.servicePort -}}
{{- end }}
{{- if $values.serviceType }}
{{- $portProtocol = $values.serviceType -}}
{{- end }}
apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }}
kind: Ingress
metadata:
name: {{ $ingressName }}
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
{{- if eq $portProtocol "HTTPS" }}
traefik.ingress.kubernetes.io/service.serversscheme: https
{{- end }}
traefik.ingress.kubernetes.io/router.entrypoints: {{ $values.entrypoint | default "websecure" }}
traefik.ingress.kubernetes.io/router.middlewares: traefik-middlewares-chain-public@kubernetescrd{{ if $values.authForwardURL }},{{ printf "%v-%v@%v" .Release.Namespace $authForwardName "kubernetescrd" }}{{ end }}
{{- with $values.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
{{- if $values.ingressClassName }}
ingressClassName: {{ $values.ingressClassName }}
{{- end }}
{{- end }}
{{- if or ( eq $values.certType "selfsigned") (eq $values.certType "ixcert") }}
tls:
- hosts:
{{- if $values.host}}
- {{ $values.host | quote }}
{{- else }}
{{- range $values.hosts }}
- {{ .host | quote }}
{{- end }}
{{- end }}
{{- if eq $values.certType "ixcert" }}
secretName: {{ $ingressName }}
{{- end }}
{{- end }}
rules:
{{- if $values.host }}
- host: {{ $values.host | quote }}
http:
paths:
- path: {{ $values.path | default "/" }}
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
pathType: Prefix
{{- end }}
backend:
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
service:
name: {{ $svcName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $svcName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- range $values.hosts }}
- host: {{ .host | quote }}
http:
paths:
- path: {{ .path | default "/" }}
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
pathType: Prefix
{{- end }}
backend:
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
service:
name: {{ $svcName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $svcName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- if $values.authForwardURL }}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: {{ $authForwardName }}
spec:
forwardAuth:
address: {{ $values.authForwardURL | quote }}
tls:
insecureSkipVerify: true
trustForwardHeader: true
authResponseHeaders:
- Remote-User
- Remote-Groups
- Remote-Name
- Remote-Email
{{- end }}
{{- end }}

View File

@@ -1,127 +0,0 @@
{{/*
This template serves as a blueprint for all ingressRoute objects that are created
within the common library.
*/}}
{{- define "common.classes.ingressRoute" -}}
{{- $ingressName := include "common.names.fullname" . -}}
{{- $values := .Values -}}
{{- $svcPort := 80 }}
{{- $portProtocol := "" }}
{{- $ingressService := $.Values }}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.ingress -}}
{{- $values = . -}}
{{- end -}}
{{ end -}}
{{- if hasKey $values "nameSuffix" -}}
{{- $ingressName = printf "%v-%v" $ingressName $values.nameSuffix -}}
{{- if and ( $.Values.services ) ( not $values.servicePort ) }}
{{- $ingressService := index $.Values.services ( $values.nameSuffix | quote) }}
{{- $svcPort = $ingressService.port.port }}
{{- $portProtocol = $ingressService.port.protocol | default "" }}
{{ end -}}
{{- else if and ( $.Values.services ) ( not $values.servicePort ) }}
{{- $svcPort = $.Values.services.main.port.port }}
{{- $portProtocol = $.Values.services.main.port.protocol | default "" }}
{{ end -}}
{{- $authForwardName := ( printf "%v-%v" $ingressName "auth-forward" ) -}}
{{- $svcName := $values.serviceName | default $ingressName -}}
{{- if $values.servicePort }}
{{- $svcPort = $values.servicePort }}
{{- end }}
{{- if $values.serviceType }}
{{- $portProtocol = $values.serviceType }}
{{- end }}
apiVersion: traefik.containo.us/v1alpha1
{{- if eq $values.type "UDP" }}
kind: IngressRouteUDP
{{- else if eq $values.type "TCP" }}
kind: IngressRouteTCP
{{- else }}
kind: IngressRoute
{{- end }}
metadata:
name: {{ $ingressName }}
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
{{- with $values.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
entryPoints:
- {{ $values.entrypoint }}
routes:
{{- if eq $values.type "UDP" }}
- services:
- name: {{ $svcName }}
port: {{ $svcPort }}
weight: 10
{{- else if eq $values.type "TCP" }}
- match: HostSNI(`*`)
services:
- name: {{ $svcName }}
port: {{ $svcPort }}
weight: 10
terminationDelay: 400
{{- else }}
- kind: Rule
match: Host(`{{ (index $values.hosts 0).host }}`) && PathPrefix(`{{ (index $values.hosts 0).path | default "/" }}`)
services:
- name: {{ $svcName }}
{{- if $values.serviceKind }}
kind: {{ $values.serviceKind }}
{{- else }}
port: {{ $svcPort }}
{{- end }}
middlewares:
- name: traefik-middlewares-chain-public@kubernetescrd
{{- if $values.authForwardURL }}
- name: "{{ printf "%v-%v@%v" .Release.Namespace $authForwardName "kubernetescrd" }}"
{{- end }}
{{- end }}
{{- if not ( eq $values.type "UDP" ) }}
{{- if or ( eq $values.certType "selfsigned") (eq $values.certType "ixcert") }}
tls:
domains:
- main: {{ (index $values.hosts 0).host }}
sans:
{{- range $values.hosts }}
- {{ .host | quote }}
{{- end }}
{{- if eq $values.certType "ixcert" }}
secretName: {{ $ingressName }}
{{- end }}
passthrough: false
{{- end }}
{{- end }}
{{- if $values.authForwardURL }}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: {{ $authForwardName }}
spec:
forwardAuth:
address: {{ $values.authForwardURL | quote }}
tls:
insecureSkipVerify: true
trustForwardHeader: true
authResponseHeaders:
- Remote-User
- Remote-Groups
- Remote-Name
- Remote-Email
{{- end }}
{{- end }}

View File

@@ -0,0 +1,27 @@
{{- define "common.cert.secret" -}}
{{- $secretName := include "common.names.fullname" . -}}
{{- if .ObjectValues.certHolder -}}
{{- if hasKey .ObjectValues.certHolder "nameSuffix" -}}
{{- $secretName = ( printf "%v-%v-%v-%v" $secretName .ObjectValues.certHolder.nameSuffix "ixcert" .ObjectValues.certHolder.scaleCert ) -}}
{{- else }}
{{- $secretName = ( printf "%v-%v-%v" $secretName "ixcert" .ObjectValues.certHolder.scaleCert ) -}}
{{ end -}}
{{ else }}
{{- $_ := set $ "ObjectValues" (dict "certHolder" .Values) -}}
{{- $secretName = ( printf "%v-%v-%v-%v" $secretName "scalecert" "ixcert" .Values.scaleCert ) -}}
{{ end -}}
{{- if eq (include "common.cert.available" $ ) "true" -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
labels: {{ include "common.labels" . | nindent 4 }}
type: kubernetes.io/tls
data:
tls.crt: {{ (include "common.cert.publicKey" $ ) | toString | b64enc | quote }}
tls.key: {{ (include "common.cert.privateKey" $ ) | toString | b64enc | quote }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,57 @@
{{/*
Retrieve true/false if certificate is configured
*/}}
{{- define "common.cert.available" -}}
{{- if .ObjectValues.certHolder.scaleCert -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert) -}}
{{- template "common.cert_present" $values -}}
{{- else -}}
{{- false -}}
{{- end -}}
{{- end -}}
{{/*
Retrieve public key of certificate
*/}}
{{- define "common.cert.publicKey" -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert "publicKey" true) -}}
{{ include "common.cert" $values }}
{{- end -}}
{{/*
Retrieve private key of certificate
*/}}
{{- define "common.cert.privateKey" -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert) -}}
{{ include "common.cert" $values }}
{{- end -}}
{{/*
Retrieve true/false if certificate is available in ixCertificates
*/}}
{{- define "common.cert_present" -}}
{{- $values := . -}}
{{- hasKey $values.Values.ixCertificates ($values.commonCertOptions.certKeyName | toString) -}}
{{- end -}}
{{/*
Retrieve certificate from variable name
*/}}
{{- define "common.cert" -}}
{{- $values := . -}}
{{- $certKey := ($values.commonCertOptions.certKeyName | toString) -}}
{{- if hasKey $values.Values.ixCertificates $certKey -}}
{{- $cert := get $values.Values.ixCertificates $certKey -}}
{{- if $values.commonCertOptions.publicKey -}}
{{ $cert.certificate }}
{{- else -}}
{{ $cert.privatekey }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -87,9 +87,7 @@ Return the appropriate apiVersion for Ingress objects.
*/}}
{{- define "common.capabilities.ingress.apiVersion" -}}
{{- if .Values.ingress.apiVersion -}}
{{- .Values.ingress.apiVersion -}}
{{- else if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
{{- print "extensions/v1beta1" -}}
{{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}}
{{- print "networking.k8s.io/v1beta1" -}}
@@ -110,37 +108,3 @@ Waiting on https://github.com/helm/helm/pull/8608
{{- end }}
{{- end -}}
*/}}
{{/*
Return the appropriate apiVersion for RBAC resources.
*/}}
{{- define "common.capabilities.rbac.apiVersion" -}}
{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}}
{{- print "rbac.authorization.k8s.io/v1beta1" -}}
{{- else -}}
{{- print "rbac.authorization.k8s.io/v1" -}}
{{- end -}}
{{- end -}}
{{/*
Return the appropriate apiVersion for CRDs.
*/}}
{{- define "common.capabilities.crd.apiVersion" -}}
{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}}
{{- print "apiextensions.k8s.io/v1beta1" -}}
{{- else -}}
{{- print "apiextensions.k8s.io/v1" -}}
{{- end -}}
{{- end -}}
{{/*
Returns true if the used Helm version is 3.3+.
A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure.
This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error.
**To be removed when the catalog's minimun Helm version is 3.3**
*/}}
{{- define "common.capabilities.supportsHelmVersion" -}}
{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }}
{{- true -}}
{{- end -}}
{{- end -}}

View File

@@ -35,21 +35,3 @@ Selector labels shared across objects.
app.kubernetes.io/name: {{ include "common.names.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
## Bitnami Compatibility links
{{/* vim: set filetype=mustache: */}}
{{/*
Kubernetes standard labels
*/}}
{{- define "common.labels.standard" -}}
{{ include "common.labels" . }}
{{- end -}}
{{/*
Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector
*/}}
{{- define "common.labels.matchLabels" -}}
{{ include "common.labels.selectorLabels" . }}
{{- end -}}

View File

@@ -21,8 +21,8 @@ This file is considered to be modified by the TrueCharts Project.
Expand the name of the chart.
*/}}
{{- define "common.names.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
@@ -30,18 +30,17 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this
If release name contains chart name it will be used as a full name.
*/}}
{{- define "common.names.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.

View File

@@ -22,71 +22,84 @@ The main container included in the controller.
*/ -}}
{{- define "common.controller.mainContainer" -}}
- name: {{ include "common.names.fullname" . }}
image: "{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }}"
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- with .Values.command }}
{{- if kindIs "string" . }}
command: {{ . }}
{{- else }}
command:
{{ toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- with .Values.args }}
{{- if kindIs "string" . }}
args: {{ . }}
{{- else }}
args:
{{ toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.lifecycle }}
lifecycle:
{{- toYaml . | nindent 2 }}
{{- end }}
env:
- name: PUID
value: {{ .Values.PUID | quote }}
- name: PGID
value: {{ .Values.PGID | quote }}
- name: UMASK
value: {{ .Values.UMASK | quote }}
{{- if .Values.timezone }}
- name: TZ
value: {{ .Values.timezone | quote }}
{{- end }}
{{- if or .Values.env .Values.envTpl .Values.envValueFrom .Values.envVariable .Values.environmentVariables }}
{{- range $envVariable := .Values.environmentVariables }}
{{- if and $envVariable.name $envVariable.value }}
- name: {{ $envVariable.name }}
value: {{ $envVariable.value | quote }}
{{- if or .Values.env .Values.envTpl .Values.envValueFrom .Values.envVariable .Values.envList }}
{{- range $envList := .Values.envList }}
{{- if and $envList.name $envList.value }}
- name: {{ $envList.name }}
value: {{ $envList.value | quote }}
{{- else }}
{{- fail "Please specify name/value for environment variable" }}
{{- end }}
{{- end}}
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $key, $value := .Values.envTpl }}
- name: {{ $key }}
value: {{ tpl $value $ | quote }}
- name: {{ $key }}
value: {{ tpl $value $ | quote }}
{{- end }}
{{- range $key, $value := .Values.envValueFrom }}
- name: {{ $key }}
valueFrom:
{{- $value | toYaml | nindent 8 }}
- name: {{ $key }}
valueFrom:
{{- $value | toYaml | nindent 6 }}
{{- end }}
{{- end }}
{{- with .Values.envFrom }}
{{- if or .Values.envFrom .Values.secret }}
envFrom:
{{- toYaml . | nindent 12 }}
{{- with .Values.envFrom }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- if or .Values.secret }}
- secretRef:
name: {{ include "common.names.fullname" . }}
{{- end }}
{{- end }}
{{- include "common.controller.ports" . | trim | nindent 2 }}
{{- with (include "common.controller.volumeMounts" . | trim) }}
volumeMounts:
{{- . | nindent 2 }}
{{- end }}
{{- include "common.controller.probes" . | nindent 2 }}
{{/*
Merges the TrueNAS SCALE generated GPU info with the .Values.resources dict
*/}}
{{- $resources := dict "limits" ( .Values.scaleGPU | default dict ) }}
{{- $resources = merge $resources .Values.resources }}
resources:
{{- with .Values.resources }}
{{- with $resources }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if and .Values.gpuConfiguration }}
limits:
{{- toYaml .Values.gpuConfiguration | nindent 6 }}
{{- end }}
{{- end -}}

View File

@@ -24,9 +24,7 @@ hostNetwork: {{ . }}
hostname: {{ . }}
{{- end }}
{{- if .Values.dnsPolicy }}
{{- with .Values.dnsPolicy }}
dnsPolicy: {{ . }}
{{- end }}
dnsPolicy: {{ .Values.dnsPolicy }}
{{- else if .Values.hostNetwork }}
dnsPolicy: "ClusterFirstWithHostNet"
{{- else }}
@@ -44,7 +42,7 @@ initContainers:
containers:
{{- include "common.controller.mainContainer" . | nindent 0 }}
{{- with .Values.additionalContainers }}
{{- toYaml . | nindent 0 }}
{{- tpl (toYaml .) $ | nindent 0 }}
{{- end }}
{{- with (include "common.controller.volumes" . | trim) }}
volumes:

View File

@@ -1,34 +1,13 @@
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
`SPDX-License-Identifier: Apache-2.0`
This file is considered to be modified by the TrueCharts Project.
*/}}
{{/*
Ports included by the controller.
*/}}
{{- define "common.controller.ports" -}}
{{- $ports := list -}}
{{/* append the ports for each appAdditionalService - TrueCharts */}}
{{/* append the ports for each service */}}
{{- if $.Values.services -}}
{{- range $name, $_ := $.Values.services }}
{{- if or ( .enabled ) ( eq $name "main" ) -}}
{{- if eq $name "main" -}}
{{- $_ := set .port "name" (default "http" .port.name) -}}
{{- else if kindIs "string" $name -}}
{{- if .enabled -}}
{{- if kindIs "string" $name -}}
{{- $_ := set .port "name" (default .port.name | default $name) -}}
{{- else -}}
{{- $_ := set .port "name" (required "Missing port.name" .port.name) -}}
@@ -42,19 +21,6 @@ Ports included by the controller.
{{- end }}
{{- end }}
{{- if $.Values.additionalServices -}}
{{- range $_ := $.Values.additionalServices }}
{{- if .enabled -}}
{{- $_ := set .port "name" (required "Missing port.name" .port.name) -}}
{{- $ports = mustAppend $ports .port -}}
{{- range $_ := .additionalPorts -}}
{{/* append the additonalPorts for each additional service */}}
{{- $ports = mustAppend $ports . -}}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{/* export/render the list of ports */}}
{{- if $ports -}}
ports:

View File

@@ -21,7 +21,8 @@ This file is considered to be modified by the TrueCharts Project.
Probes selection logic.
*/}}
{{- define "common.controller.probes" -}}
{{- $svcPort := .Values.services.main.port.name -}}
{{- $svc := index .Values.services (keys .Values.services | first) -}}
{{- $svcPort := $svc.port.name -}}
{{- range $probeName, $probe := .Values.probes }}
{{- if $probe.enabled -}}
{{- "" | nindent 0 }}

View File

@@ -1,11 +1,11 @@
{{/*
Volumes included by the controller.
*/}}
{{- define "common.controller.volumeMounts" -}}
{{- range $index, $PVC := .Values.persistence }}
{{- if and ( $PVC.enabled ) ( $PVC.mountPath ) }}
- mountPath: {{ $PVC.mountPath }}
{{- if $PVC.enabled }}
- mountPath: {{ $PVC.mountPath | default (printf "/%v" $index) }}
name: {{ $index }}
{{- if $PVC.subPath }}
subPath: {{ $PVC.subPath }}
@@ -13,7 +13,9 @@ Volumes included by the controller.
{{- end }}
{{- end }}
{{/*
Creates mountpoints to mount devices directly to the same path inside the container
*/}}
{{ range $name, $dmm := .Values.deviceMounts }}
{{- if $dmm.enabled -}}
{{ if $dmm.name }}
@@ -27,28 +29,29 @@ Volumes included by the controller.
{{- end -}}
{{ end }}
{{ range $name, $csm := .Values.customStorage }}
{{- if $csm.enabled -}}
{{ if $csm.name }}
{{ $name = $csm.name }}
{{/*
Creates mountpoints to mount hostPaths directly to the container
*/}}
{{ range $name, $hpm := .Values.hostPathMounts }}
{{- if $hpm.enabled -}}
{{ if $hpm.name }}
{{ $name = $hpm.name }}
{{ end }}
- name: customstorage-{{ $name }}
mountPath: {{ $csm.mountPath }}
{{ if $csm.subPath }}
subPath: {{ $csm.subPath }}
- name: hostpathmounts-{{ $name }}
mountPath: {{ $hpm.mountPath }}
{{ if $hpm.subPath }}
subPath: {{ $hpm.subPath }}
{{ end }}
{{ if $csm.readOnly }}
readOnly: {{ $csm.readOnly }}
{{ if $hpm.readOnly }}
readOnly: {{ $hpm.readOnly }}
{{ end }}
{{- end -}}
{{ end }}
{{- if .Values.additionalVolumeMounts }}
{{- toYaml .Values.additionalVolumeMounts | nindent 0 }}
{{- toYaml .Values.additionalVolumeMounts | nindent 0 }}
{{- end }}
{{- if eq .Values.controllerType "statefulset" }}
{{- range $index, $vct := .Values.volumeClaimTemplates }}
- mountPath: {{ $vct.mountPath }}

View File

@@ -29,23 +29,46 @@ Volumes included by the controller.
persistentVolumeClaim:
claimName: {{ $persistence.existingClaim }}
{{- else -}}
{{- if $persistence.emptyDir -}}
{{- /* Always prefer an emptyDir next if that is set */}}
{{- $emptyDir := false -}}
{{- if $persistence.emptyDir -}}
{{- if $persistence.emptyDir.enabled -}}
{{- $emptyDir = true -}}
{{- end -}}
{{- end -}}
{{- if $emptyDir }}
{{- if or $persistence.emptyDir.medium $persistence.emptyDir.sizeLimit }}
emptyDir:
{{- with $persistence.emptyDir.medium }}
medium: "{{ . }}"
{{- end }}
{{- with $persistence.emptyDir.sizeLimit }}
sizeLimit: "{{ . }}"
{{- end }}
{{- else }}
emptyDir: {}
{{- end }}
{{- else -}}
{{- /* Otherwise refer to the PVC name */}}
persistentVolumeClaim:
{{- if $persistence.nameOverride }}
claimName: {{ $persistence.nameOverride }}
{{- else if $persistence.nameSuffix }}
claimName: {{ printf "%s-%s" (include "common.names.fullname" $) $persistence.nameSuffix }}
{{- else }}
claimName: {{ printf "%s-%s" (include "common.names.fullname" $) $index }}
{{- end }}
{{- $pvcName := (include "common.names.fullname" $) -}}
{{- if $persistence.nameOverride -}}
{{- $pvcName = $persistence.nameOverride -}}
{{- else if $persistence.nameSuffix -}}
{{- if not (eq $persistence.nameSuffix "-") -}}
{{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $persistence.nameSuffix) -}}
{{- end -}}
{{- else -}}
{{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $index) -}}
{{- end }}
persistentVolumeClaim:
claimName: {{ $pvcName }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.additionalVolumes }}
{{- toYaml .Values.additionalVolumes | nindent 0 }}
{{- end }}
{{- range $name, $dm := .Values.deviceMounts -}}
{{ if $dm.enabled }}
@@ -62,23 +85,22 @@ Volumes included by the controller.
{{ end }}
{{- end -}}
{{- range $name, $cs := .Values.customStorage -}}
{{ if $cs.enabled }}
{{ if $cs.name }}
{{ $name = $cs.name }}
{{/*
Creates Volumes for hostPaths which can be directly mounted to a container
*/}}
{{- range $name, $hpm := .Values.hostPathMounts -}}
{{ if $hpm.enabled }}
{{ if $hpm.name }}
{{ $name = $hpm.name }}
{{ end }}
- name: customstorage-{{ $name }}
{{ if $cs.emptyDir }}
- name: hostpathmounts-{{ $name }}
{{ if $hpm.emptyDir }}
emptyDir: {}
{{- else -}}
hostPath:
path: {{ required "hostPath not set" $cs.hostPath }}
path: {{ required "hostPath not set" $hpm.hostPath }}
{{ end }}
{{ end }}
{{- end -}}
{{- if .Values.additionalVolumes }}
{{- toYaml .Values.additionalVolumes | nindent 0 }}
{{- end }}
{{- end -}}

View File

@@ -1,32 +0,0 @@
{{/*
Retrieve true/false if certificate is configured
*/}}
{{- define "common.resources.cert.available" -}}
{{- if .ObjectValues.certHolder.certificate -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.certificate) -}}
{{- template "common.resources.cert_present" $values -}}
{{- else -}}
{{- false -}}
{{- end -}}
{{- end -}}
{{/*
Retrieve public key of certificate
*/}}
{{- define "common.resources.cert.publicKey" -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.certificate "publicKey" true) -}}
{{ include "common.resources.cert" $values }}
{{- end -}}
{{/*
Retrieve private key of certificate
*/}}
{{- define "common.resources.cert.privateKey" -}}
{{- $values := (. | mustDeepCopy) -}}
{{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.certificate) -}}
{{ include "common.resources.cert" $values }}
{{- end -}}

View File

@@ -1,25 +0,0 @@
{{- define "common.resources.cert.secret" -}}
{{- $secretName := include "common.names.fullname" . -}}
{{- if .ObjectValues.certHolder -}}
{{- if hasKey .ObjectValues.certHolder "nameSuffix" -}}
{{- $secretName = printf "%v-%v" $secretName .ObjectValues.certHolder.nameSuffix -}}
{{ end -}}
{{ else }}
{{- $_ := set $ "ObjectValues" (dict "certHolder" .Values) -}}
{{ end -}}
{{- if eq (include "common.resources.cert.available" $ ) "true" -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ $secretName }}
labels: {{ include "common.labels" . | nindent 4 }}
type: kubernetes.io/tls
data:
tls.crt: {{ (include "common.resources.cert.publicKey" $ ) | toString | b64enc | quote }}
tls.key: {{ (include "common.resources.cert.privateKey" $ ) | toString | b64enc | quote }}
{{- end -}}
{{- end -}}

View File

@@ -1,24 +0,0 @@
{{/*
Retrieve true/false if certificate is available in ixCertificates
*/}}
{{- define "common.resources.cert_present" -}}
{{- $values := . -}}
{{- hasKey $values.Values.ixCertificates ($values.commonCertOptions.certKeyName | toString) -}}
{{- end -}}
{{/*
Retrieve certificate from variable name
*/}}
{{- define "common.resources.cert" -}}
{{- $values := . -}}
{{- $certKey := ($values.commonCertOptions.certKeyName | toString) -}}
{{- if hasKey $values.Values.ixCertificates $certKey -}}
{{- $cert := get $values.Values.ixCertificates $certKey -}}
{{- if $values.commonCertOptions.publicKey -}}
{{ $cert.certificate }}
{{- else -}}
{{ $cert.privatekey }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -1,64 +0,0 @@
{{- define "common.resources.portal" -}}
{{- if .Values.portal }}
{{- if .Values.portal.enabled }}
{{- $host := "$node_ip" }}
{{- $port := 443 }}
{{- $protocol := "https" }}
{{- $portProtocol := "" }}
{{- if hasKey .Values "ingress" }}
{{- if hasKey .Values.ingress "main" -}}
{{- if .Values.ingress.main.host }}
{{- $host = .Values.ingress.main.host }}
{{- else }}
{{- range .Values.ingress.main.hosts }}
{{- $host = ( .host | quote ) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if and ( .Values.portal.ingressPort ) ( ne $host "$node_ip" ) }}
{{- $port = .Values.portal.ingressPort }}
{{- else if and ( eq $host "$node_ip" ) ( hasKey .Values "services" ) }}
{{- if hasKey .Values.services "main" }}
{{- if and (hasKey .Values.services.main.port "nodePort" ) ( eq .Values.services.main.type "NodePort" ) }}
{{- $port = .Values.services.main.port.nodePort }}
{{- if or ( eq .Values.services.main.port.protocol "HTTP" ) ( eq .Values.services.main.port.protocol "HTTPS" ) }}
{{- $portProtocol = .Values.services.main.port.protocol }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if and ( $portProtocol ) ( eq $host "$node_ip" ) }}
{{- $protocol = $portProtocol }}
{{- else if and ( ne $host "$node_ip" ) }}
{{- if .Values.ingress.main.certType }}
{{- if eq .Values.ingress.main.certType "" }}
{{- $protocol = "http" }}
{{- end }}
{{- end }}
{{- end }}
{{- if and ( .Values.portal.host ) ( eq $host "$node_ip" ) }}
{{- $host = .Values.portal.host }}
{{- end }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: portal
labels: {{ include "common.labels" . | nindent 4 }}
data:
protocol: {{ $protocol }}
host: {{ $host }}
port: {{ $port | quote }}
url: {{ printf "%v%v%v%v%v" $protocol "://" $host ":" $port }}
{{- end }}
{{- end }}
{{- end -}}

View File

@@ -1,77 +0,0 @@
{{/*
This template serves as the blueprint for the mountPermissions job that is run
before chart installation.
*/}}
{{- define "common.storage.permissions" -}}
{{- if .Values.fixMountPermissions }}
{{- $jobName := include "common.names.fullname" . -}}
{{- $values := .Values -}}
{{- print "---" | nindent 0 -}}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $jobName }}-autopermissions
labels:
{{- include "common.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-10"
"helm.sh/hook-delete-policy": hook-succeeded,hook-failed,before-hook-creation
spec:
template:
metadata:
spec:
restartPolicy: Never
containers:
- name: set-mount-permissions
image: "alpine:3.3"
command:
- /bin/sh
- -c
- | {{ range $index, $cs := .Values.customStorage}}{{ if and $cs.enabled $cs.setPermissions}}
chown -R {{ if eq $values.podSecurityContext.runAsNonRoot false }}{{ print $values.PUID }}{{ else }}{{ print $values.podSecurityContext.runAsUser }}{{ end }}:{{ print $values.podSecurityContext.fsGroup }} {{ print $cs.mountPath }}{{ end }}{{ end }}
#args:
#
#securityContext:
#
volumeMounts:
{{ range $name, $csm := .Values.customStorage }}
{{- if $csm.enabled -}}
{{- if $csm.setPermissions -}}
{{ if $csm.name }}
{{ $name = $csm.name }}
{{ end }}
- name: customstorage-{{ $name }}
mountPath: {{ $csm.mountPath }}
{{ if $csm.subPath }}
subPath: {{ $csm.subPath }}
{{ end }}
{{- end -}}
{{- end -}}
{{ end }}
volumes:
{{- range $name, $cs := .Values.customStorage -}}
{{ if $cs.enabled }}
{{ if $cs.setPermissions }}
{{ if $cs.name }}
{{ $name = $cs.name }}
{{ end }}
- name: customstorage-{{ $name }}
{{ if $cs.emptyDir }}
emptyDir: {}
{{- else -}}
hostPath:
path: {{ required "hostPath not set" $cs.hostPath }}
{{ end }}
{{ end }}
{{ end }}
{{- end -}}
{{- end }}
{{- end }}

View File

@@ -82,12 +82,12 @@ hostNetwork: false
enableServiceLinks: true
# Configure the Security Context for the Pod
podSecurityContext:
runAsNonRoot: true
runAsUser: 568
runAsGroup: 568
fsGroup: 568
fsGroupChangePolicy: "OnRootMismatch"
# podSecurityContext:
# runAsNonRoot: true
# runAsUser: 568
# runAsGroup: 568
# fsGroup: 568
# fsGroupChangePolicy: "OnRootMismatch"
# Configure the Security Context for the main container
securityContext: {}
@@ -141,11 +141,14 @@ services:
enabled: true
type: ClusterIP
## Specify the default port information
## It is adviced not to mix different port protocols on the same service
port:
port:
## name defaults to http
name:
protocol: TCP
## Accepts: HTTP, HTTPS, TCP and UDP
## HTTPS and HTTPS spawn a TCP service and get used for internal URL and name generation
protocol: HTTP
## Specify a service targetPort if you wish to differ the service port from the application port.
## If targetPort is specified, this port number is used in the container definition instead of
## service.port.port. Therefore named ports are not supported for this field.
@@ -163,60 +166,21 @@ services:
annotations: {}
labels: {}
additionalServices: []
# - enabled: false
# nameSuffix: api
# type: ClusterIP
# # Specify the default port information
# port:
# port:
# # name defaults to http
# name:
# protocol: TCP
# # targetPort defaults to http
# targetPort:
# # nodePort:
# additionalPorts: []
# annotations: {}
# labels: {}
# ingress:
# main:
# enabled: false
# # Used when including ingress using {{ include "common.ingress" . }}
# type: "HTTP"
# entrypoint: "websecure"
# certType: ""
# ## Optional: defaults to IngressName
# serviceName: ""
# ## Optional: Almost never needed
# serviceKind: ""
# ## Optional: defaults to either service port
# servicePort: 80
# annotations: {}
# # kubernetes.io/ingress.class: nginx
# # kubernetes.io/tls-acme: "true"
# labels: {}
# hosts:
# - host: chart-example.local
# path: /
# additionalIngresses: []
# - enabled: false
# nameSuffix: "api"
# annotations: {}
# # kubernetes.io/ingress.class: nginx
# # kubernetes.io/tls-acme: "true"
# labels: {}
# hosts:
# - host: chart-example.local
# paths:
# - path: /api
# # Ignored if not kubeVersion >= 1.14-0
# pathType: Prefix
# tls: []
# # - secretName: chart-example-tls
# # hosts:
# # - chart-example.local
## additionalServices can be created as either a dict.
# additionalService:
# type: ClusterIP
# # Specify the default port information
# port:
# port:
# # name defaults to http
# name:
# protocol: TCP
# # targetPort defaults to http
# targetPort:
# # nodePort:
# additionalPorts: []
# annotations: {}
# labels: {}
persistence:
config:
@@ -243,7 +207,8 @@ persistence:
# Create an emptyDir volume to share between all containers
shared:
enabled: false
emptyDir: true
emptyDir:
enabled: true
mountPath: /shared
additionalVolumes: []
@@ -289,12 +254,10 @@ resources: {}
# cpu: 100m
# memory: 128Mi
## TrueCharts Specific
## Used by TrueNAS SCALE to easily set add GPU's to Apps
# scaleGPU: {}
PUID: 568
PGID: 568
UMASK: "002"
fixMountPermissions: true
## TrueCharts Specific
# deviceMounts:
# config:
@@ -312,3 +275,60 @@ fixMountPermissions: true
# hostPath: ""
# readOnly: false
# setPermissions: true
ingress:
main:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
labels: {}
# ingressClassName: "nginx"
hosts:
- host: chart-example.local
## Or a tpl that is evaluated
# hostTpl: '{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.ingress.domainname }}'
paths:
- path: /
## Or a tpl that is evaluated
# pathTpl: '{{ include "common.names.fullname" . }}'
## Ignored if not kubeVersion >= 1.14-0
pathType: Prefix
tls: []
# - secretName: chart-example-tls
## Or if you need a dynamic secretname
# - secretNameTpl: '{{ include "common.names.fullname" . }}-ingress'
# hosts:
# - chart-example.local
## Or a tpl that is evaluated
# hostsTpl:
# - '{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.ingress.domainname }}'
# additionalIngress:
# annotations: {}
# # kubernetes.io/ingress.class: nginx
# # kubernetes.io/tls-acme: "true"
# labels: {}
# hosts:
# - host: chart-example.local
# paths:
# - path: /api
# # Ignored if not kubeVersion >= 1.14-0
# pathType: Prefix
# serviceName: # optionally target a specific service
# servicePort: # optionally target a specific service port
# tls: []
# # - secretName: chart-example-tls
# # hosts:
# # - chart-example.local
# ## Adds a portal configmap for use with TrueNAS SCALE
# ## This should not be enabled on other systems than TrueNAS SCALE,
# ## Because it requires a seperate namespace for each chart.
# portal:
# enabled: false
# ## Override default port used for the portal button when using ingress.
# # ingressPort: 80
# ## Override hostname used for the portal button when using nodePort
# # host: 192.168.0.2
# ## Override the path used in the url
# # path: /example

View File

@@ -0,0 +1,322 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'scaleCertificate' do
it 'disabled by default' do
values = {
ingress: {
main: {
enabled: true
}
}
}
chart.value values
assert_nil(resource('Secret'))
end
it 'can be enabled and selected' do
values = {
"ixCertificateAuthorities": {},
"ixCertificates": {
"1": {
"CA_type_existing": false,
"CA_type_intermediate": false,
"CA_type_internal": false,
"CSR": "",
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
"cert_type": "CERTIFICATE",
"cert_type_CSR": false,
"cert_type_existing": true,
"cert_type_internal": false,
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
"certificate_path": "/etc/certificates/freenas_default.crt",
"chain": false,
"chain_list": [
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
],
"city": "Maryville",
"common": "localhost",
"country": "US",
"csr_path": "/etc/certificates/freenas_default.csr",
"digest_algorithm": "SHA256",
"email": "info@ixsystems.com",
"extensions": {
"ExtendedKeyUsage": "TLS Web Server Authentication",
"SubjectAltName": "DNS:localhost"
},
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
"from": "Fri Sep 25 16:05:38 2020",
"id": 1,
"internal": "NO",
"issuer": "external",
"key_length": 2048,
"key_type": "RSA",
"lifetime": 825,
"name": "freenas_default",
"organization": "iXsystems",
"organizational_unit": "",
"parsed": true,
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
"privatekey_path": "/etc/certificates/freenas_default.key",
"revoked": false,
"revoked_date": "",
"root_path": "/etc/certificates",
"san": [
"DNS:localhost"
],
"serial": 1,
"signedby": "",
"state": "Tennessee",
"subject_name_hash": 3193428416,
"type": 8,
"until": "Thu Dec 29 15:05:38 2022"
}
},
ingress: {
main: {
enabled: true,
tls: [
{
scaleCert: 1
}
]
}
}
}
chart.value values
refute_nil(resource('Secret'))
secret = chart.resources(kind: "Secret").first
assert_equal("common-test-main-tls-0-ixcert-1", secret["metadata"]["name"])
refute_nil(secret["data"]["tls.crt"])
refute_nil(secret["data"]["tls.key"])
end
it 'secret can be used for TLS ingress' do
values = {
"ixCertificateAuthorities": {},
"ixCertificates": {
"1": {
"CA_type_existing": false,
"CA_type_intermediate": false,
"CA_type_internal": false,
"CSR": "",
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
"cert_type": "CERTIFICATE",
"cert_type_CSR": false,
"cert_type_existing": true,
"cert_type_internal": false,
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
"certificate_path": "/etc/certificates/freenas_default.crt",
"chain": false,
"chain_list": [
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
],
"city": "Maryville",
"common": "localhost",
"country": "US",
"csr_path": "/etc/certificates/freenas_default.csr",
"digest_algorithm": "SHA256",
"email": "info@ixsystems.com",
"extensions": {
"ExtendedKeyUsage": "TLS Web Server Authentication",
"SubjectAltName": "DNS:localhost"
},
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
"from": "Fri Sep 25 16:05:38 2020",
"id": 1,
"internal": "NO",
"issuer": "external",
"key_length": 2048,
"key_type": "RSA",
"lifetime": 825,
"name": "freenas_default",
"organization": "iXsystems",
"organizational_unit": "",
"parsed": true,
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
"privatekey_path": "/etc/certificates/freenas_default.key",
"revoked": false,
"revoked_date": "",
"root_path": "/etc/certificates",
"san": [
"DNS:localhost"
],
"serial": 1,
"signedby": "",
"state": "Tennessee",
"subject_name_hash": 3193428416,
"type": 8,
"until": "Thu Dec 29 15:05:38 2022"
}
},
ingress: {
main: {
enabled: true,
tls: [
{
hosts: [ 'hostname' ],
scaleCert: 1
}
]
}
}
}
chart.value values
refute_nil(resource('Secret'))
secret = chart.resources(kind: "Secret").first
assert_equal("common-test-main-tls-0-ixcert-1", secret["metadata"]["name"])
refute_nil(secret["data"]["tls.crt"])
refute_nil(secret["data"]["tls.key"])
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal("common-test-main-tls-0-ixcert-1", ingress["spec"]["tls"][0]["secretName"])
end
it 'multiple tls sections generate multiple secrets' do
values = {
"ixCertificateAuthorities": {},
"ixCertificates": {
"2": {
"CA_type_existing": false,
"CA_type_intermediate": false,
"CA_type_internal": false,
"CSR": "",
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
"cert_type": "CERTIFICATE",
"cert_type_CSR": false,
"cert_type_existing": true,
"cert_type_internal": false,
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
"certificate_path": "/etc/certificates/freenas_default.crt",
"chain": false,
"chain_list": [
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
],
"city": "Maryville",
"common": "localhost",
"country": "US",
"csr_path": "/etc/certificates/freenas_default.csr",
"digest_algorithm": "SHA256",
"email": "info@ixsystems.com",
"extensions": {
"ExtendedKeyUsage": "TLS Web Server Authentication",
"SubjectAltName": "DNS:localhost"
},
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
"from": "Fri Sep 25 16:05:38 2020",
"id": 2,
"internal": "NO",
"issuer": "external",
"key_length": 2048,
"key_type": "RSA",
"lifetime": 825,
"name": "freenas_default",
"organization": "iXsystems",
"organizational_unit": "",
"parsed": true,
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
"privatekey_path": "/etc/certificates/freenas_default.key",
"revoked": false,
"revoked_date": "",
"root_path": "/etc/certificates",
"san": [
"DNS:localhost"
],
"serial": 1,
"signedby": "",
"state": "Tennessee",
"subject_name_hash": 3193428416,
"type": 8,
"until": "Thu Dec 29 15:05:38 2022"
},
"1": {
"CA_type_existing": false,
"CA_type_intermediate": false,
"CA_type_internal": false,
"CSR": "",
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
"cert_type": "CERTIFICATE",
"cert_type_CSR": false,
"cert_type_existing": true,
"cert_type_internal": false,
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
"certificate_path": "/etc/certificates/freenas_default.crt",
"chain": false,
"chain_list": [
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
],
"city": "Maryville",
"common": "localhost",
"country": "US",
"csr_path": "/etc/certificates/freenas_default.csr",
"digest_algorithm": "SHA256",
"email": "info@ixsystems.com",
"extensions": {
"ExtendedKeyUsage": "TLS Web Server Authentication",
"SubjectAltName": "DNS:localhost"
},
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
"from": "Fri Sep 25 16:05:38 2020",
"id": 1,
"internal": "NO",
"issuer": "external",
"key_length": 2048,
"key_type": "RSA",
"lifetime": 825,
"name": "freenas_default",
"organization": "iXsystems",
"organizational_unit": "",
"parsed": true,
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
"privatekey_path": "/etc/certificates/freenas_default.key",
"revoked": false,
"revoked_date": "",
"root_path": "/etc/certificates",
"san": [
"DNS:localhost"
],
"serial": 1,
"signedby": "",
"state": "Tennessee",
"subject_name_hash": 3193428416,
"type": 8,
"until": "Thu Dec 29 15:05:38 2022"
}
},
ingress: {
main: {
enabled: true,
tls: [
{
hosts: [ 'hostname1' ],
scaleCert: 1
},
{
hosts: [ 'hostname2' ],
scaleCert: 2
}
]
}
}
}
chart.value values
refute_nil(resource('Secret'))
secret1 = chart.resources(kind: "Secret").first
assert_equal("common-test-main-tls-0-ixcert-1", secret1["metadata"]["name"])
refute_nil(secret1["data"]["tls.crt"])
refute_nil(secret1["data"]["tls.key"])
secret2 = chart.resources(kind: "Secret").find{ |s| s["metadata"]["name"] == "common-test-main-tls-1-ixcert-2" }
refute_nil(secret2)
refute_nil(secret2["data"]["tls.crt"])
refute_nil(secret2["data"]["tls.key"])
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal("common-test-main-tls-0-ixcert-1", ingress["spec"]["tls"][0]["secretName"])
assert_equal("common-test-main-tls-1-ixcert-2", ingress["spec"]["tls"][1]["secretName"])
end
end
end
end

View File

@@ -0,0 +1,90 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'container::resources' do
it 'no resources added by default' do
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{}}, mainContainer["resources"])
end
it 'resources can be added' do
values = {
resources: {
testresourcename: "testresourcevalue"
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{}, "testresourcename"=>"testresourcevalue"}, mainContainer["resources"])
end
it 'resources.limits can be added' do
values = {
resources: {
limits: {
testlimitkey: "testlimitvalue"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{"testlimitkey"=>"testlimitvalue"}}, mainContainer["resources"])
end
it 'resources and resources.limits can both be added' do
values = {
resources: {
testresourcekey: "testresourcevalue",
limits: {
testlimitkey: "testlimitvalue"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{"testlimitkey"=>"testlimitvalue"}, "testresourcekey"=>"testresourcevalue"}, mainContainer["resources"])
end
end
describe 'container::resources-scaleGPU' do
it 'scaleGPU can be set' do
values = {
scaleGPU: {
intelblabla: 1
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{"intelblabla"=>1}}, mainContainer["resources"])
end
it 'scaleGPU can be combined with resources and resource values' do
values = {
resources: {
testresourcekey: "testresourcevalue",
limits: {
testlimitkey: "testlimitvalue"
}
},
scaleGPU: {
intelblabla: 1
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal({"limits"=>{"intelblabla"=>1, "testlimitkey"=>"testlimitvalue"}, "testresourcekey"=>"testresourcevalue"}, mainContainer["resources"])
end
end
end
end

View File

@@ -0,0 +1,380 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'container::command' do
it 'defaults to nil' do
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_nil(mainContainer["command"])
end
it 'accepts a single string' do
values = {
command: "/bin/sh"
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:command], mainContainer["command"])
end
it 'accepts a list of strings' do
values = {
command: [
"/bin/sh",
"-c"
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:command], mainContainer["command"])
end
end
describe 'container::arguments' do
it 'defaults to nil' do
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_nil(mainContainer["args"])
end
it 'accepts a single string' do
values = {
args: "sleep infinity"
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:args], mainContainer["args"])
end
it 'accepts a list of strings' do
values = {
args: [
"sleep",
"infinity"
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:args], mainContainer["args"])
end
end
describe 'container::environment settings' do
it 'Check no environment variables' do
values = {}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_nil(mainContainer["env"])
end
it 'set "static" environment variables' do
values = {
env: {
STATIC_ENV: 'value_of_env',
TRUTHY_ENV: '0',
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][0]["name"])
assert_equal(values[:env].values[0].to_s, mainContainer["env"][0]["value"])
assert_equal(values[:env].keys[1].to_s, mainContainer["env"][1]["name"])
assert_equal(values[:env].values[1].to_s, mainContainer["env"][1]["value"])
end
it 'set "list" of "static" environment variables' do
values = {
envList: [
{
name: 'STATIC_ENV_FROM_LIST',
value: 'STATIC_ENV_VALUE_FROM_LIST'
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:envList][0][:name].to_s, mainContainer["env"][0]["name"])
assert_equal(values[:envList][0][:value].to_s, mainContainer["env"][0]["value"])
end
it 'set both "list" AND "dict" of "static" environment variables' do
values = {
env: {
STATIC_ENV: 'value_of_env'
},
envList: [
{
name: 'STATIC_ENV_FROM_LIST',
value: 'STATIC_ENV_VALUE_FROM_LIST'
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:envList][0][:name].to_s, mainContainer["env"][0]["name"])
assert_equal(values[:envList][0][:value].to_s, mainContainer["env"][0]["value"])
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][1]["name"])
assert_equal(values[:env].values[0].to_s, mainContainer["env"][1]["value"])
end
it 'set "valueFrom" environment variables' do
values = {
envValueFrom: {
NODE_NAME: {
fieldRef: {
fieldPath: "spec.nodeName"
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:envValueFrom].keys[0].to_s, mainContainer["env"][0]["name"])
assert_equal(values[:envValueFrom].values[0][:fieldRef][:fieldPath], mainContainer["env"][0]["valueFrom"]["fieldRef"]["fieldPath"])
end
it 'set "static" and "Dynamic/Tpl" environment variables' do
values = {
env: {
STATIC_ENV: 'value_of_env'
},
envTpl: {
DYN_ENV: "{{ .Release.Name }}-admin"
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][0]["name"])
assert_equal(values[:env].values[0].to_s, mainContainer["env"][0]["value"])
assert_equal(values[:envTpl].keys[0].to_s, mainContainer["env"][1]["name"])
assert_equal("common-test-admin", mainContainer["env"][1]["value"])
end
it 'set "Dynamic/Tpl" environment variables' do
values = {
envTpl: {
DYN_ENV: "{{ .Release.Name }}-admin"
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:envTpl].keys[0].to_s, mainContainer["env"][0]["name"])
assert_equal("common-test-admin", mainContainer["env"][0]["value"])
end
it 'set "static" secret variables' do
expectedSecretName = 'common-test'
values = {
secret: {
STATIC_SECRET: 'value_of_secret'
}
}
chart.value values
secret = chart.resources(kind: "Secret").find{ |s| s["metadata"]["name"] == expectedSecretName }
refute_nil(secret)
assert_equal(values[:secret].values[0].to_s, secret["stringData"]["STATIC_SECRET"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(expectedSecretName, mainContainer["envFrom"][0]["secretRef"]["name"])
end
end
describe 'container::persistence' do
it 'supports multiple volumeMounts' do
values = {
persistence: {
cache: {
enabled: true,
emptyDir: {
enabled: true
}
},
config: {
enabled: true,
existingClaim: "configClaim"
},
data: {
enabled: true,
existingClaim: "dataClaim"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
# Check that all persistent volumes have mounts
values[:persistence].each { |key, value|
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == key.to_s }
refute_nil(volumeMount)
}
end
it 'defaults mountPath to persistence key' do
values = {
persistence: {
data: {
enabled: true,
existingClaim: "dataClaim"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
refute_nil(volumeMount)
assert_equal("/data", volumeMount["mountPath"])
end
it 'supports setting custom mountPath' do
values = {
persistence: {
data: {
enabled: true,
existingClaim: "dataClaim",
mountPath: "/myMountPath"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
refute_nil(volumeMount)
assert_equal("/myMountPath", volumeMount["mountPath"])
end
it 'supports setting subPath' do
values = {
persistence: {
data: {
enabled: true,
existingClaim: "dataClaim",
subPath: "mySubPath"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
refute_nil(volumeMount)
assert_equal("mySubPath", volumeMount["subPath"])
end
end
describe 'container::hostPathMounts' do
it 'supports multiple hostPathMounts' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
mountPath: "/data",
hostPath: "/tmp"
},
{
name: "config",
enabled: true,
mountPath: "/config",
hostPath: "/tmp"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
# Check that all hostPathMounts volumes have mounts
values[:hostPathMounts].each { |value|
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-" + value[:name].to_s }
refute_nil(volumeMount)
}
end
it 'supports setting mountPath' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
mountPath: "/data",
hostPath: "/tmp"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
refute_nil(volumeMount)
assert_equal("/data", volumeMount["mountPath"])
end
it 'supports setting subPath' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
mountPath: "/data",
hostPath: "/tmp",
subPath: "mySubPath"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
refute_nil(volumeMount)
assert_equal("mySubPath", volumeMount["subPath"])
end
end
end
end

View File

@@ -0,0 +1,60 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'controller::type' do
it 'defaults to "Deployment"' do
assert_nil(resource('StatefulSet'))
assert_nil(resource('DaemonSet'))
refute_nil(resource('Deployment'))
end
it 'accepts "statefulset"' do
chart.value controllerType: 'statefulset'
assert_nil(resource('Deployment'))
assert_nil(resource('DaemonSet'))
refute_nil(resource('StatefulSet'))
end
it 'accepts "daemonset"' do
chart.value controllerType: 'daemonset'
assert_nil(resource('Deployment'))
assert_nil(resource('StatefulSet'))
refute_nil(resource('DaemonSet'))
end
end
describe 'controller::statefulset::volumeClaimTemplates' do
it 'volumeClaimTemplates should be empty by default' do
chart.value controllerType: 'statefulset'
statefulset = chart.resources(kind: "StatefulSet").first
assert_nil(statefulset['spec']['volumeClaimTemplates'])
end
it 'can set values for volumeClaimTemplates' do
values = {
controllerType: 'statefulset',
volumeClaimTemplates: [
{
name: 'storage',
accessMode: 'ReadWriteOnce',
size: '10Gi',
storageClass: 'storage'
}
]
}
chart.value values
statefulset = chart.resources(kind: "StatefulSet").first
volumeClaimTemplate = statefulset["spec"]["volumeClaimTemplates"].find{ |v| v["metadata"]["name"] == values[:volumeClaimTemplates][0][:name]}
refute_nil(volumeClaimTemplate)
assert_equal(values[:volumeClaimTemplates][0][:accessMode], volumeClaimTemplate["spec"]["accessModes"][0])
assert_equal(values[:volumeClaimTemplates][0][:size], volumeClaimTemplate["spec"]["resources"]["requests"]["storage"])
assert_equal(values[:volumeClaimTemplates][0][:storageClass], volumeClaimTemplate["spec"]["storageClassName"])
end
end
end
end

View File

@@ -0,0 +1,120 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'hpa::defaults' do
it 'does not exist by default' do
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_nil(hpa)
end
it 'can be enabled' do
values = {
autoscaling: {
enabled: true
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
refute_nil(hpa)
end
it 'default target is common.names.fullname ' do
values = {
autoscaling: {
enabled: true
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal("common-test",hpa["spec"]["scaleTargetRef"]["name"])
end
it 'default numer of replicas is min 1 max 3' do
values = {
autoscaling: {
enabled: true
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal(1,hpa["spec"]["minReplicas"])
assert_equal(3,hpa["spec"]["maxReplicas"])
end
end
describe 'hpa::customsettings' do
it 'can override target' do
values = {
autoscaling: {
enabled: true,
target: "targetname"
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal(values[:autoscaling][:target],hpa["spec"]["scaleTargetRef"]["name"])
end
it 'can change min and max replicas' do
values = {
autoscaling: {
enabled: true,
minReplicas: 4,
maxReplicas: 8
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal(values[:autoscaling][:minReplicas],hpa["spec"]["minReplicas"])
assert_equal(values[:autoscaling][:maxReplicas],hpa["spec"]["maxReplicas"])
end
it 'can set targetCPUUtilizationPercentage' do
values = {
autoscaling: {
enabled: true,
targetCPUUtilizationPercentage: 60
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal("cpu",hpa["spec"]["metrics"][0]["resource"]["name"])
assert_equal(values[:autoscaling][:targetCPUUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
end
it 'can set targetMemoryUtilizationPercentage' do
values = {
autoscaling: {
enabled: true,
targetMemoryUtilizationPercentage: 70
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal("memory",hpa["spec"]["metrics"][0]["resource"]["name"])
assert_equal(values[:autoscaling][:targetMemoryUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
end
it 'can set both targetCPU and targetMemoryUtilizationPercentage' do
values = {
autoscaling: {
enabled: true,
targetCPUUtilizationPercentage: 60,
targetMemoryUtilizationPercentage: 70
}
}
chart.value values
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
assert_equal("cpu",hpa["spec"]["metrics"][0]["resource"]["name"])
assert_equal(values[:autoscaling][:targetCPUUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
assert_equal("memory",hpa["spec"]["metrics"][1]["resource"]["name"])
assert_equal(values[:autoscaling][:targetMemoryUtilizationPercentage],hpa["spec"]["metrics"][1]["resource"]["targetAverageUtilization"])
end
end
end
end

View File

@@ -0,0 +1,281 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'ingress' do
it 'disabled when ingress.main.enabled: false' do
values = {
ingress: {
main: {
enabled: false
}
}
}
chart.value values
assert_nil(resource('Ingress'))
end
it 'enabled when ingress.main.enabled: true' do
values = {
ingress: {
main: {
enabled: true
}
}
}
chart.value values
refute_nil(resource('Ingress'))
end
it 'tls can be provided' do
expectedPath = 'common-test.path'
values = {
ingress: {
main: {
enabled: true,
tls: [
{
hosts: [ 'hostname' ],
secretName: 'secret-name'
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal(values[:ingress][:main][:tls][0][:hosts][0], ingress["spec"]["tls"][0]["hosts"][0])
assert_equal(values[:ingress][:main][:tls][0][:secretName], ingress["spec"]["tls"][0]["secretName"])
end
it 'tls secret can be left empty' do
expectedPath = 'common-test.path'
values = {
ingress: {
main: {
enabled: true,
tls: [
{
hosts: [ 'hostname' ]
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal(values[:ingress][:main][:tls][0][:hosts][0], ingress["spec"]["tls"][0]["hosts"][0])
assert_equal(false, ingress["spec"]["tls"][0].key?("secretName"))
assert_nil(ingress["spec"]["tls"][0]["secretName"])
end
it 'tls secret template can be provided' do
expectedPath = 'common-test.path'
values = {
ingress: {
main: {
enabled: true,
tls: [
{
secretNameTpl: '{{ .Release.Name }}-secret'
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal('common-test-secret', ingress["spec"]["tls"][0]["secretName"])
end
it 'path template can be provided' do
expectedPath = 'common-test.path'
values = {
ingress: {
main: {
enabled: true,
hosts: [
{
paths: [
{
pathTpl: '{{ .Release.Name }}.path'
}
]
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal(expectedPath, ingress["spec"]["rules"][0]["http"]["paths"][0]["path"])
end
it 'hosts can be provided' do
values = {
ingress: {
main: {
enabled: true,
hosts: [
{
host: 'hostname'
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal(values[:ingress][:main][:hosts][0][:host], ingress["spec"]["rules"][0]["host"])
end
it 'hosts template can be provided' do
expectedHostName = 'common-test.hostname'
values = {
ingress: {
main: {
enabled: true,
hosts: [
{
hostTpl: '{{ .Release.Name }}.hostname'
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
refute_nil(ingress)
assert_equal(expectedHostName, ingress["spec"]["rules"][0]["host"])
end
it 'custom service name / port can optionally be set on path level' do
values = {
ingress: {
main: {
enabled: true,
hosts: [
{
paths: [
{
path: '/'
},
{
path: '/second',
serviceName: 'pathService',
servicePort: 1234
}
]
}
]
}
}
}
chart.value values
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
firstPath = ingress["spec"]["rules"][0]["http"]["paths"][0]
secondPath = ingress["spec"]["rules"][0]["http"]["paths"][1]
assert_equal("common-test", firstPath["backend"]["service"]["name"])
assert_equal(8080, firstPath["backend"]["service"]["port"]["number"])
assert_equal("pathService", secondPath["backend"]["service"]["name"])
assert_equal(1234, secondPath["backend"]["service"]["port"]["number"])
end
end
describe 'additionalIngress' do
ingressValues = {
ingress: {
extra: {
enabled: true,
hosts: [
{
paths: [
{
path: '/'
}
]
}
]
}
}
}
it 'can be specified' do
values = ingressValues
chart.value values
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
refute_nil(additionalIngress)
end
it 'refers to main Service by default' do
values = ingressValues
chart.value values
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
assert_equal("common-test", additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["name"])
assert_equal(8080, additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["port"]["number"])
end
it 'custom service name / port can be set on Ingress level' do
values = ingressValues.deep_merge_override({
ingress: {
extra: {
serviceName: "customService",
servicePort: 8081
}
}
})
chart.value values
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
assert_equal("customService", additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["name"])
assert_equal(8081, additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["port"]["number"])
end
it 'custom service name / port can optionally be set on path level' do
values = ingressValues.deep_merge_override({
ingress: {
extra: {
hosts: [
{
paths: [
{
path: '/'
},
{
path: '/second',
serviceName: 'pathService',
servicePort: 1234
}
]
}
]
}
}
})
chart.value values
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
firstPath = additionalIngress["spec"]["rules"][0]["http"]["paths"][0]
secondPath = additionalIngress["spec"]["rules"][0]["http"]["paths"][1]
assert_equal("common-test", firstPath["backend"]["service"]["name"])
assert_equal(8080, firstPath["backend"]["service"]["port"]["number"])
assert_equal("pathService", secondPath["backend"]["service"]["name"])
assert_equal(1234, secondPath["backend"]["service"]["port"]["number"])
end
end
end
end

View File

@@ -0,0 +1,347 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'job::permissions' do
it 'no job exists by default' do
job = chart.resources(kind: "Job").first
assert_nil(job)
end
it 'hostPathMounts do not affect permissions job by default' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
mountPath: "/data",
hostPath: "/tmp"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
assert_nil(job["spec"]["template"]["spec"]["volumes"])
assert_nil(job["spec"]["template"]["spec"]["containers"][0]["volumeMounts"])
end
it 'hostPathMounts.setPermissions adds volume(mounts)' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
assert_equal("hostpathmounts-data", job["spec"]["template"]["spec"]["volumes"][0]["name"])
assert_equal("hostpathmounts-data", job["spec"]["template"]["spec"]["containers"][0]["volumeMounts"][0]["name"])
end
it 'supports multiple hostPathMounts' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
# Check that all hostPathMounts volumes have mounts
values[:hostPathMounts].each { |value|
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-" + value[:name].to_s }
refute_nil(volumeMount)
}
end
it 'supports setting mountPath' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
refute_nil(volumeMount)
assert_equal("/data", volumeMount["mountPath"])
end
it 'could mount multiple volumes' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
volumes = job["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
refute_nil(volume)
assert_equal('/tmp1', volume["hostPath"]["path"])
volume = volumes.find{ |v| v["name"] == "hostpathmounts-config"}
refute_nil(volume)
assert_equal('/tmp2', volume["hostPath"]["path"])
end
it 'emptyDir can be enabled' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
emptyDir: true,
mountPath: "/data"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
volumes = job["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
refute_nil(volume)
assert_equal(Hash.new, volume["emptyDir"])
end
it 'can process default (568:568) permissions for multiple volumes' do
results= {
command: ["/bin/sh", "-c", "chown -R 568:568 /data
chown -R 568:568 /config
"]
}
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
it 'outputs default permissions with irrelevant podSecurityContext' do
results= {
command: ["/bin/sh", "-c", "chown -R 568:568 /data
chown -R 568:568 /config
"]
}
values = {
podSecurityContext: {
allowPrivilegeEscalation: false
},
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
it 'outputs fsgroup permissions for multiple volumes when set' do
results= {
command: ["/bin/sh", "-c", "chown -R 568:666 /data
chown -R 568:666 /config
"]
}
values = {
podSecurityContext: {
fsGroup: 666
},
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
it 'outputs runAsUser permissions for multiple volumes when set' do
results= {
command: ["/bin/sh", "-c", "chown -R 999:568 /data
chown -R 999:568 /config
"]
}
values = {
podSecurityContext: {
runAsUser: 999
},
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
it 'outputs fsGroup AND runAsUser permissions for multiple volumes when both are set' do
results= {
command: ["/bin/sh", "-c", "chown -R 999:666 /data
chown -R 999:666 /config
"]
}
values = {
podSecurityContext: {
fsGroup: 666,
runAsUser: 999
},
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
it 'outputs PUID AND PGID permissions for multiple volumes when both are set' do
results= {
command: ["/bin/sh", "-c", "chown -R 999:666 /data
chown -R 999:666 /config
"]
}
values = {
env: {
PGID: 666,
PUID: 999
},
hostPathMounts: [
{
name: "data",
enabled: true,
setPermissions: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
setPermissions: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
job = chart.resources(kind: "Job").first
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
assert_equal(results[:command], mainContainer["command"])
end
end
end
end

View File

@@ -0,0 +1,316 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'pod::replicas' do
it 'defaults to 1' do
deployment = chart.resources(kind: "Deployment").first
assert_equal(1, deployment["spec"]["replicas"])
end
it 'accepts integer as value' do
chart.value replicas: 3
deployment = chart.resources(kind: "Deployment").first
assert_equal(3, deployment["spec"]["replicas"])
end
end
describe 'pod::hostNetwork' do
it 'defaults to nil' do
deployment = chart.resources(kind: "Deployment").first
assert_nil(deployment["spec"]["template"]["spec"]["hostNetwork"])
end
it 'can be enabled' do
values = {
hostNetwork: true
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
assert_equal(true, deployment["spec"]["template"]["spec"]["hostNetwork"])
end
end
describe 'pod::dnsPolicy' do
it 'defaults to "ClusterFirst" without hostNetwork' do
deployment = chart.resources(kind: "Deployment").first
assert_equal("ClusterFirst", deployment["spec"]["template"]["spec"]["dnsPolicy"])
end
it 'defaults to "ClusterFirst" when hostNetwork: false' do
values = {
hostNetwork: false
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
assert_equal("ClusterFirst", deployment["spec"]["template"]["spec"]["dnsPolicy"])
end
it 'defaults to "ClusterFirstWithHostNet" when hostNetwork: true' do
values = {
hostNetwork: true
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
assert_equal("ClusterFirstWithHostNet", deployment["spec"]["template"]["spec"]["dnsPolicy"])
end
it 'accepts manual override' do
values = {
dnsPolicy: "None"
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
assert_equal("None", deployment["spec"]["template"]["spec"]["dnsPolicy"])
end
end
describe 'pod::additional containers' do
it 'accepts static additionalContainers' do
values = {
additionalContainers: [
{
name: "template-test"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
additionalContainer = containers.find{ |c| c["name"] == values[:additionalContainers][0][:name] }
refute_nil(additionalContainer)
end
it 'accepts "Dynamic/Tpl" additionalContainers' do
expectedContainerName = "common-test-container"
values = {
additionalContainers: [
{
name: "{{ .Release.Name }}-container",
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
additionalContainer = containers.find{ |c| c["name"] == expectedContainerName }
refute_nil(additionalContainer)
end
end
describe 'pod::persistence' do
it 'multiple volumes' do
values = {
persistence: {
cache: {
enabled: true,
emptyDir: {
enabled: true
}
},
config: {
enabled: true,
existingClaim: "configClaim",
emptyDir: {
enabled: false
}
},
data: {
enabled: true,
existingClaim: "dataClaim"
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "cache"}
refute_nil(volume)
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal('configClaim', volume["persistentVolumeClaim"]["claimName"])
volume = volumes.find{ |v| v["name"] == "data"}
refute_nil(volume)
assert_equal('dataClaim', volume["persistentVolumeClaim"]["claimName"])
end
it 'default nameSuffix' do
values = {
persistence: {
config: {
enabled: true,
emptyDir: {
enabled: false
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal('common-test-config', volume["persistentVolumeClaim"]["claimName"])
end
it 'custom nameSuffix' do
values = {
persistence: {
config: {
enabled: true,
nameSuffix: "test",
emptyDir: {
enabled: false
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal('common-test-test', volume["persistentVolumeClaim"]["claimName"])
end
it 'no nameSuffix' do
values = {
persistence: {
config: {
enabled: true,
nameSuffix: "-",
emptyDir: {
enabled: false
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal('common-test', volume["persistentVolumeClaim"]["claimName"])
end
end
describe 'pod::persistence::emptyDir' do
it 'can be configured' do
values = {
persistence: {
config: {
enabled: true,
emptyDir: {
enabled: true
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal(Hash.new, volume["emptyDir"])
end
it 'medium can be configured' do
values = {
persistence: {
config: {
enabled: true,
emptyDir: {
enabled: true,
medium: "memory"
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal("memory", volume["emptyDir"]["medium"])
end
it 'sizeLimit can be configured' do
values = {
persistence: {
config: {
enabled: true,
emptyDir: {
enabled: true,
medium: "memory",
sizeLimit: "1Gi"
}
}
}
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "config"}
refute_nil(volume)
assert_equal("1Gi", volume["emptyDir"]["sizeLimit"])
end
end
describe 'pod::hostPathMounts' do
it 'multiple volumes' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
mountPath: "/data",
hostPath: "/tmp1"
},
{
name: "config",
enabled: true,
mountPath: "/config",
hostPath: "/tmp2"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
refute_nil(volume)
assert_equal('/tmp1', volume["hostPath"]["path"])
volume = volumes.find{ |v| v["name"] == "hostpathmounts-config"}
refute_nil(volume)
assert_equal('/tmp2', volume["hostPath"]["path"])
end
it 'emptyDir can be enabled' do
values = {
hostPathMounts: [
{
name: "data",
enabled: true,
emptyDir: true,
mountPath: "/data"
}
]
}
chart.value values
deployment = chart.resources(kind: "Deployment").first
volumes = deployment["spec"]["template"]["spec"]["volumes"]
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
refute_nil(volume)
assert_equal(Hash.new, volume["emptyDir"])
end
end
end
end

View File

@@ -0,0 +1,313 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'configmap::portal-defaults' do
it 'no configmap exists by default' do
configmap = chart.resources(kind: "ConfigMap").first
assert_nil(configmap)
end
it 'creates configmap whe enabled' do
values = {
portal: {
enabled: true
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
refute_nil(configmap)
end
it 'is named "portal"' do
values = {
portal: {
enabled: true
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("portal", configmap["metadata"]["name"])
end
it 'uses "$node_ip" by default' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("$node_ip", configmap["data"]["host"])
end
it 'uses port "443" by default' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("443", configmap["data"]["port"])
end
it 'uses protocol "https" by default' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("https", configmap["data"]["protocol"])
end
it 'uses path "/" by default' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("/", configmap["data"]["path"])
end
end
describe 'configmap::portal-overrides' do
it 'ingressPort can be overridden' do
values = {
portal: {
enabled: true,
ingressPort: "666"
},
ingress: {
main: {
enabled: true
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal(values[:portal][:ingressPort], configmap["data"]["port"])
end
it 'nodePort Host can be overridden' do
values = {
portal: {
enabled: true,
host: "test.host"
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal(values[:portal][:host], configmap["data"]["host"])
end
it 'path can be overridden' do
values = {
portal: {
enabled: true,
path: "/path"
},
ingress: {
main: {
enabled: false
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal(values[:portal][:path], configmap["data"]["path"])
end
end
describe 'configmap::portal-nodePort' do
it 'nodePort host defaults to "$node_ip"' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
},
services: {
main: {
type: "NodePort",
port: {
nodePort: 666
}
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("$node_ip", configmap["data"]["host"])
end
it 'nodePort port defaults to the nodePort' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
},
services: {
main: {
type: "NodePort",
port: {
nodePort: 666
}
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("666", configmap["data"]["port"])
end
it 'uses nodeport port protocol as protocol (HTTPS)' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
},
services: {
main: {
type: "NodePort",
port: {
nodePort: 666,
protocol: "HTTPS"
}
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal(values[:services][:main][:port][:protocol], configmap["data"]["protocol"])
end
it 'uses nodeport port protocol as protocol (HTTP)' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: false
}
},
services: {
main: {
type: "NodePort",
port: {
nodePort: 666,
protocol: "HTTP"
}
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal(values[:services][:main][:port][:protocol], configmap["data"]["protocol"])
end
end
describe 'configmap::portal-Ingress' do
it 'uses ingress host' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: true,
hosts: [
{
host: "test.domain",
paths:
[
{
path: "/test"
}
]
}
]
}
}
}
chart.value values
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("test.domain", configmap["data"]["host"])
end
it 'uses ingress path' do
values = {
portal: {
enabled: true
},
ingress: {
main: {
enabled: true,
hosts: [
{
host: "test.domain",
paths:
[
{
path: "/test"
}
]
}
]
}
}
}
chart.value values
configmap = chart.resources(kind: "ConfigMap").first
assert_equal("/test", configmap["data"]["path"])
end
end
end
end

View File

@@ -0,0 +1,110 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'pvc' do
it 'nameSuffix defaults to persistence key' do
values = {
persistence: {
config: {
enabled: true
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
refute_nil(pvc)
end
it 'nameSuffix can be overridden' do
values = {
persistence: {
config: {
enabled: true,
nameSuffix: 'customSuffix'
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-customSuffix" }
refute_nil(pvc)
end
it 'name can be overridden by nameOverride' do
values = {
persistence: {
config: {
enabled: true,
nameOverride: 'customname'
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "customname" }
refute_nil(pvc)
end
it 'nameSuffix can be skipped' do
values = {
persistence: {
config: {
enabled: true,
nameSuffix: '-'
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(pvc)
end
it 'storageClass can be set' do
values = {
persistence: {
config: {
enabled: true,
storageClass: "test"
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
refute_nil(pvc)
assert_equal('test', pvc["spec"]["storageClassName"])
end
it 'can generate TrueNAS SCALE zfs storageClass' do
values = {
persistence: {
config: {
enabled: true,
storageClass: "SCALE-ZFS"
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
refute_nil(pvc)
assert_equal('ix-storage-class-common-test', pvc["spec"]["storageClassName"])
end
it 'storageClass can be set to an empty value' do
values = {
persistence: {
config: {
enabled: true,
storageClass: "-"
}
}
}
chart.value values
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
refute_nil(pvc)
assert_equal('', pvc["spec"]["storageClassName"])
end
end
end
end

View File

@@ -0,0 +1,223 @@
# frozen_string_literal: true
require_relative '../../test_helper'
class Test < ChartTest
@@chart = Chart.new('charts/library/common-test')
describe @@chart.name do
describe 'service::ports settings' do
default_name = 'main'
default_port = 8080
it 'defaults to name "servicename" on port 8080' do
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal(default_port, service["spec"]["ports"].first["port"])
assert_equal(default_name, service["spec"]["ports"].first["targetPort"])
assert_equal(default_name, service["spec"]["ports"].first["name"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(default_port, mainContainer["ports"].first["containerPort"])
assert_equal(default_name, mainContainer["ports"].first["name"])
end
it 'port name can be overridden' do
values = {
services: {
main: {
port: {
name: "server",
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal(default_port, service["spec"]["ports"].first["port"])
assert_equal(values[:services][:main][:port][:name], service["spec"]["ports"].first["targetPort"])
assert_equal(values[:services][:main][:port][:name], service["spec"]["ports"].first["name"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(default_port, mainContainer["ports"].first["containerPort"])
assert_equal(values[:services][:main][:port][:name], mainContainer["ports"].first["name"])
end
it 'targetPort can be overridden' do
values = {
services: {
main: {
port: {
targetPort: 80,
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal(default_port, service["spec"]["ports"].first["port"])
assert_equal(values[:services][:main][:port][:targetPort], service["spec"]["ports"].first["targetPort"])
assert_equal(default_name, service["spec"]["ports"].first["name"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal(values[:services][:main][:port][:targetPort], mainContainer["ports"].first["containerPort"])
assert_equal(default_name, mainContainer["ports"].first["name"])
end
it 'targetPort cannot be a named port' do
values = {
services: {
main: {
port: {
targetPort: "test",
},
},
},
}
chart.value values
exception = assert_raises HelmCompileError do
chart.execute_helm_template!
end
assert_match("Our charts do not support named ports for targetPort. (port name #{default_name}, targetPort #{values[:services][:main][:port][:targetPort]})", exception.message)
end
it 'protocol defaults to TCP' do
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal("TCP", mainContainer["ports"].first["protocol"])
end
it 'protocol is TCP when set to TCP explicitly' do
values = {
services: {
main: {
port: {
protocol: "TCP",
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal("TCP", mainContainer["ports"].first["protocol"])
end
it 'protocol is TCP when set to HTTP explicitly' do
values = {
services: {
main: {
port: {
protocol: "HTTP",
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal("TCP", mainContainer["ports"].first["protocol"])
end
it 'protocol is TCP when set to HTTPS explicitly' do
values = {
services: {
main: {
port: {
protocol: "HTTPS",
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal("TCP", mainContainer["ports"].first["protocol"])
end
it 'protocol is UDP when set to UDP explicitly' do
values = {
services: {
main: {
port: {
protocol: "UDP",
},
},
},
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("UDP", service["spec"]["ports"].first["protocol"])
deployment = chart.resources(kind: "Deployment").first
containers = deployment["spec"]["template"]["spec"]["containers"]
mainContainer = containers.find{ |c| c["name"] == "common-test" }
assert_equal("UDP", mainContainer["ports"].first["protocol"])
end
it 'No annotations get set by default' do
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_nil(service["metadata"]["annotations"])
end
it 'TCP port protocol does not set annotations' do
values = {
services: {
main: {
port: {
protocol: 'TCP'
}
}
}
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_nil(service["metadata"]["annotations"])
end
it 'HTTPS port protocol sets traefik HTTPS annotation' do
values = {
services: {
main: {
port: {
protocol: 'HTTPS'
}
}
}
}
chart.value values
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
refute_nil(service)
assert_equal("https", service["metadata"]["annotations"]["traefik.ingress.kubernetes.io/service.serversscheme"])
end
end
end
end

View File

@@ -4,7 +4,6 @@ require 'json'
require 'yaml'
require 'open3'
require 'jq/extend'
require 'minitest-implicit-subject'
require "minitest/reporters"
require 'minitest/autorun'
@@ -105,10 +104,6 @@ class ChartTest < ExtendedMinitest
def resource(name)
chart.resources(kind: name).first
end
def jq(matcher, object)
value(object.jq(matcher)[0])
end
end
class Minitest::Result
@@ -117,3 +112,35 @@ class Minitest::Result
test_name.to_s.gsub /\Atest_\d{4,}_/, ""
end
end
class ::Hash
def deep_merge_override(second)
merger = proc do |key, original, override|
if original.instance_of?(Hash) && override.instance_of?(Hash)
original.merge(override, &merger)
else
if original.instance_of?(Array) && override.instance_of?(Array)
# if the lengths are different, prefer the override
if original.length != override.length
override
else
# if the first element in the override's Array is a Hash, then we assume they all are
if override[0].instance_of?(Hash)
original.map.with_index do |v, i|
# deep merge everything between the two arrays
original[i].merge(override[i], &merger)
end
else
# if we don't have a Hash in the override,
# override the whole array with our new one
override
end
end
else
override
end
end
end
self.merge(second.to_h, &merger)
end
end