diff --git a/charts/library/common-test/Chart.yaml b/charts/library/common-test/Chart.yaml index 12d5c9164da..030e37c68aa 100644 --- a/charts/library/common-test/Chart.yaml +++ b/charts/library/common-test/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 kubeVersion: ">=1.16.0-0" name: common-test -version: 3.0.3 +version: 3.0.4 # upstream_version: appVersion: none description: Helper chart to test different use cases of the common library diff --git a/charts/library/common-test/crds/ingressroute.yaml b/charts/library/common-test/crds/ingressroute.yaml deleted file mode 100644 index 9422be3c878..00000000000 --- a/charts/library/common-test/crds/ingressroute.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressroutes.traefik.containo.us -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRoute - plural: ingressroutes - singular: ingressroute - scope: Namespaced diff --git a/charts/library/common-test/crds/ingressroutetcp.yaml b/charts/library/common-test/crds/ingressroutetcp.yaml deleted file mode 100644 index b50eb9dcc46..00000000000 --- a/charts/library/common-test/crds/ingressroutetcp.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressroutetcps.traefik.containo.us -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRouteTCP - plural: ingressroutetcps - singular: ingressroutetcp - scope: Namespaced diff --git a/charts/library/common-test/crds/ingressrouteudp.yaml b/charts/library/common-test/crds/ingressrouteudp.yaml deleted file mode 100644 index d7c2624b576..00000000000 --- a/charts/library/common-test/crds/ingressrouteudp.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: ingressrouteudps.traefik.containo.us - -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: IngressRouteUDP - plural: ingressrouteudps - singular: ingressrouteudp - scope: Namespaced diff --git a/charts/library/common-test/crds/middlewares.yaml b/charts/library/common-test/crds/middlewares.yaml deleted file mode 100644 index 513b36f5d8a..00000000000 --- a/charts/library/common-test/crds/middlewares.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: middlewares.traefik.containo.us -spec: - group: traefik.containo.us - version: v1alpha1 - names: - kind: Middleware - plural: middlewares - singular: middleware - scope: Namespaced diff --git a/charts/library/common/Chart.yaml b/charts/library/common/Chart.yaml index 353a3468721..01bc4a974d7 100644 --- a/charts/library/common/Chart.yaml +++ b/charts/library/common/Chart.yaml @@ -18,4 +18,4 @@ maintainers: name: common sources: type: library -version: 5.1.3 +version: 6.0.0 diff --git a/charts/library/common/templates/_daemonset.tpl b/charts/library/common/templates/_daemonset.tpl index 239d9c1742d..05c292147b7 100644 --- a/charts/library/common/templates/_daemonset.tpl +++ b/charts/library/common/templates/_daemonset.tpl @@ -32,6 +32,9 @@ spec: {{- end }} labels: {{- include "common.labels.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: {{- include "common.controller.pod" . | nindent 6 }} {{- end }} diff --git a/charts/library/common/templates/_deployment.tpl b/charts/library/common/templates/_deployment.tpl index 9b0cb4158ca..eb905d3b0ca 100644 --- a/charts/library/common/templates/_deployment.tpl +++ b/charts/library/common/templates/_deployment.tpl @@ -50,6 +50,9 @@ spec: {{- end }} labels: {{- include "common.labels.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: {{- include "common.controller.pod" . | nindent 6 }} {{- end }} diff --git a/charts/library/common/templates/_pvc.tpl b/charts/library/common/templates/_pvc.tpl index e6322e4a8ce..e5276dd0a69 100644 --- a/charts/library/common/templates/_pvc.tpl +++ b/charts/library/common/templates/_pvc.tpl @@ -1,36 +1,21 @@ {{/* -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. -*/}} - -{{/* -Renders the PersistentVolumeClaim objects required by the chart by returning a concatinated list -of all the entries of the persistence key. +Renders the Persistent Volume Claim objects required by the chart. */}} {{- define "common.pvc" -}} + {{- $perDict := dict }} + {{- range $index, $item := .Values.persistenceList -}} + {{- $name := ( printf "list-%s" ( $index | toString ) ) }} + {{- if $item.name }} + {{- $name = $item.name }} + {{- end }} + {{- $_ := set $perDict $name $item }} + {{- end }} + {{- $per := merge .Values.persistence $perDict }} + {{- $_ := set .Values "persistence" (deepCopy $per) -}} + {{- /* Generate pvc as required */ -}} {{- range $index, $PVC := .Values.persistence }} - {{- $emptyDir := false -}} - {{- if $PVC.emptyDir -}} - {{- if $PVC.emptyDir.enabled -}} - {{- $emptyDir = true -}} - {{- end -}} - {{- end -}} - - {{- if and $PVC.enabled (not (or $emptyDir $PVC.existingClaim)) -}} + {{- if and $PVC.enabled (eq (default "pvc" $PVC.type) "pvc") (not $PVC.existingClaim) -}} {{- $persistenceValues := $PVC -}} {{- if not $persistenceValues.nameOverride -}} {{- $_ := set $persistenceValues "nameOverride" $index -}} diff --git a/charts/library/common/templates/_statefulset.tpl b/charts/library/common/templates/_statefulset.tpl index 59f7551a61a..e99a7b05f2f 100644 --- a/charts/library/common/templates/_statefulset.tpl +++ b/charts/library/common/templates/_statefulset.tpl @@ -1,21 +1,3 @@ -{{/* -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. -*/}} - {{/* This template serves as the blueprint for the StatefulSet objects that are created within the common library. @@ -31,9 +13,8 @@ metadata: {{- with .Values.controller.labels }} {{- toYaml . | nindent 4 }} {{- end }} - annotations: - {{- include "common.annotations.workload" . | nindent 4 }} {{- with .Values.controller.annotations }} + annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: @@ -55,13 +36,15 @@ spec: serviceName: {{ include "common.names.fullname" . }} template: metadata: - annotations: - {{- include "common.annotations.workload.spec" . | nindent 8 }} {{- with .Values.podAnnotations }} + annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "common.labels.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} spec: {{- include "common.controller.pod" . | nindent 6 }} volumeClaimTemplates: diff --git a/charts/library/common/templates/classes/_mountPermissions.tpl b/charts/library/common/templates/classes/_mountPermissions.tpl index 0f5b708d02c..640fdfd2f7c 100644 --- a/charts/library/common/templates/classes/_mountPermissions.tpl +++ b/charts/library/common/templates/classes/_mountPermissions.tpl @@ -3,25 +3,24 @@ This template serves as the blueprint for the mountPermissions job that is run before chart installation. */}} {{- define "common.class.mountPermissions" -}} - {{- if .Values.hostPathMounts -}} + {{- if .Values.persistence -}} {{- $jobName := include "common.names.fullname" . -}} {{- $user := 568 -}} + {{- $group := 568 -}} {{- if .Values.env -}} - {{- $user = dig "PUID" $user .Values.env -}} + {{- $user = dig "PUID" $user .Values.env -}} + {{- $group = dig "PGID" $group .Values.env -}} {{- end -}} {{- $user = dig "runAsUser" $user .Values.podSecurityContext -}} - {{- $group := 568 -}} - {{- if and .Values.env -}} - {{- $group = dig "PGID" $group .Values.env -}} - {{- end -}} {{- $group = dig "fsGroup" $group .Values.podSecurityContext -}} {{- $hostPathMounts := dict -}} - {{- range $name, $mount := .Values.hostPathMounts -}} + {{- range $name, $mount := .Values.persistence -}} {{- if and $mount.enabled $mount.setPermissions -}} {{- $name = default ( $name| toString ) $mount.name -}} {{- $_ := set $hostPathMounts $name $mount -}} {{- end -}} {{- end }} + {{- if $hostPathMounts -}} --- apiVersion: batch/v1 kind: Job @@ -83,6 +82,6 @@ spec: path: {{ required "hostPath not set" $hpm.hostPath }} {{ end }} {{- end }} - + {{- end -}} {{- end -}} {{- end -}} diff --git a/charts/library/common/templates/classes/_pvc.tpl b/charts/library/common/templates/classes/_pvc.tpl index b2e4064aac5..8f05af338ca 100644 --- a/charts/library/common/templates/classes/_pvc.tpl +++ b/charts/library/common/templates/classes/_pvc.tpl @@ -1,21 +1,3 @@ -{{/* -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. -*/}} - {{/* This template serves as a blueprint for all PersistentVolumeClaim objects that are created within the common library. @@ -58,4 +40,7 @@ spec: {{- if $values.storageClass }} 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 }} + {{- if $values.volumeName }} + volumeName: {{ $values.volumeName | quote }} + {{- end }} {{- end -}} diff --git a/charts/library/common/templates/classes/_service.tpl b/charts/library/common/templates/classes/_service.tpl index 09e49a43fb4..4874110410d 100644 --- a/charts/library/common/templates/classes/_service.tpl +++ b/charts/library/common/templates/classes/_service.tpl @@ -1,21 +1,3 @@ -{{/* -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. -*/}} - {{/* This template serves as a blueprint for all Service objects that are created within the common library. diff --git a/charts/library/common/templates/classes/_service_ports.tpl b/charts/library/common/templates/classes/_service_ports.tpl index 3eaaa9e1bc4..4e287de52e2 100644 --- a/charts/library/common/templates/classes/_service_ports.tpl +++ b/charts/library/common/templates/classes/_service_ports.tpl @@ -1,21 +1,3 @@ -{{/* -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. -*/}} - {{/* Return the name of the primary port for a given Service object. */}} diff --git a/charts/library/common/templates/lib/chart/_names.tpl b/charts/library/common/templates/lib/chart/_names.tpl index d0587cddf24..a32d572ffe7 100644 --- a/charts/library/common/templates/lib/chart/_names.tpl +++ b/charts/library/common/templates/lib/chart/_names.tpl @@ -1,24 +1,10 @@ -{{/* -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. -*/}} - {{/* Expand the name of the chart */}} {{- define "common.names.name" -}} - {{- default .Chart.Name (default .Values.nameOverride .Values.global.nameOverride) | trunc 63 | trimSuffix "-" -}} + {{- $globalNameOverride := "" -}} + {{- if hasKey .Values "global" -}} + {{- $globalNameOverride = (default $globalNameOverride .Values.global.nameOverride) -}} + {{- end -}} + {{- default .Chart.Name (default .Values.nameOverride $globalNameOverride) | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* @@ -28,13 +14,17 @@ If release name contains chart name it will be used as a full name. */}} {{- define "common.names.fullname" -}} {{- $name := include "common.names.name" . -}} - {{- if or .Values.fullnameOverride .Values.global.fullnameOverride -}} - {{- $name = default .Values.fullnameOverride .Values.global.fullnameOverride -}} + {{- $globalFullNameOverride := "" -}} + {{- if hasKey .Values "global" -}} + {{- $globalFullNameOverride = (default $globalFullNameOverride .Values.global.fullnameOverride) -}} + {{- end -}} + {{- if or .Values.fullnameOverride $globalFullNameOverride -}} + {{- $name = default .Values.fullnameOverride $globalFullNameOverride -}} {{- else -}} {{- if contains $name .Release.Name -}} - {{- $name := .Release.Name -}} + {{- $name = .Release.Name -}} {{- else -}} - {{- $name := printf "%s-%s" .Release.Name $name -}} + {{- $name = printf "%s-%s" .Release.Name $name -}} {{- end -}} {{- end -}} {{- trunc 63 $name | trimSuffix "-" -}} diff --git a/charts/library/common/templates/lib/controller/_probes.tpl b/charts/library/common/templates/lib/controller/_probes.tpl index f8eaa26cb80..2f6ecfe9485 100644 --- a/charts/library/common/templates/lib/controller/_probes.tpl +++ b/charts/library/common/templates/lib/controller/_probes.tpl @@ -1,22 +1,3 @@ -{{/* -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. -*/}} - - {{/* Probes selection logic. */}} diff --git a/charts/library/common/templates/lib/controller/_volumeMounts.tpl b/charts/library/common/templates/lib/controller/_volumeMounts.tpl index f0badf21818..5a6ad4c72a6 100644 --- a/charts/library/common/templates/lib/controller/_volumeMounts.tpl +++ b/charts/library/common/templates/lib/controller/_volumeMounts.tpl @@ -1,34 +1,25 @@ {{/* Volumes included by the controller */}} {{- define "common.controller.volumeMounts" -}} - {{- range $index, $PVC := .Values.persistence }} - {{- if $PVC.enabled }} -- mountPath: {{ $PVC.mountPath | default (printf "/%v" $index) }} + {{- range $index, $item := .Values.persistence }} + {{- $mountPath := (printf "/%v" $index) -}} + {{- if eq "hostPath" (default "pvc" $item.type) -}} + {{- $mountPath = $item.hostPath -}} + {{- end -}} + {{- with $item.mountPath -}} + {{- $mountPath = . -}} + {{- end }} + {{- if and $item.enabled (ne $mountPath "-") }} +- mountPath: {{ $mountPath }} name: {{ $index }} - {{- if $PVC.subPath }} - subPath: {{ $PVC.subPath }} + {{- with $item.subPath }} + subPath: {{ . }} + {{- end }} + {{- with $item.readOnly }} + readOnly: {{ . }} {{- end }} {{- 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 }} - {{ $name = $dmm.name }} -{{ end }} -- name: devicemount-{{ $name }} - mountPath: {{ $dmm.devicePath }} - {{ if $dmm.subPath }} - subPath: {{ $dmm.subPath }} - {{ end }} -{{- end -}} -{{ end }} - {{- if .Values.additionalVolumeMounts }} - {{- toYaml .Values.additionalVolumeMounts | nindent 0 }} - {{- end }} - {{- if eq .Values.controller.type "statefulset" }} {{- range $index, $vct := .Values.volumeClaimTemplates }} - mountPath: {{ $vct.mountPath }} @@ -39,18 +30,4 @@ Creates mountpoints to mount devices directly to the same path inside the contai {{- end }} {{- end }} - {{/* Creates mountpoints to mount hostPaths directly to the container */}} - {{- range $name, $hpm := .Values.hostPathMounts }} - {{- if $hpm.enabled }} - {{- $name = default $name $hpm.name }} -- name: hostpathmounts-{{ $name }} - mountPath: {{ $hpm.mountPath }} - {{- if $hpm.subPath }} - subPath: {{ $hpm.subPath }} - {{- end }} - {{- if $hpm.readOnly }} - readOnly: {{ $hpm.readOnly }} - {{- end }} - {{- end }} - {{ end }} {{- end -}} diff --git a/charts/library/common/templates/lib/controller/_volumes.tpl b/charts/library/common/templates/lib/controller/_volumes.tpl index c85a685f5e9..e2aa485d185 100644 --- a/charts/library/common/templates/lib/controller/_volumes.tpl +++ b/charts/library/common/templates/lib/controller/_volumes.tpl @@ -5,98 +5,43 @@ Volumes included by the controller. {{- range $index, $persistence := .Values.persistence }} {{- if $persistence.enabled }} - name: {{ $index }} -{{- if $persistence.existingClaim }} -{{- /* Always prefer an existingClaim if that is set */}} - persistentVolumeClaim: - claimName: {{ $persistence.existingClaim }} -{{- else -}} - {{- /* 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: "{{ . }}" + {{- if eq (default "pvc" $persistence.type) "pvc" }} + {{- $pvcName := (include "common.names.fullname" $) -}} + {{- if $persistence.existingClaim }} + {{- /* Always prefer an existingClaim if that is set */}} + {{- $pvcName = $persistence.existingClaim -}} + {{- else -}} + {{- /* Otherwise refer to the PVC name */}} + {{- if $persistence.nameOverride -}} + {{- if not (eq $persistence.nameOverride "-") -}} + {{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $persistence.nameOverride) -}} + {{- end -}} + {{- else -}} + {{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $index) -}} + {{- end -}} {{- end }} - {{- with $persistence.emptyDir.sizeLimit }} - sizeLimit: "{{ . }}" - {{- end }} - {{- else }} - emptyDir: {} - {{- end }} - {{- else -}} - {{- /* Otherwise refer to the PVC name */}} - {{- $pvcName := (include "common.names.fullname" $) -}} - {{- if $persistence.nameOverride -}} - {{- if not (eq $persistence.nameOverride "-") -}} - {{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $persistence.nameOverride) -}} - {{- 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 }} -{{ if $dm.name }} -{{ $name = $dm.name }} -{{ end }} -- name: devicemount-{{ $name }} - {{ if $dm.emptyDir }} - emptyDir: {} - {{- else -}} - hostPath: - path: {{ required "hostPath not set" $dm.devicePath }} - {{ end }} -{{ end }} -{{- end -}} - -{{/* -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: hostpathmounts-{{ $name }} - {{- /* Always prefer an emptyDir next if that is set */}} - {{- $emptyDir := false -}} - {{- if $hpm.emptyDir -}} - {{- if $hpm.emptyDir.enabled -}} - {{- $emptyDir = true -}} + {{- else if eq $persistence.type "emptyDir" }} + {{- $emptyDir := dict -}} + {{- with $persistence.medium -}} + {{- $_ := set $emptyDir "medium" . -}} {{- end -}} - {{- end -}} - {{- if $emptyDir }} - {{- if or $hpm.emptyDir.medium $hpm.emptyDir.sizeLimit }} - emptyDir: - {{- with $hpm.emptyDir.medium }} - medium: "{{ . }}" + {{- with $persistence.sizeLimit -}} + {{- $_ := set $emptyDir "sizeLimit" . -}} {{- end }} - {{- with $hpm.emptyDir.sizeLimit }} - sizeLimit: "{{ . }}" - {{- end }} - {{- else }} - emptyDir: {} - {{- end }} - {{- else }} + emptyDir: {{- $emptyDir | toYaml | nindent 4 }} + {{- else if eq $persistence.type "hostPath" }} hostPath: - path: {{ required "hostPath not set" $hpm.hostPath }} - {{ end }} -{{ end }} -{{- end -}} - -{{- end -}} + path: {{ required "hostPath not set" $persistence.hostPath }} + {{- with $persistence.hostPathType }} + type: {{ . }} + {{- end }} + {{- else if eq $persistence.type "custom" }} + {{- toYaml $persistence.volumeSpec | nindent 2 }} + {{- else }} + {{- fail (printf "Not a valid persistence.type (%s)" .Values.persistence.type) }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/library/common/tests/container_test.go b/charts/library/common/tests/container_test.go index 39716967ff2..89a7a7a785f 100644 --- a/charts/library/common/tests/container_test.go +++ b/charts/library/common/tests/container_test.go @@ -1,247 +1,243 @@ package common import ( - "testing" - - "github.com/stretchr/testify/suite" + "testing" "github.com/truecharts/apps/tests/helmunit" + "github.com/stretchr/testify/suite" ) type ContainerTestSuite struct { - suite.Suite - Chart helmunit.HelmChart + suite.Suite + Chart helmunit.HelmChart } func (suite *ContainerTestSuite) SetupSuite() { suite.Chart = helmunit.New("common-test", "../../common-test") - suite.Chart.UpdateDependencies() + suite.Chart.UpdateDependencies() } // We need this function to kick off the test suite, otherwise // "go test" won't know about our tests func TestContainer(t *testing.T) { - suite.Run(t, new(ContainerTestSuite)) + suite.Run(t, new(ContainerTestSuite)) } func (suite *ContainerTestSuite) TestCommand() { - tests := map[string]struct { - values []string - expectedCommand []string - }{ - "Default": {values: nil, expectedCommand: nil}, - "SingleString": {values: []string{"command=/bin/sh"}, expectedCommand: []string{"/bin/sh"}}, - "StringList": {values: []string{"command={/bin/sh,-c}"}, expectedCommand: []string{"/bin/sh", "-c"}}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, tc.values, nil) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values []string + expectedCommand []string + }{ + "Default": {values: nil, expectedCommand: nil}, + "SingleString": {values: []string{"command=/bin/sh"}, expectedCommand: []string{"/bin/sh"}}, + "StringList": {values: []string{"command={/bin/sh,-c}"}, expectedCommand: []string{"/bin/sh", "-c"}}, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, tc.values, nil) + if err != nil { + suite.FailNow(err.Error()) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerCommand := containers[0].Path("command") + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerCommand := containers[0].Path("command") - if tc.expectedCommand == nil { - suite.Assertions.Empty(containerCommand) - } else { - var actualDataList []string - actualData, _ := containerCommand.Children() - for _, key := range actualData { - actualDataList = append(actualDataList, key.Data().(string)) - } - suite.Assertions.EqualValues(tc.expectedCommand, actualDataList) - } - }) - } + if tc.expectedCommand == nil { + suite.Assertions.Empty(containerCommand) + } else { + var actualDataList []string + actualData, _ := containerCommand.Children() + for _, key := range actualData { + actualDataList = append(actualDataList, key.Data().(string)) + } + suite.Assertions.EqualValues(tc.expectedCommand, actualDataList) + } + }) + } } func (suite *ContainerTestSuite) TestArgs() { - tests := map[string]struct { - values []string - expectedArgs []string - }{ - "Default": {values: nil, expectedArgs: nil}, - "SingleString": {values: []string{"args=sleep infinity"}, expectedArgs: []string{"sleep infinity"}}, - "StringList": {values: []string{"args={sleep,infinity}"}, expectedArgs: []string{"sleep", "infinity"}}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, tc.values, nil) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values []string + expectedArgs []string + }{ + "Default": {values: nil, expectedArgs: nil}, + "SingleString": {values: []string{"args=sleep infinity"}, expectedArgs: []string{"sleep infinity"}}, + "StringList": {values: []string{"args={sleep,infinity}"}, expectedArgs: []string{"sleep", "infinity"}}, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, tc.values, nil) + if err != nil { + suite.FailNow(err.Error()) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerArgs := containers[0].Path("args") + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerArgs := containers[0].Path("args") - if tc.expectedArgs == nil { - suite.Assertions.Empty(containerArgs) - } else { - var actualDataList []string - actualData, _ := containerArgs.Children() - for _, key := range actualData { - actualDataList = append(actualDataList, key.Data().(string)) - } - suite.Assertions.EqualValues(tc.expectedArgs, actualDataList) - } - }) - } + if tc.expectedArgs == nil { + suite.Assertions.Empty(containerArgs) + } else { + var actualDataList []string + actualData, _ := containerArgs.Children() + for _, key := range actualData { + actualDataList = append(actualDataList, key.Data().(string)) + } + suite.Assertions.EqualValues(tc.expectedArgs, actualDataList) + } + }) + } } func (suite *ContainerTestSuite) TestEnv() { - tests := map[string]struct { - values []string - expectedEnv map[string]string - }{ - "Default": {values: nil, expectedEnv: nil}, - "KeyValueString": {values: []string{"env.string=value_of_env"}, expectedEnv: map[string]string{"string": "value_of_env"}}, - "KeyValueFloat": {values: []string{"env.float=4.2"}, expectedEnv: map[string]string{"float": "4.2"}}, - "KeyValueBool": {values: []string{"env.bool=false"}, expectedEnv: map[string]string{"bool": "false"}}, - "KeyValueInt": {values: []string{"env.int=42"}, expectedEnv: map[string]string{"int": "42"}}, - "List": {values: []string{"env[0].name=STATIC_ENV_FROM_LIST", "env[0].value=STATIC_ENV_VALUE_FROM_LIST"}, expectedEnv: map[string]string{"STATIC_ENV_FROM_LIST": "STATIC_ENV_VALUE_FROM_LIST"}}, - "ValueFrom": {values: []string{"env[0].name=STATIC_ENV_FROM_LIST", "env[0].valueFrom.fieldRef.fieldPath=spec.nodeName"}, expectedEnv: map[string]string{"STATIC_ENV_FROM_LIST": "spec.nodeName"}}, - "KeyValue+ExplicitValueFrom": {values: []string{"env.STATIC_ENV=value_of_env", "env.STATIC_ENV_FROM.valueFrom.fieldRef.fieldPath=spec.nodeName"}, expectedEnv: map[string]string{"STATIC_ENV": "value_of_env", "STATIC_ENV_FROM": "spec.nodeName"}}, - "ImplicitValueFrom": {values: []string{"env.NODE_NAME.fieldRef.fieldPath=spec.nodeName"}, expectedEnv: map[string]string{"NODE_NAME": "spec.nodeName"}}, - "Templated": {values: []string{`env.DYN_ENV=\{\{ .Release.Name \}\}-admin`}, expectedEnv: map[string]string{"DYN_ENV": "common-test-admin"}}, - "Mixed": { - values: []string{ - `env.DYN_ENV=\{\{ .Release.Name \}\}-admin`, - "env.STATIC_ENV=value_of_env", - "env.STATIC_EXPLICIT_ENV_FROM.valueFrom.fieldRef.fieldPath=spec.nodeName", - "env.STATIC_IMPLICIT_ENV_FROM.fieldRef.fieldPath=spec.nodeName", - }, - expectedEnv: map[string]string{ - "DYN_ENV": "common-test-admin", - "STATIC_ENV": "value_of_env", - "STATIC_EXPLICIT_ENV_FROM": "spec.nodeName", - "STATIC_IMPLICIT_ENV_FROM": "spec.nodeName", - }, - }, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, tc.values, nil) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values []string + expectedEnv map[string]string + }{ + "Default": {values: nil, expectedEnv: nil}, + "KeyValueString": {values: []string{"env.string=value_of_env"}, expectedEnv: map[string]string{"string": "value_of_env"}}, + "KeyValueFloat": {values: []string{"env.float=4.2"}, expectedEnv: map[string]string{"float": "4.2"}}, + "KeyValueBool": {values: []string{"env.bool=false"}, expectedEnv: map[string]string{"bool": "false"}}, + "KeyValueInt": {values: []string{"env.int=42"}, expectedEnv: map[string]string{"int": "42"}}, + "KeyValue+ExplicitValueFrom": {values: []string{"env.STATIC_ENV=value_of_env", "env.STATIC_ENV_FROM.valueFrom.fieldRef.fieldPath=spec.nodeName"}, expectedEnv: map[string]string{"STATIC_ENV": "value_of_env", "STATIC_ENV_FROM": "spec.nodeName"}}, + "ImplicitValueFrom": {values: []string{"env.NODE_NAME.fieldRef.fieldPath=spec.nodeName"}, expectedEnv: map[string]string{"NODE_NAME": "spec.nodeName"}}, + "Templated": {values: []string{`env.DYN_ENV=\{\{ .Release.Name \}\}-admin`}, expectedEnv: map[string]string{"DYN_ENV": "common-test-admin"}}, + "Mixed": { + values: []string{ + `env.DYN_ENV=\{\{ .Release.Name \}\}-admin`, + "env.STATIC_ENV=value_of_env", + "env.STATIC_EXPLICIT_ENV_FROM.valueFrom.fieldRef.fieldPath=spec.nodeName", + "env.STATIC_IMPLICIT_ENV_FROM.fieldRef.fieldPath=spec.nodeName", + }, + expectedEnv: map[string]string{ + "DYN_ENV": "common-test-admin", + "STATIC_ENV": "value_of_env", + "STATIC_EXPLICIT_ENV_FROM": "spec.nodeName", + "STATIC_IMPLICIT_ENV_FROM": "spec.nodeName", + }, + }, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, tc.values, nil) + if err != nil { + suite.FailNow(err.Error()) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerEnv := containers[0].Path("env") + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerEnv := containers[0].Path("env") - if tc.expectedEnv == nil { - suite.Assertions.Empty(containerEnv) - } else { - actualDataMap := make(map[string]string) - actualData, _ := containerEnv.Children() - for _, value := range actualData { - envVar, _ := value.ChildrenMap() - envName := envVar["name"].Data().(string) - var envValue string - if _, ok := envVar["valueFrom"]; ok { - envValue = value.Path("valueFrom.fieldRef.fieldPath").Data().(string) - } else { - envValue = value.Path("value").Data().(string) - } - actualDataMap[envName] = envValue - } - suite.Assertions.EqualValues(tc.expectedEnv, actualDataMap) - } - }) - } + if tc.expectedEnv == nil { + suite.Assertions.Empty(containerEnv) + } else { + actualDataMap := make(map[string]string) + actualData, _ := containerEnv.Children() + for _, value := range actualData { + envVar, _ := value.ChildrenMap() + envName := envVar["name"].Data().(string) + var envValue string + if _, ok := envVar["valueFrom"]; ok { + envValue = value.Path("valueFrom.fieldRef.fieldPath").Data().(string) + } else { + envValue = value.Path("value").Data().(string) + } + actualDataMap[envName] = envValue + } + suite.Assertions.EqualValues(tc.expectedEnv, actualDataMap) + } + }) + } } func (suite *ContainerTestSuite) TestEnvFrom() { - tests := map[string]struct { - values []string - expectSecret bool - expectedSecretName string - }{ - "Default": {values: nil, expectSecret: false, expectedSecretName: ""}, - "FromSecret": {values: []string{"secret.STATIC_SECRET=value_of_secret"}, expectSecret: true, expectedSecretName: "common-test"}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, tc.values, nil) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values []string + expectSecret bool + expectedSecretName string + }{ + "Default": {values: nil, expectSecret: false, expectedSecretName: ""}, + "FromSecret": {values: []string{"secret.STATIC_SECRET=value_of_secret"}, expectSecret: true, expectedSecretName: "common-test"}, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, tc.values, nil) + if err != nil { + suite.FailNow(err.Error()) + } - secretManifest := suite.Chart.Manifests.Get("Secret", tc.expectedSecretName) - if tc.expectSecret { - suite.Assertions.NotEmpty(secretManifest) - } else { - suite.Assertions.Empty(secretManifest) - } + secretManifest := suite.Chart.Manifests.Get("Secret", tc.expectedSecretName) + if tc.expectSecret { + suite.Assertions.NotEmpty(secretManifest) + } else { + suite.Assertions.Empty(secretManifest) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerEnvFrom, _ := containers[0].Path("envFrom").Children() + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerEnvFrom, _ := containers[0].Path("envFrom").Children() - if !tc.expectSecret { - suite.Assertions.Empty(containerEnvFrom) - } else { - suite.Assertions.EqualValues(tc.expectedSecretName, containerEnvFrom[0].Path("secretRef.name").Data().(string)) - } - }) - } + if !tc.expectSecret { + suite.Assertions.Empty(containerEnvFrom) + } else { + suite.Assertions.EqualValues(tc.expectedSecretName, containerEnvFrom[0].Path("secretRef.name").Data().(string)) + } + }) + } } func (suite *ContainerTestSuite) TestPorts() { - tests := map[string]struct { - values []string - expectedPortName string - expectedPort int - expectedProtocol string - }{ - "Default": {values: nil, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, - "CustomName": {values: []string{"service.main.ports.main.enabled=false", "service.main.ports.server.enabled=true", "service.main.ports.server.port=8080"}, expectedPortName: "server", expectedPort: 8080, expectedProtocol: "TCP"}, - "ProtocolHTTP": {values: []string{"service.main.ports.main.protocol=HTTP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, - "ProtocolHTTPS": {values: []string{"service.main.ports.main.protocol=HTTP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, - "ProtocolUDP": {values: []string{"service.main.ports.main.protocol=UDP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "UDP"}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, tc.values, nil) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values []string + expectedPortName string + expectedPort int + expectedProtocol string + }{ + "Default": {values: nil, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, + "CustomName": {values: []string{"service.main.ports.main.enabled=false", "service.main.ports.server.enabled=true", "service.main.ports.server.port=8080"}, expectedPortName: "server", expectedPort: 8080, expectedProtocol: "TCP"}, + "ProtocolHTTP": {values: []string{"service.main.ports.main.protocol=HTTP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, + "ProtocolHTTPS": {values: []string{"service.main.ports.main.protocol=HTTP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "TCP"}, + "ProtocolUDP": {values: []string{"service.main.ports.main.protocol=UDP"}, expectedPortName: "main", expectedPort: 0, expectedProtocol: "UDP"}, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, tc.values, nil) + if err != nil { + suite.FailNow(err.Error()) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerPorts, _ := containers[0].Path("ports").Children() - suite.Assertions.NotEmpty(containerPorts[0]) - suite.Assertions.EqualValues(tc.expectedPortName, containerPorts[0].Path("name").Data()) - suite.Assertions.EqualValues(tc.expectedProtocol, containerPorts[0].Path("protocol").Data()) + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerPorts, _ := containers[0].Path("ports").Children() + suite.Assertions.NotEmpty(containerPorts[0]) + suite.Assertions.EqualValues(tc.expectedPortName, containerPorts[0].Path("name").Data()) + suite.Assertions.EqualValues(tc.expectedProtocol, containerPorts[0].Path("protocol").Data()) - if tc.expectedPort == 0 { - suite.Assertions.Empty(containerPorts[0].Path("containerPort").Data()) - } else { - suite.Assertions.EqualValues(tc.expectedPort, containerPorts[0].Path("containerPort").Data()) - } - }) - } + if tc.expectedPort == 0 { + suite.Assertions.Empty(containerPorts[0].Path("containerPort").Data()) + } else { + suite.Assertions.EqualValues(tc.expectedPort, containerPorts[0].Path("containerPort").Data()) + } + }) + } } func (suite *ContainerTestSuite) TestPersistenceVolumeMounts() { - values := ` + values := ` persistence: config: enabled: true cache: enabled: true - emptyDir: - enabled: true + type: emptyDir claimWithCustomMountPath: enabled: true mountPath: /custom @@ -251,102 +247,56 @@ func (suite *ContainerTestSuite) TestPersistenceVolumeMounts() { enabled: true existingClaim: myClaim subPath: "mySubPath" - ` - tests := map[string]struct { - values *string - volumeToTest string - expectedMountPath string - expectedSubPath string - }{ - "MountWithoutMountPath": {values: &values, volumeToTest: "config", expectedMountPath: "/config"}, - "EmptyDir": {values: &values, volumeToTest: "cache", expectedMountPath: "/cache"}, - "MountWithCustomMountPath": {values: &values, volumeToTest: "claimWithCustomMountPath", expectedMountPath: "/custom"}, - "MountWithSubPath": {values: &values, volumeToTest: "claimWithSubPath", expectedMountPath: "/claimWithSubPath", expectedSubPath: "mySubPath"}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, nil, tc.values) - if err != nil { - suite.FailNow(err.Error()) - } - - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerVolumeMounts, _ := containers[0].Path("volumeMounts").Children() - suite.Assertions.NotEmpty(containerVolumeMounts) - - for _, volumeMount := range containerVolumeMounts { - volumeMountName := volumeMount.Path("name").Data().(string) - if volumeMountName == tc.volumeToTest { - suite.Assertions.EqualValues(tc.expectedMountPath, volumeMount.Path("mountPath").Data()) - - if tc.expectedSubPath == "" { - suite.Assertions.Empty(volumeMount.Path("subPath").Data()) - } else { - suite.Assertions.EqualValues(tc.expectedSubPath, volumeMount.Path("subPath").Data()) - } - break - } - } - }) - } -} - -func (suite *ContainerTestSuite) TestPersistenceHostpathMounts() { - values := ` - hostPathMounts: - - name: data - enabled: true - mountPath: /data - hostPath: /tmp - - name: config - enabled: true - hostPath: /tmp - mountPath: /config - subPath: mySubPath - - name: cache - enabled: true - mountPath: /cache - emptyDir: + hostpath-data: enabled: true + type: hostPath + mountPath: /data + hostPath: /tmp + hostpath-dev: + enabled: true + type: hostPath + hostPath: /dev + subPath: mySubPath ` - tests := map[string]struct { - values *string - volumeToTest string - expectedMountPath string - expectedSubPath string - }{ - "EmptyDir": {values: &values, volumeToTest: "cache", expectedMountPath: "/cache"}, - "WithMountPath": {values: &values, volumeToTest: "hostpathmounts-data", expectedMountPath: "/data"}, - "WithSubPath": {values: &values, volumeToTest: "hostpathmounts-config", expectedMountPath: "/config", expectedSubPath: "mySubPath"}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, nil, tc.values) - if err != nil { - suite.FailNow(err.Error()) - } + tests := map[string]struct { + values *string + volumeToTest string + expectedMountPath string + expectedSubPath string + }{ + "MountWithoutMountPath": {values: &values, volumeToTest: "config", expectedMountPath: "/config"}, + "EmptyDir": {values: &values, volumeToTest: "cache", expectedMountPath: "/cache"}, + "MountWithCustomMountPath": {values: &values, volumeToTest: "claimWithCustomMountPath", expectedMountPath: "/custom"}, + "MountWithSubPath": {values: &values, volumeToTest: "claimWithSubPath", expectedMountPath: "/claimWithSubPath", expectedSubPath: "mySubPath"}, + "HostPathMount": {values: &values, volumeToTest: "hostpath-data", expectedMountPath: "/data"}, + "HostPathMountWithSubPath": {values: &values, volumeToTest: "hostpath-dev", expectedMountPath: "/dev", expectedSubPath: "mySubPath"}, + } + for name, tc := range tests { + suite.Suite.Run(name, func() { + err := suite.Chart.Render(nil, nil, tc.values) + if err != nil { + suite.FailNow(err.Error()) + } - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - suite.Assertions.NotEmpty(deploymentManifest) - containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() - containerVolumeMounts, _ := containers[0].Path("volumeMounts").Children() - suite.Assertions.NotEmpty(containerVolumeMounts) + deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") + suite.Assertions.NotEmpty(deploymentManifest) + containers, _ := deploymentManifest.Path("spec.template.spec.containers").Children() + containerVolumeMounts, _ := containers[0].Path("volumeMounts").Children() + suite.Assertions.NotEmpty(containerVolumeMounts) - for _, volumeMount := range containerVolumeMounts { - volumeMountName := volumeMount.Path("name").Data().(string) - if volumeMountName == tc.volumeToTest { - suite.Assertions.EqualValues(tc.expectedMountPath, volumeMount.Path("mountPath").Data()) + for _, volumeMount := range containerVolumeMounts { + volumeMountName := volumeMount.Path("name").Data().(string) + if volumeMountName == tc.volumeToTest { + suite.Assertions.EqualValues(tc.expectedMountPath, volumeMount.Path("mountPath").Data()) - if tc.expectedSubPath == "" { - suite.Assertions.Empty(volumeMount.Path("subPath").Data()) - } else { - suite.Assertions.EqualValues(tc.expectedSubPath, volumeMount.Path("subPath").Data()) - } - break - } - } - }) - } + if tc.expectedSubPath == "" { + suite.Assertions.Empty(volumeMount.Path("subPath").Data()) + } else { + suite.Assertions.EqualValues(tc.expectedSubPath, volumeMount.Path("subPath").Data()) + } + break + } + } + }) + } } diff --git a/charts/library/common/tests/permissions_job_test.go b/charts/library/common/tests/permissions_job_test.go index 3dc1b38e5bc..3783b8e7b46 100644 --- a/charts/library/common/tests/permissions_job_test.go +++ b/charts/library/common/tests/permissions_job_test.go @@ -34,10 +34,12 @@ func (suite *PermissionsJobTestSuite) TestPresence() { }, "WithHostPathMount": { values: []string{ - "hostPathMounts[0].name=data", - "hostPathMounts[0].enabled=true", - "hostPathMounts[0].mountPath=/data", - "hostPathMounts[0].hostPath=/tmp", + "persistenceList[0].name=data", + "persistenceList[0].type=hostPath", + "persistenceList[0].enabled=true", + "persistenceList[0].mountPath=/data", + "persistenceList[0].setPermissions=true", + "persistenceList[0].hostPath=/tmp", }, expectedJob: true, }, @@ -64,27 +66,20 @@ func (suite *PermissionsJobTestSuite) TestVolumesAndMounts() { values []string expectedVolumes []string }{ - "Default": { + "MultiplepersistenceList": { values: []string{ - "hostPathMounts[0].name=data", - "hostPathMounts[0].enabled=true", - "hostPathMounts[0].mountPath=/data", - "hostPathMounts[0].hostPath=/tmp", - }, - expectedVolumes: nil, - }, - "MultipleHostPathMounts": { - values: []string{ - "hostPathMounts[0].name=data", - "hostPathMounts[0].enabled=true", - "hostPathMounts[0].setPermissions=true", - "hostPathMounts[0].mountPath=/data", - "hostPathMounts[0].hostPath=/tmp", - "hostPathMounts[1].name=config", - "hostPathMounts[1].enabled=true", - "hostPathMounts[1].setPermissions=true", - "hostPathMounts[1].mountPath=/config", - "hostPathMounts[1].hostPath=/tmp", + "persistenceList[0].name=data", + "persistenceList[0].type=hostPath", + "persistenceList[0].enabled=true", + "persistenceList[0].setPermissions=true", + "persistenceList[0].mountPath=/data", + "persistenceList[0].hostPath=/tmp", + "persistenceList[1].name=config", + "persistenceList[1].type=hostPath", + "persistenceList[1].enabled=true", + "persistenceList[1].setPermissions=true", + "persistenceList[1].mountPath=/config", + "persistenceList[1].hostPath=/tmp", }, expectedVolumes: []string{"hostpathmounts-config", "hostpathmounts-data"}, }, @@ -124,16 +119,18 @@ func (suite *PermissionsJobTestSuite) TestVolumesAndMounts() { func (suite *PermissionsJobTestSuite) TestCommand() { baseValues := []string{ - "hostPathMounts[0].name=data", - "hostPathMounts[0].enabled=true", - "hostPathMounts[0].setPermissions=true", - "hostPathMounts[0].mountPath=/data", - "hostPathMounts[0].hostPath=/tmp", - "hostPathMounts[1].name=config", - "hostPathMounts[1].enabled=true", - "hostPathMounts[1].setPermissions=true", - "hostPathMounts[1].mountPath=/config", - "hostPathMounts[1].hostPath=/tmp", + "persistenceList[0].name=data", + "persistenceList[0].type=hostPath", + "persistenceList[0].enabled=true", + "persistenceList[0].setPermissions=true", + "persistenceList[0].mountPath=/data", + "persistenceList[0].hostPath=/tmp", + "persistenceList[1].name=config", + "persistenceList[1].type=hostPath", + "persistenceList[1].enabled=true", + "persistenceList[1].setPermissions=true", + "persistenceList[1].mountPath=/config", + "persistenceList[1].hostPath=/tmp", } tests := map[string]struct { values []string diff --git a/charts/library/common/tests/pod_test.go b/charts/library/common/tests/pod_test.go index f514703ccbc..e80755c112e 100644 --- a/charts/library/common/tests/pod_test.go +++ b/charts/library/common/tests/pod_test.go @@ -118,23 +118,28 @@ func (suite *PodTestSuite) TestPersistenceItems() { persistence: cache: enabled: true - emptyDir: - enabled: true + type: emptyDir config: enabled: true - emptyDir: - enabled: false data: enabled: true existingClaim: dataClaim + custom-mount: + enabled: true + type: custom + volumeSpec: + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels ` - tests := map[string]struct { values *string expectedVolumes []string }{ "Default": {values: nil, expectedVolumes: nil}, - "MultipleItems": {values: &values, expectedVolumes: []string{"config", "cache", "data"}}, + "MultipleItems": {values: &values, expectedVolumes: []string{"config", "cache", "data", "custom-mount"}}, } for name, tc := range tests { suite.Suite.Run(name, func() { @@ -214,8 +219,7 @@ func (suite *PodTestSuite) TestPersistenceEmptyDir() { persistence: config: enabled: true - emptyDir: - enabled: true + type: emptyDir ` tests := map[string]struct { values []string @@ -223,8 +227,8 @@ func (suite *PodTestSuite) TestPersistenceEmptyDir() { expectedSizeLimit string }{ "Enabled": {values: nil, expectedMedium: "", expectedSizeLimit: ""}, - "WithMedium": {values: []string{"persistence.config.emptyDir.medium=memory"}, expectedMedium: "memory", expectedSizeLimit: ""}, - "WithSizeLimit": {values: []string{"persistence.config.emptyDir.medium=memory", "persistence.config.emptyDir.sizeLimit=1Gi"}, expectedMedium: "memory", expectedSizeLimit: "1Gi"}, + "WithMedium": {values: []string{"persistence.config.medium=memory"}, expectedMedium: "memory", expectedSizeLimit: ""}, + "WithSizeLimit": {values: []string{"persistence.config.medium=memory", "persistence.config.sizeLimit=1Gi"}, expectedMedium: "memory", expectedSizeLimit: "1Gi"}, } for name, tc := range tests { suite.Suite.Run(name, func() { @@ -256,23 +260,25 @@ func (suite *PodTestSuite) TestPersistenceEmptyDir() { func (suite *PodTestSuite) TestHostPathVolumes() { values := ` - hostPathMounts: - - name: data - enabled: true - mountPath: "/data" - hostPath: "/tmp1" - - name: config - enabled: true - emptyDir: + persistence: + hostpathmounts-data: enabled: true - mountPath: "/data" + type: hostPath + hostPath: "/tmp1" + mountPath: "/data" + hostpathmounts-with-type: + enabled: true + type: hostPath + hostPath: "/tmp2" + hostPathType: "Directory" + mountPath: "/data2" ` tests := map[string]struct { values *string expectedVolumes []string }{ "Default": {values: nil, expectedVolumes: nil}, - "MultipleItems": {values: &values, expectedVolumes: []string{"hostpathmounts-data", "hostpathmounts-config"}}, + "MultipleItems": {values: &values, expectedVolumes: []string{"hostpathmounts-data", "hostpathmounts-with-type"}}, } for name, tc := range tests { suite.Suite.Run(name, func() { @@ -297,59 +303,6 @@ func (suite *PodTestSuite) TestHostPathVolumes() { } } -func (suite *PodTestSuite) TestHostPathVolumePaths() { - values := ` - hostPathMounts: - - name: data - enabled: true - mountPath: "/data" - hostPath: "/tmp1" - - name: config - enabled: true - emptyDir: - enabled: true - mountPath: "/data" - ` - tests := map[string]struct { - values *string - volumeToTest string - expectedPath string - emptyDir bool - }{ - "HostPath": {values: &values, volumeToTest: "hostpathmounts-data", expectedPath: "/tmp1", emptyDir: false}, - "EmptyDir": {values: &values, volumeToTest: "hostpathmounts-config", expectedPath: "", emptyDir: true}, - } - for name, tc := range tests { - suite.Suite.Run(name, func() { - err := suite.Chart.Render(nil, nil, tc.values) - if err != nil { - suite.FailNow(err.Error()) - } - - deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test") - volumes, _ := deploymentManifest.Path("spec.template.spec.volumes").Children() - - for _, volume := range volumes { - volumeName := volume.Path("name").Data().(string) - if volumeName == tc.volumeToTest { - if tc.expectedPath == "" { - suite.Assertions.Nil(volume.Path("hostPath.path")) - } else { - suite.Assertions.EqualValues(tc.expectedPath, volume.Path("hostPath.path").Data()) - } - - if tc.emptyDir == false { - suite.Assertions.Nil(volume.Path("emptyDir")) - } else { - suite.Assertions.NotNil(volume.Path("emptyDir")) - } - break - } - } - }) - } -} - func (suite *PodTestSuite) TestVolumeClaimTemplates() { values := ` volumeClaimTemplates: diff --git a/charts/library/common/tests/service_test.go b/charts/library/common/tests/service_test.go index c4b6e311a68..a4070ca5555 100644 --- a/charts/library/common/tests/service_test.go +++ b/charts/library/common/tests/service_test.go @@ -30,7 +30,7 @@ func (suite *ServiceTestSuite) TestServiceName() { expectedName string }{ "Default": {values: nil, expectedName: "common-test"}, - "CustomName": {values: []string{"service.main.nameOverride=http"}, expectedName: "common-test-http"}, + "CustomName": {values: []string{"service.main.nameOverride=main"}, expectedName: "common-test-main"}, } for name, tc := range tests { suite.Suite.Run(name, func() { diff --git a/charts/library/common/values.yaml b/charts/library/common/values.yaml index ba28d081553..3cdd9a67d3f 100644 --- a/charts/library/common/values.yaml +++ b/charts/library/common/values.yaml @@ -45,6 +45,9 @@ args: [] # -- Set annotations on the pod podAnnotations: {} +# -- Set labels on the pod +podLabels: {} + # -- Add a Horizontal Pod Autoscaler # @default -- autoscaling: @@ -79,10 +82,6 @@ secret: {} # C) PASSWD: # envFrom: # ... -# D) - name: TZ -# value: UTC -# E) - name: TZ -# value: '{{ .Release.Name }}' env: {} ## Variables with values set from templates, example ## With a release name of: demo, the example env value will be: demo-admin @@ -298,27 +297,34 @@ ingress: # hosts: # - chart-example.local -# -- Configure the persistent volumes for the chart here. +# -- Configure persistenceList for the chart here. +# Additional items can be added by adding a items similar to persistence +# @default -- [] +persistenceList: [] + +# -- Configure persistence for the chart here. # Additional items can be added by adding a dictionary key similar to the 'config' key. # @default -- See below persistence: # -- Default persistence for configuration files. # @default -- See below config: - # -- Enables or disables the persistent volume + # -- Enables or disables the persistence item enabled: false - # -- Where to mount the volume in the main container. - mountPath: /config + # -- Sets the persistence type + # Valid options are pvc, emptyDir, hostPath or custom + type: pvc + # -- Where to mount the volume in the main container. + # Defaults to `/`, + # setting to '-' creates the volume but disables the volumeMount. + mountPath: # /config + # -- Specify if the volume should be mounted read-only. + readOnly: false # -- Override the name suffix that is used for this volume. nameOverride: - emptyDir: - # -- Create an emptyDir volume instead of a persistent volume. - # [[ref]] (https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) - enabled: false - # -- Storage Class for the config volume. # If set to `-`, dynamic provisioning is disabled. # If set to `SCALE-ZFS`, the default provisioner for TrueNAS SCALE is used. @@ -343,31 +349,56 @@ persistence: # - Set to true to retain the PVC upon `helm uninstall` skipuninstall: false + # -- Create an emptyDir volume to share between all containers + # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) + # @default -- See below shared: - # -- Create an emptyDir volume to share between all containers enabled: false - emptyDir: - enabled: true - # -- Where to mount the shared volume in the main container. + type: emptyDir mountPath: /shared -# -- Mount a path on the host to the main container. -hostPathMounts: [] - # - name: "data" - # enabled: false - # emptyDir: - # enabled: false - # medium: "" - # mountPath: "/data" - # subPath: some-subpath - # hostPath: "" - # readOnly: false + # -- Set the medium to "Memory" to mount a tmpfs (RAM-backed filesystem) instead + # of the storage medium that backs the node. + medium: # Memory -# -- Specify any additional volumes here. (e.g. to mount nfs volumes directly) -additionalVolumes: [] + # -- If the `SizeMemoryBackedVolumes` feature gate is enabled, you can + # specify a size for memory backed volumes. + sizeLimit: # 1Gi -# -- Specify any additional volume mounts for the main container here. -additionalVolumeMounts: [] + # -- Example of a hostPath mount + # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) + # @default -- See below + host-dev: + enabled: false + type: hostPath + # -- Which path on the host should be mounted. + hostPath: /dev + # -- Where to mount the path in the main container. + # Defaults to the value of `hostPath` + mountPath: # /myDev + # -- Specifying a hostPathType adds a check before trying to mount the path. + # See Kubernetes documentation for options. + hostPathType: "" + # -- Specify if the path should be mounted read-only. + readOnly: true + + # -- Example of a custom mount + # @default -- See below + custom-mount: + enabled: false + type: custom + # -- Where to mount the volume in the main container. + # Defaults to `/`, + # setting to '-' creates the volume but disables the volumeMount. + mountPath: # /custom-mount + # -- Specify if the volume should be mounted read-only. + readOnly: false + # -- Define the custom Volume spec here + # [[ref]](https://kubernetes.io/docs/concepts/storage/volumes/) + volumeSpec: {} + # configMap: + # defaultMode: 420 + # name: my-settings # -- Used in conjunction with `controller.type: statefulset` to create individual disks for each instance. volumeClaimTemplates: [] @@ -414,3 +445,261 @@ resources: {} # requests: # cpu: 100m # memory: 128Mi + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#wireguard-vpn) + # @default -- See values.yaml + vpn: + # -- Enable running a VPN in the pod to route traffic through a VPN + enabled: false + + # -- Specify the VPN type. Valid options are openvpn or wireguard + type: openvpn + + # -- OpenVPN specific configuration + # @default -- See below + openvpn: + image: + # -- Specify the openvpn client image + repository: dperson/openvpn-client + # -- Specify the openvpn client image tag + tag: latest + # -- Specify the openvpn client image pull policy + pullPolicy: IfNotPresent + + # -- Credentials to connect to the VPN Service (used with -a) + auth: # "user;password" + # -- Optionally specify an existing secret that contains the credentials. + # Credentials should be stored under the `VPN_AUTH` key + authSecret: # my-vpn-secret + + # -- WireGuard specific configuration + # @default -- See below + wireguard: + image: + # -- Specify the WireGuard image + repository: docker pull ghcr.io/k8s-at-home/wireguard + # -- Specify the WireGuard image tag + tag: v1.0.20210424 + # -- Specify the WireGuard image pull policy + pullPolicy: IfNotPresent + + # -- Set the VPN container securityContext + # @default -- See values.yaml + securityContext: + capabilities: + add: + - NET_ADMIN + - SYS_MODULE + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: {} + # TZ: UTC + + # -- Provide a customized vpn configuration file to be used by the VPN. + configFile: # |- + # Some Example Config + # remote greatvpnhost.com 8888 + # auth-user-pass + # Cipher AES + + # -- Reference an existing secret that contains the VPN configuration file + # The chart expects it to be present under the `vpnConfigfile` key. + configFileSecret: + + # -- Provide custom up/down scripts that can be used by the vpn configuration. + # @default -- See values.yaml + scripts: + up: # |- + # #!/bin/bash + # echo "connected" > /shared/vpnstatus + down: # |- + # #!/bin/bash + # echo "disconnected" > /shared/vpnstatus + + additionalVolumeMounts: [] + + # -- Optionally specify a livenessProbe, e.g. to check if the connection is still + # being protected by the VPN + livenessProbe: {} + # exec: + # command: + # - sh + # - -c + # - if [ $(curl -s https://ipinfo.io/country) == 'US' ]; then exit 0; else exit $?; fi + # initialDelaySeconds: 30 + # periodSeconds: 60 + # failureThreshold: 1 + + # If set to true, will deploy a network policy that blocks all outbound + # traffic except traffic specified as allowed + networkPolicy: + enabled: false + + # The egress configuration for your network policy, All outbound traffic + # From the pod will be blocked unless specified here. Your cluster must + # have a CNI that supports network policies (Canal, Calico, etc...) + # https://kubernetes.io/docs/concepts/services-networking/network-policies/ + # https://github.com/ahmetb/kubernetes-network-policy-recipes + egress: + # - to: + # - ipBlock: + # cidr: 0.0.0.0/0 + # ports: + # - port: 53 + # protocol: UDP + # - port: 53 + # protocol: TCP + + # -- The common library supports adding a code-server add-on to access files. It can be configured under this key. + # For more info, check out [our docs](http://docs.k8s-at-home.com/our-helm-charts/common-library-add-ons/#code-server) + # @default -- See values.yaml + codeserver: + # -- Enable running a code-server container in the pod + enabled: false + + image: + # -- Specify the code-server image + repository: codercom/code-server + # -- Specify the code-server image tag + tag: 3.9.2 + # -- Specify the code-server image pull policy + pullPolicy: IfNotPresent + + # -- Set any environment variables for code-server here + env: {} + # TZ: UTC + + # -- Set codeserver command line arguments. + # Consider setting --user-data-dir to a persistent location to preserve code-server setting changes + args: + - --auth + - none + # - --user-data-dir + # - "/config/.vscode" + + # -- Specify a list of volumes that get mounted in the code-server container. + # At least 1 volumeMount is required! + volumeMounts: [] + # - name: config + # mountPath: /data/config + + # -- Specify the working dir that will be opened when code-server starts + # If not given, the app will default to the mountpah of the first specified volumeMount + workingDir: "" + + # -- Optionally allow access a Git repository by passing in a private SSH key + # @default -- See below + git: + # -- Raw SSH private key + deployKey: "" + # -- Base64-encoded SSH private key. When both variables are set, the raw SSH key takes precedence. + deployKeyBase64: "" + # -- Existing secret containing SSH private key + # The chart expects it to be present under the `id_rsa` key. + deployKeySecret: "" + + service: + # -- Enable a service for the code-server add-on. + enabled: true + type: ClusterIP + # Specify the default port information + ports: + codeserver: + port: 12321 + enabled: true + protocol: TCP + targetPort: codeserver + ## Specify the nodePort value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + # nodePort: + annotations: {} + labels: {} + + ingress: + # -- Enable an ingress for the code-server add-on. + enabled: false + nameOverride: codeserver + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + hosts: + - host: code.chart-example.local + paths: + - path: / + # Ignored if not kubeVersion >= 1.14-0 + pathType: Prefix + tls: [] + # - secretName: chart-example-tls + # hosts: + # - code.chart-example.local + + securityContext: + runAsUser: 0 + + # -- The common library supports adding a promtail add-on to to access logs and ship them to loki. It can be configured under this key. + # @default -- See values.yaml + promtail: + # -- Enable running a promtail container in the pod + enabled: false + + image: + # -- Specify the promtail image + repository: grafana/promtail + # -- Specify the promtail image tag + tag: 2.2.0 + # -- Specify the promtail image pull policy + pullPolicy: IfNotPresent + + # -- Set any environment variables for promtail here + env: {} + + # -- Set promtail command line arguments + args: [] + + # -- The URL to Loki + loki: "" + + # -- The paths to logs on the volume + logs: [] + # - name: log + # path: /config/logs/*.log + + # -- Specify a list of volumes that get mounted in the promtail container. + # At least 1 volumeMount is required! + volumeMounts: [] + # - name: config + # mountPath: /config + # readOnly: true + + securityContext: + runAsUser: 0 + + # -- The common library supports adding a netshoot add-on to troubleshoot network issues within a Pod. It can be configured under this key. + # @default -- See values.yaml + netshoot: + # -- Enable running a netshoot container in the pod + enabled: false + + image: + # -- Specify the netshoot image + repository: nicolaka/netshoot + # -- Specify the netshoot image tag + tag: latest + # -- Specify the netshoot image pull policy + pullPolicy: Always + + # -- Set any environment variables for netshoot here + env: {} + + securityContext: + capabilities: + add: + - NET_ADMIN