Feat: port addons from k8s-at-home to common (#948)

* Feat: port addons from k8s-at-home to common

* use an older version of upstream
This commit is contained in:
Kjeld Schouten-Lebbing
2021-09-09 20:55:33 +02:00
committed by GitHub
parent eec671de22
commit 5cb0b239e0
25 changed files with 1169 additions and 1 deletions

View File

@@ -18,4 +18,4 @@ maintainers:
name: common
sources: null
type: library
version: 6.13.11
version: 6.14.0

View File

@@ -8,6 +8,26 @@ Main entrypoint for the common library chart. It will render all underlying temp
{{- /* Build the templates */ -}}
{{- include "common.pvc" . }}
{{- /* Enable code-server add-on if required */ -}}
{{- if .Values.addons.codeserver.enabled }}
{{- include "common.addon.codeserver" . }}
{{- end -}}
{{- /* Enable VPN add-on if required */ -}}
{{- if .Values.addons.vpn.enabled }}
{{- include "common.addon.vpn" . }}
{{- end -}}
{{- /* Enable promtail add-on if required */ -}}
{{- if .Values.addons.promtail.enabled }}
{{- include "common.addon.promtail" . }}
{{- end -}}
{{- /* Enable netshoot add-on if required */ -}}
{{- if .Values.addons.netshoot.enabled }}
{{- include "common.addon.netshoot" . }}
{{- end -}}
{{- if .Values.serviceAccount.create -}}
{{- include "common.serviceAccount" . }}
{{- end -}}

View File

@@ -0,0 +1,51 @@
{{/*
Template to render code-server addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "common.addon.codeserver" -}}
{{- if .Values.addons.codeserver.enabled -}}
{{/* Append the code-server container to the additionalContainers */}}
{{- $container := include "common.addon.codeserver.container" . | fromYaml -}}
{{- if $container -}}
{{- $additionalContainers := append .Values.additionalContainers $container -}}
{{- $_ := set .Values "additionalContainers" $additionalContainers -}}
{{- end -}}
{{/* Include the deployKeySecret if not empty */}}
{{- $secret := include "common.addon.codeserver.deployKeySecret" . -}}
{{- if $secret -}}
{{- $secret | nindent 0 -}}
{{- end -}}
{{/* Append the secret volume to the volumes */}}
{{- $volume := include "common.addon.codeserver.deployKeyVolumeSpec" . | fromYaml -}}
{{- if $volume -}}
{{- $_ := set .Values.persistence "deploykey" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $volume) -}}
{{- end -}}
{{/* Add the code-server service */}}
{{- if .Values.addons.codeserver.service.enabled -}}
{{- $serviceValues := .Values.addons.codeserver.service -}}
{{- $_ := set $serviceValues "nameOverride" "codeserver" -}}
{{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}}
{{- include "common.classes.service" $ -}}
{{- $_ := unset $ "ObjectValues" -}}
{{- end -}}
{{/* Add the code-server ingress */}}
{{- if .Values.addons.codeserver.ingress.enabled -}}
{{- $ingressValues := .Values.addons.codeserver.ingress -}}
{{- $_ := set $ingressValues "nameOverride" "codeserver" -}}
{{/* Determine the target service name & port */}}
{{- $svcName := printf "%v-codeserver" (include "common.names.fullname" .) -}}
{{- $svcPort := .Values.addons.codeserver.service.ports.codeserver.port -}}
{{- range $_, $host := $ingressValues.hosts -}}
{{- $_ := set (index $host.paths 0) "service" (dict "name" $svcName "port" $svcPort) -}}
{{- end -}}
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
{{- include "common.classes.ingress" $ -}}
{{- $_ := unset $ "ObjectValues" -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,46 @@
{{/*
The code-server sidecar container to be inserted.
*/}}
{{- define "common.addon.codeserver.container" -}}
{{- if lt (len .Values.addons.codeserver.volumeMounts) 1 }}
{{- fail "At least 1 volumeMount is required for codeserver container" }}
{{- end -}}
name: codeserver
image: "{{ .Values.addons.codeserver.image.repository }}:{{ .Values.addons.codeserver.image.tag }}"
imagePullPolicy: {{ .Values.addons.codeserver.pullPolicy }}
{{- with .Values.addons.codeserver.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.codeserver.env }}
env:
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
ports:
- name: codeserver
containerPort: {{ .Values.addons.codeserver.service.ports.codeserver.port }}
protocol: TCP
args:
{{- range .Values.addons.codeserver.args }}
- {{ . | quote }}
{{- end }}
- "--port"
- "{{ .Values.addons.codeserver.service.ports.codeserver.port }}"
- {{ .Values.addons.codeserver.workingDir | default (first .Values.addons.codeserver.volumeMounts).mountPath }}
volumeMounts:
{{- with .Values.addons.codeserver.volumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- if or .Values.addons.codeserver.git.deployKey .Values.addons.codeserver.git.deployKeyBase64 .Values.addons.codeserver.git.deployKeySecret }}
- name: deploykey
mountPath: /root/.ssh/id_rsa
subPath: id_rsa
{{- end }}
{{- with .Values.addons.codeserver.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,22 @@
{{/*
The OpenVPN credentials secrets to be included.
*/}}
{{- define "common.addon.codeserver.deployKeySecret" -}}
{{- if or .Values.addons.codeserver.git.deployKey .Values.addons.codeserver.git.deployKeyBase64 }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "common.names.fullname" . }}-deploykey
labels:
{{- include "common.labels" . | nindent 4 }}
type: Opaque
{{- if .Values.addons.codeserver.git.deployKey }}
stringData:
id_rsa: {{ .Values.addons.codeserver.git.deployKey | quote }}
{{- else }}
data:
id_rsa: {{ .Values.addons.codeserver.git.deployKeyBase64 | quote }}
{{- end }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,17 @@
{{/*
The volume (referencing git deploykey) to be inserted into additionalVolumes.
*/}}
{{- define "common.addon.codeserver.deployKeyVolumeSpec" -}}
{{- if or .Values.addons.codeserver.git.deployKey .Values.addons.codeserver.git.deployKeyBase64 .Values.addons.codeserver.git.deployKeySecret }}
secret:
{{- if .Values.addons.codeserver.git.deployKeySecret }}
secretName: {{ .Values.addons.codeserver.git.deployKeySecret }}
{{- else }}
secretName: {{ include "common.names.fullname" . }}-deploykey
{{- end }}
defaultMode: 256
items:
- key: id_rsa
path: id_rsa
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,27 @@
{{/*
The netshoot sidecar container to be inserted.
*/}}
{{- define "common.addon.netshoot.container" -}}
name: netshoot
image: "{{ .Values.addons.netshoot.image.repository }}:{{ .Values.addons.netshoot.image.tag }}"
imagePullPolicy: {{ .Values.addons.netshoot.pullPolicy }}
{{- with .Values.addons.netshoot.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.netshoot.env }}
env:
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
command:
- /bin/sh
- -c
- sleep infinity
{{- with .Values.addons.netshoot.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,14 @@
{{/*
Template to render netshoot addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "common.addon.netshoot" -}}
{{- if .Values.addons.netshoot.enabled -}}
{{/* Append the netshoot container to the additionalContainers */}}
{{- $container := include "common.addon.netshoot.container" . | fromYaml -}}
{{- if $container -}}
{{- $additionalContainers := append .Values.additionalContainers $container -}}
{{- $_ := set .Values "additionalContainers" $additionalContainers -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,35 @@
{{/*
The promtail config to be included.
*/}}
{{- define "common.addon.promtail.configmap" -}}
{{- if .Values.addons.promtail.enabled }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "common.names.fullname" . }}-promtail
labels:
{{- include "common.labels" . | nindent 4 }}
data:
promtail.yaml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
{{- with .Values.addons.promtail.loki }}
client:
url: {{ . }}
{{- end }}
scrape_configs:
{{- range .Values.addons.promtail.logs }}
- job_name: {{ .name }}
static_configs:
- targets:
- localhost
labels:
job: {{ .name }}
__path__: "{{ .path }}"
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,39 @@
{{/*
The promtail sidecar container to be inserted.
*/}}
{{- define "common.addon.promtail.container" -}}
{{- if lt (len .Values.addons.promtail.volumeMounts) 1 }}
{{- fail "At least 1 volumeMount is required for the promtail container" }}
{{- end -}}
name: promtail
image: "{{ .Values.addons.promtail.image.repository }}:{{ .Values.addons.promtail.image.tag }}"
imagePullPolicy: {{ .Values.addons.promtail.pullPolicy }}
{{- with .Values.addons.promtail.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.promtail.env }}
env:
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
args:
{{- range .Values.addons.promtail.args }}
- {{ . | quote }}
{{- end }}
- "-config.file=/etc/promtail/promtail.yaml"
volumeMounts:
- name: promtail-config
mountPath: /etc/promtail/promtail.yaml
subPath: promtail.yaml
readOnly: true
{{- with .Values.addons.promtail.volumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.promtail.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,26 @@
{{/*
Template to render promtail addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "common.addon.promtail" -}}
{{- if .Values.addons.promtail.enabled -}}
{{/* Append the promtail container to the additionalContainers */}}
{{- $container := include "common.addon.promtail.container" . | fromYaml -}}
{{- if $container -}}
{{- $additionalContainers := append .Values.additionalContainers $container -}}
{{- $_ := set .Values "additionalContainers" $additionalContainers -}}
{{- end -}}
{{/* Include the configmap if not empty */}}
{{- $configmap := include "common.addon.promtail.configmap" . -}}
{{- if $configmap -}}
{{- $configmap | nindent 0 -}}
{{- end -}}
{{/* Append the promtail config volume to the volumes */}}
{{- $volume := include "common.addon.promtail.volumeSpec" . | fromYaml -}}
{{- if $volume -}}
{{- $_ := set .Values.persistence "promtail-config" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $volume) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,7 @@
{{/*
The volume (referencing config) to be inserted into additionalVolumes.
*/}}
{{- define "common.addon.promtail.volumeSpec" -}}
configMap:
name: {{ include "common.names.fullname" . }}-promtail
{{- end -}}

View File

@@ -0,0 +1,23 @@
{{/*
The VPN config and scripts to be included.
*/}}
{{- define "common.addon.vpn.configmap" -}}
{{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "common.names.fullname" . }}-vpn
labels:
{{- include "common.labels" . | nindent 4 }}
data:
{{- with .Values.addons.vpn.scripts.up }}
up.sh: |-
{{- . | nindent 4}}
{{- end }}
{{- with .Values.addons.vpn.scripts.down }}
down.sh: |-
{{- . | nindent 4}}
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,19 @@
{{/*
The OpenVPN config secret to be included.
*/}}
{{- define "common.addon.vpn.secret" -}}
{{- if and .Values.addons.vpn.configFile (not .Values.addons.vpn.configFileSecret) }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "common.names.fullname" . }}-vpnconfig
labels:
{{- include "common.labels" $ | nindent 4 }}
stringData:
{{- with .Values.addons.vpn.configFile }}
vpnConfigfile: |-
{{- . | nindent 4}}
{{- end }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,37 @@
{{/*
The volume (referencing VPN scripts) to be inserted into additionalVolumes.
*/}}
{{- define "common.addon.vpn.scriptsVolumeSpec" -}}
{{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down -}}
configMap:
name: {{ include "common.names.fullname" . }}-vpn
items:
{{- if .Values.addons.vpn.scripts.up }}
- key: up.sh
path: up.sh
mode: 0777
{{- end }}
{{- if .Values.addons.vpn.scripts.down }}
- key: down.sh
path: down.sh
mode: 0777
{{- end }}
{{- end -}}
{{- end -}}
{{/*
The volume (referencing VPN config) to be inserted into additionalVolumes.
*/}}
{{- define "common.addon.vpn.configVolumeSpec" -}}
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.configFileSecret -}}
secret:
{{- if .Values.addons.vpn.configFileSecret }}
secretName: {{ .Values.addons.vpn.configFileSecret }}
{{- else }}
secretName: {{ include "common.names.fullname" . }}-vpnconfig
{{- end }}
items:
- key: vpnConfigfile
path: vpnConfigfile
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,40 @@
{{/*
Template to render VPN addon
It will include / inject the required templates based on the given values.
*/}}
{{- define "common.addon.vpn" -}}
{{- if .Values.addons.vpn.enabled -}}
{{- if eq "openvpn" .Values.addons.vpn.type -}}
{{- include "common.addon.openvpn" . }}
{{- end -}}
{{- if eq "wireguard" .Values.addons.vpn.type -}}
{{- include "common.addon.wireguard" . }}
{{- end -}}
{{/* Include the configmap if not empty */}}
{{- $configmap := include "common.addon.vpn.configmap" . -}}
{{- if $configmap -}}
{{- $configmap | nindent 0 -}}
{{- end -}}
{{/* Include the secret if not empty */}}
{{- $secret := include "common.addon.vpn.secret" . -}}
{{- if $secret -}}
{{- $secret | nindent 0 -}}
{{- end -}}
{{/* Append the vpn scripts volume to the volumes */}}
{{- $scriptVolume := include "common.addon.vpn.scriptsVolumeSpec" . | fromYaml -}}
{{- if $scriptVolume -}}
{{- $_ := set .Values.persistence "vpnscript" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $scriptVolume) -}}
{{- end -}}
{{/* Append the vpn config volume to the volumes */}}
{{- $configVolume := include "common.addon.vpn.configVolumeSpec" . | fromYaml }}
{{ if $configVolume -}}
{{- $_ := set .Values.persistence "vpnconfig" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $configVolume) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,18 @@
{{/*
Template to render OpenVPN addon. It will add the container to the list of additionalContainers
and add a credentials secret if speciffied.
*/}}
{{- define "common.addon.openvpn" -}}
{{/* Append the openVPN container to the additionalContainers */}}
{{- $container := include "common.addon.openvpn.container" . | fromYaml -}}
{{- if $container -}}
{{- $additionalContainers := append .Values.additionalContainers $container -}}
{{- $_ := set .Values "additionalContainers" $additionalContainers -}}
{{- end -}}
{{/* Include the secret if not empty */}}
{{- $secret := include "common.addon.openvpn.secret" . -}}
{{- if $secret -}}
{{- $secret | nindent 0 -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,61 @@
{{/*
The OpenVPN sidecar container to be inserted.
*/}}
{{- define "common.addon.openvpn.container" -}}
name: openvpn
image: "{{ .Values.addons.vpn.openvpn.image.repository }}:{{ .Values.addons.vpn.openvpn.image.tag }}"
imagePullPolicy: {{ .Values.addons.vpn.openvpn.pullPolicy }}
{{- with .Values.addons.vpn.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.vpn.env }}
env:
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
{{- if or .Values.addons.vpn.openvpn.auth .Values.addons.vpn.openvpn.authSecret }}
envFrom:
- secretRef:
{{- if .Values.addons.vpn.openvpn.authSecret }}
name: {{ .Values.addons.vpn.openvpn.authSecret }}
{{- else }}
name: {{ include "common.names.fullname" . }}-openvpn
{{- end }}
{{- end }}
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.configFileSecret .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down .Values.addons.vpn.additionalVolumeMounts .Values.persistence.shared.enabled }}
volumeMounts:
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.configFileSecret }}
- name: vpnconfig
mountPath: /vpn/vpn.conf
subPath: vpnConfigfile
{{- end }}
{{- if .Values.addons.vpn.scripts.up }}
- name: vpnscript
mountPath: /vpn/up.sh
subPath: up.sh
{{- end }}
{{- if .Values.addons.vpn.scripts.down }}
- name: vpnscript
mountPath: /vpn/down.sh
subPath: down.sh
{{- end }}
{{- if .Values.persistence.shared.enabled }}
- mountPath: {{ .Values.persistence.shared.mountPath }}
name: shared
{{- end }}
{{- with .Values.addons.vpn.additionalVolumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- with .Values.addons.vpn.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- with .Values.addons.vpn.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,16 @@
{{/*
The OpenVPN credentials secrets to be included.
*/}}
{{- define "common.addon.openvpn.secret" -}}
{{- with .Values.addons.vpn.openvpn.auth }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ include "common.names.fullname" $ }}-openvpn
labels:
{{- include "common.labels" $ | nindent 4 }}
data:
VPN_AUTH: {{ . | b64enc }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,12 @@
{{/*
Template to render Wireguard addon. It will add the container to the list of additionalContainers.
*/}}
*/}}
{{- define "common.addon.wireguard" -}}
{{/* Append the Wireguard container to the additionalContainers */}}
{{- $container := fromYaml (include "common.addon.wireguard.container" .) -}}
{{- if $container -}}
{{- $additionalContainers := append .Values.additionalContainers $container -}}
{{- $_ := set .Values "additionalContainers" $additionalContainers -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,52 @@
{{/*
The Wireguard sidecar container to be inserted.
*/}}
{{- define "common.addon.wireguard.container" -}}
name: wireguard
image: "{{ .Values.addons.vpn.wireguard.image.repository }}:{{ .Values.addons.vpn.wireguard.image.tag }}"
imagePullPolicy: {{ .Values.addons.vpn.wireguard.pullPolicy }}
{{- with .Values.addons.vpn.securityContext }}
securityContext:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- with .Values.addons.vpn.env }}
env:
{{- range $k, $v := . }}
- name: {{ $k }}
value: {{ $v | quote }}
{{- end }}
{{- end }}
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.configFileSecret .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down .Values.addons.vpn.additionalVolumeMounts .Values.persistence.shared.enabled }}
volumeMounts:
{{- if or .Values.addons.vpn.configFile .Values.addons.vpn.configFileSecret }}
- name: vpnconfig
mountPath: /etc/wireguard/wg0.conf
subPath: vpnConfigfile
{{- end }}
{{- if .Values.addons.vpn.scripts.up }}
- name: vpnscript
mountPath: /config/up.sh
subPath: up.sh
{{- end }}
{{- if .Values.addons.vpn.scripts.down }}
- name: vpnscript
mountPath: /config/down.sh
subPath: down.sh
{{- end }}
{{- if .Values.persistence.shared.enabled }}
- mountPath: {{ .Values.persistence.shared.mountPath }}
name: shared
{{- end }}
{{- with .Values.addons.vpn.additionalVolumeMounts }}
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end }}
{{- with .Values.addons.vpn.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 2 }}
{{- end -}}
{{- with .Values.addons.vpn.resources }}
resources:
{{- toYaml . | nindent 2 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,136 @@
package common
import (
"testing"
"github.com/Jeffail/gabs/v2"
"github.com/truecharts/apps/tests/helmunit"
"github.com/stretchr/testify/suite"
)
type AddonCodeserverTestSuite struct {
suite.Suite
Chart helmunit.HelmChart
baseValues string
}
func (suite *AddonCodeserverTestSuite) SetupSuite() {
suite.Chart = helmunit.New("common-test", "../../common-test")
suite.Chart.UpdateDependencies()
suite.baseValues = `
addons:
codeserver:
enabled: true
volumeMounts:
- name: "config"
mountPath: "/data/config"
`
}
// We need this function to kick off the test suite, otherwise
// "go test" won't know about our tests
func TestAddonCodeserver(t *testing.T) {
suite.Run(t, new(AddonCodeserverTestSuite))
}
func (suite *AddonCodeserverTestSuite) TestContainer() {
tests := map[string]struct {
values *string
expectedCodeserverContainer bool
}{
"Default": {values: nil, expectedCodeserverContainer: false},
"AddonEnabled": {values: &suite.baseValues, expectedCodeserverContainer: 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")
suite.Assertions.NotEmpty(deploymentManifest)
containers := deploymentManifest.Path("spec.template.spec.containers").Children()
var codeserverContainer *gabs.Container
for _, container := range containers {
containerName := container.Path("name").Data().(string)
if containerName == "codeserver" {
codeserverContainer = container
break
}
}
if tc.expectedCodeserverContainer {
suite.Assertions.NotEmpty(codeserverContainer)
} else {
suite.Assertions.Empty(codeserverContainer)
}
})
}
}
func (suite *AddonCodeserverTestSuite) TestDeployKey() {
tests := map[string]struct {
values []string
expectSecret bool
expectedSecretName string
}{
"Inline": {values: []string{"addons.codeserver.git.deployKey=test"}, expectSecret: true, expectedSecretName: "common-test-deploykey"},
"InlineBase64": {values: []string{"addons.codeserver.git.deployKeyBase64=dGVzdEtleQ=="}, expectSecret: true, expectedSecretName: "common-test-deploykey"},
"ExistingSecret": {values: []string{"addons.codeserver.git.deployKeySecret=test-secret"}, expectSecret: false, expectedSecretName: "test-secret"},
}
for name, tc := range tests {
suite.Suite.Run(name, func() {
err := suite.Chart.Render(nil, tc.values, &suite.baseValues)
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)
}
deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test")
suite.Assertions.NotEmpty(deploymentManifest)
containers := deploymentManifest.Path("spec.template.spec.containers").Children()
var codeserverContainer *gabs.Container
for _, container := range containers {
containerName := container.Path("name").Data().(string)
if containerName == "codeserver" {
codeserverContainer = container
break
}
}
suite.Assertions.NotEmpty(codeserverContainer)
volumeMounts := codeserverContainer.Path("volumeMounts").Children()
var gitDeploykeyVolumeMount *gabs.Container
for _, volumeMount := range volumeMounts {
volumeMountName := volumeMount.Path("name").Data().(string)
if volumeMountName == "deploykey" {
gitDeploykeyVolumeMount = volumeMount
break
}
}
suite.Assertions.NotEmpty(gitDeploykeyVolumeMount)
suite.Assertions.EqualValues("/root/.ssh/id_rsa", gitDeploykeyVolumeMount.Path("mountPath").Data())
suite.Assertions.EqualValues("id_rsa", gitDeploykeyVolumeMount.Path("subPath").Data())
volumes := deploymentManifest.Path("spec.template.spec.volumes").Children()
var gitDeploykeyVolume *gabs.Container
for _, volume := range volumes {
volumeName := volume.Path("name").Data().(string)
if volumeName == "deploykey" {
gitDeploykeyVolume = volume
break
}
}
suite.Assertions.NotEmpty(gitDeploykeyVolume)
})
}
}

View File

@@ -0,0 +1,64 @@
package common
import (
"testing"
"github.com/Jeffail/gabs/v2"
"github.com/truecharts/apps/tests/helmunit"
"github.com/stretchr/testify/suite"
)
type AddonNetshootTestSuite struct {
suite.Suite
Chart helmunit.HelmChart
baseValues []string
}
func (suite *AddonNetshootTestSuite) SetupSuite() {
suite.Chart = helmunit.New("common-test", "../../common-test")
suite.Chart.UpdateDependencies()
suite.baseValues = []string{"addons.netshoot.enabled=true"}
}
// We need this function to kick off the test suite, otherwise
// "go test" won't know about our tests
func TestAddonNetshoot(t *testing.T) {
suite.Run(t, new(AddonNetshootTestSuite))
}
func (suite *AddonNetshootTestSuite) TestContainer() {
tests := map[string]struct {
values []string
expectedNetshootContainer bool
}{
"Default": {values: nil, expectedNetshootContainer: false},
"AddonEnabled": {values: suite.baseValues, expectedNetshootContainer: true},
}
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()
var netshootContainer *gabs.Container
for _, container := range containers {
containerName := container.Path("name").Data().(string)
if containerName == "netshoot" {
netshootContainer = container
break
}
}
if tc.expectedNetshootContainer {
suite.Assertions.NotEmpty(netshootContainer)
} else {
suite.Assertions.Empty(netshootContainer)
}
})
}
}

View File

@@ -0,0 +1,129 @@
package common
import (
"testing"
"github.com/Jeffail/gabs/v2"
"github.com/truecharts/apps/tests/helmunit"
"github.com/stretchr/testify/suite"
)
type AddonVpnTestSuite struct {
suite.Suite
Chart helmunit.HelmChart
baseValues []string
}
func (suite *AddonVpnTestSuite) SetupSuite() {
suite.Chart = helmunit.New("common-test", "../../common-test")
suite.Chart.UpdateDependencies()
suite.baseValues = []string{"addons.vpn.enabled=true"}
}
// We need this function to kick off the test suite, otherwise
// "go test" won't know about our tests
func TestAddonVpn(t *testing.T) {
suite.Run(t, new(AddonVpnTestSuite))
}
func (suite *AddonVpnTestSuite) TestContainer() {
tests := map[string]struct {
values []string
expectedVpnContainer bool
}{
"Default": {values: nil, expectedVpnContainer: false},
"AddonEnabled": {values: suite.baseValues, expectedVpnContainer: true},
}
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()
var vpnContainer *gabs.Container
for _, container := range containers {
containerName := container.Path("name").Data().(string)
if containerName == "openvpn" {
vpnContainer = container
break
}
}
if tc.expectedVpnContainer {
suite.Assertions.NotEmpty(vpnContainer)
} else {
suite.Assertions.Empty(vpnContainer)
}
})
}
}
func (suite *AddonVpnTestSuite) TestConfiguration() {
tests := map[string]struct {
values []string
expectSecret bool
expectedSecretName string
}{
"InlineConfig": {values: append(suite.baseValues, "addons.vpn.configFile=test"), expectSecret: true, expectedSecretName: "common-test-vpnconfig"},
"ExistingSecret": {values: append(suite.baseValues, "addons.vpn.configFileSecret=test-secret"), expectSecret: false, expectedSecretName: "test-secret"},
}
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)
}
deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test")
suite.Assertions.NotEmpty(deploymentManifest)
containers := deploymentManifest.Path("spec.template.spec.containers").Children()
var vpnContainer *gabs.Container
for _, container := range containers {
containerName := container.Path("name").Data().(string)
if containerName == "openvpn" {
vpnContainer = container
break
}
}
suite.Assertions.NotEmpty(vpnContainer)
volumeMounts := vpnContainer.Path("volumeMounts").Children()
var vpnConfigVolumeMount *gabs.Container
for _, volumeMount := range volumeMounts {
volumeMountName := volumeMount.Path("name").Data().(string)
if volumeMountName == "vpnconfig" {
vpnConfigVolumeMount = volumeMount
break
}
}
suite.Assertions.NotEmpty(vpnConfigVolumeMount)
suite.Assertions.EqualValues("/vpn/vpn.conf", vpnConfigVolumeMount.Path("mountPath").Data())
suite.Assertions.EqualValues("vpnConfigfile", vpnConfigVolumeMount.Path("subPath").Data())
volumes := deploymentManifest.Path("spec.template.spec.volumes").Children()
var vpnConfigVolume *gabs.Container
for _, volume := range volumes {
volumeName := volume.Path("name").Data().(string)
if volumeName == "vpnconfig" {
vpnConfigVolume = volume
break
}
}
suite.Assertions.NotEmpty(vpnConfigVolume)
})
}
}

View File

@@ -613,3 +613,260 @@ 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: 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
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