mirror of
https://github.com/truecharts/charts.git
synced 2026-07-09 08:55:13 -03:00
port most recent changes from KAH (#478)
* port most recent changes from KAH * add general shizzle * add rests of go tests * whoops * hmm * make pre-release wait more * try another synthaxis * okey... * test-> tests * Make unittests a bit more usefull
This commit is contained in:
committed by
GitHub
parent
fd43d79929
commit
d3033f71fb
@@ -1,26 +1,36 @@
|
||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/ruby/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Ruby version: 2, 2.7, 2.6, 2.5
|
||||
ARG VARIANT="2"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/ruby:0-${VARIANT}
|
||||
ARG VARIANT="1.16"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT}
|
||||
|
||||
ARG HELM_VERSION="3.5.4"
|
||||
ARG CT_VERSION=3.3.1
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
COPY Gemfile /tmp/Gemfile
|
||||
|
||||
RUN \
|
||||
apt-get update \
|
||||
&& \
|
||||
apt-get -y install --no-install-recommends \
|
||||
jq \
|
||||
libjq-dev \
|
||||
libonig-dev \
|
||||
gnupg2 \
|
||||
python3-pip \
|
||||
python3-setuptools \
|
||||
&& \
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin \
|
||||
&& \
|
||||
curl -fsSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | /bin/bash - \
|
||||
curl -o /tmp/helm.tar.gz "https://get.helm.sh/helm-v${HELM_VERSION}-linux-$(dpkg --print-architecture).tar.gz" \
|
||||
&& tar xvzf /tmp/helm.tar.gz -C /usr/local/bin --strip-components 1 "linux-$(dpkg --print-architecture)/helm" \
|
||||
&& chmod +x /usr/local/bin/helm \
|
||||
&& \
|
||||
bundle config set system 'true' \
|
||||
&& bundle install --gemfile /tmp/Gemfile \
|
||||
&& rm /tmp/Gemfile
|
||||
curl -o /tmp/ct.tar.gz -L "https://github.com/helm/chart-testing/releases/download/v${CT_VERSION}/chart-testing_${CT_VERSION}_linux_$(dpkg --print-architecture).tar.gz" \
|
||||
&& mkdir -p /etc/ct \
|
||||
&& tar xvzf /tmp/ct.tar.gz -C /usr/local/bin "ct" \
|
||||
&& tar xvzf /tmp/ct.tar.gz --strip-components=1 -C /etc/ct "etc/" \
|
||||
&& chmod +x /usr/local/bin/ct \
|
||||
&& \
|
||||
pip3 install \
|
||||
pre-commit \
|
||||
yamale \
|
||||
yamllint \
|
||||
&& \
|
||||
rm \
|
||||
/tmp/helm.tar.gz \
|
||||
/tmp/ct.tar.gz
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/ruby
|
||||
{
|
||||
"name": "Ruby",
|
||||
"build": {
|
||||
"context": "..",
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
// Update 'VARIANT' to pick a Ruby version: 2, 2.7, 2.6, 2.5
|
||||
"VARIANT": "2.7",
|
||||
}
|
||||
},
|
||||
"name": "Go",
|
||||
"build": {
|
||||
"context": "..",
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
"VARIANT": "1.16",
|
||||
}
|
||||
},
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools",
|
||||
"rebornix.Ruby"
|
||||
],
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools",
|
||||
"golang.go"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "export RUBYJQ_USE_SYSTEM_LIBRARIES=1 && bundle install",
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "export RUBYJQ_USE_SYSTEM_LIBRARIES=1 && bundle install",
|
||||
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||
"remoteUser": "vscode"
|
||||
}
|
||||
|
||||
99
.github/workflows/apps.yaml
vendored
99
.github/workflows/apps.yaml
vendored
@@ -59,6 +59,80 @@ jobs:
|
||||
echo "::set-output name=empty_matrix::false"
|
||||
fi
|
||||
|
||||
app-unit-tests:
|
||||
needs: [changes]
|
||||
if: ${{ needs.changes.outputs.empty_matrix == 'false' }}
|
||||
name: App Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix: ${{ fromJson(needs.changes.outputs.matrix) }}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
if: ${{ matrix.app != '.gitkee' }}
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare-Lint
|
||||
if: ${{ matrix.app != '.gitkee' }}
|
||||
id: prep-lint
|
||||
run: |
|
||||
if test -f "./charts/stable/${{ matrix.app }}/Chart.yaml"; then
|
||||
train="stable"
|
||||
elif test -f "./charts/incubator/${{ matrix.app }}/Chart.yaml"; then
|
||||
train="incubator"
|
||||
elif test -f "./charts/deprecated/${{ matrix.app }}/Chart.yaml"; then
|
||||
train="deprecated"
|
||||
elif test -f "./charts/non-free/${{ matrix.app }}/Chart.yaml"; then
|
||||
train="non-free"
|
||||
elif test -f "./charts/library/${{ matrix.app }}/Chart.yaml"; then
|
||||
train="library"
|
||||
else
|
||||
train="develop"
|
||||
fi
|
||||
echo ::set-output name=train::${train}
|
||||
if test -d "./charts/${train}/${{ matrix.app }}/tests/"; then
|
||||
unittests='true'
|
||||
echo "::set-output name=unittests::true"
|
||||
else
|
||||
unittests="false"
|
||||
echo "::set-output name=unittests::false"
|
||||
fi
|
||||
|
||||
- uses: actions/setup-go@v2
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
with:
|
||||
go-version: '^1.16'
|
||||
|
||||
# Get values for cache paths to be used in later steps
|
||||
- id: go-cache-paths
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
run: |
|
||||
echo "::set-output name=go-build::$(go env GOCACHE)"
|
||||
echo "::set-output name=go-mod::$(go env GOMODCACHE)"
|
||||
# Cache go build cache, used to speedup go test
|
||||
- name: Go Build Cache
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.go-cache-paths.outputs.go-build }}
|
||||
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Download modules
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
run: |
|
||||
go mod download
|
||||
- name: Run tests
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
run: |
|
||||
go test ./charts/.../tests -json | tee test.json
|
||||
- name: Annotate tests
|
||||
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
|
||||
uses: guyarb/golang-test-annotations@v0.3.0
|
||||
with:
|
||||
test-results: test.json
|
||||
|
||||
app-tests:
|
||||
needs: [changes]
|
||||
if: ${{ needs.changes.outputs.empty_matrix == 'false' }}
|
||||
@@ -104,16 +178,6 @@ jobs:
|
||||
with:
|
||||
python-version: 3.7
|
||||
|
||||
- name: Install Dev tools for unittests
|
||||
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
|
||||
run: sudo apt-get update && sudo apt-get install -y jq libjq-dev
|
||||
|
||||
- name: Install Ruby for unittests
|
||||
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.7
|
||||
|
||||
- name: Set up chart-testing
|
||||
if: ${{ matrix.app != '.gitkee' }}
|
||||
uses: helm/chart-testing-action@v2.0.1
|
||||
@@ -123,17 +187,6 @@ jobs:
|
||||
id: lint
|
||||
run: ct lint --config .github/ct-lint.yaml --charts 'charts/${{ steps.prep-lint.outputs.train }}/${{ matrix.app }}'
|
||||
|
||||
- name: Install dependencies
|
||||
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
|
||||
run: |
|
||||
export RUBYJQ_USE_SYSTEM_LIBRARIES=1
|
||||
bundle install
|
||||
|
||||
- name: Run common unit tests
|
||||
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
|
||||
run: |
|
||||
bundle exec m -r tests
|
||||
|
||||
- name: Create k3d cluster
|
||||
if: ${{ matrix.app != 'common' && matrix.app != '.gitkee' }}
|
||||
uses: nolar/setup-k3d-k3s@v1
|
||||
@@ -146,7 +199,7 @@ jobs:
|
||||
run: ct install --config .github/ct-install.yaml --charts 'charts/${{ steps.prep-lint.outputs.train }}/${{ matrix.app }}'
|
||||
|
||||
app-tests-complete:
|
||||
needs: [app-tests]
|
||||
needs: [app-tests, app-unit-tests]
|
||||
name: Apps Test Complete
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -154,7 +207,7 @@ jobs:
|
||||
run: echo "App Tests Completed Successfully"
|
||||
|
||||
pre-release:
|
||||
needs: [app-tests]
|
||||
needs: [app-tests, app-unit-tests]
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release: ${{ steps.prep.outputs.release }}
|
||||
|
||||
2
.vscode/extensions.json
vendored
2
.vscode/extensions.json
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"ms-vscode-remote.remote-containers",
|
||||
"rebornix.ruby"
|
||||
"golang.go"
|
||||
]
|
||||
}
|
||||
|
||||
36
.vscode/launch.json
vendored
36
.vscode/launch.json
vendored
@@ -1,34 +1,18 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "UnitTest - active spec file only",
|
||||
"type": "Ruby",
|
||||
"name": "Common",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"program": "/usr/local/bin/bundle",
|
||||
"args": [
|
||||
"exec",
|
||||
"m",
|
||||
"-r",
|
||||
"${relativeFile}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UnitTest - all spec files",
|
||||
"type": "Ruby",
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"program": "/usr/local/bin/bundle",
|
||||
"args": [
|
||||
"exec",
|
||||
"m",
|
||||
"-r",
|
||||
"${workspaceFolder}/tests"
|
||||
]
|
||||
"mode": "test",
|
||||
"remotePath": "",
|
||||
"port": 2345,
|
||||
"host": "127.0.0.1",
|
||||
"program": "${workspaceRoot}/charts/library/common/tests/",
|
||||
"env": {},
|
||||
"args": ["-test.v"],
|
||||
"showLog": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
12
Gemfile
12
Gemfile
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
|
||||
group :test do
|
||||
gem 'm'
|
||||
gem 'minitest'
|
||||
gem 'minitest-implicit-subject'
|
||||
gem 'minitest-reporters'
|
||||
gem 'pry'
|
||||
gem 'ruby-jq'
|
||||
end
|
||||
42
Gemfile.lock
42
Gemfile.lock
@@ -1,42 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ansi (1.5.0)
|
||||
builder (3.2.4)
|
||||
coderay (1.1.3)
|
||||
m (1.5.1)
|
||||
method_source (>= 0.6.7)
|
||||
rake (>= 0.9.2.2)
|
||||
method_source (1.0.0)
|
||||
mini_portile2 (2.5.0)
|
||||
minitest (5.14.4)
|
||||
minitest-implicit-subject (1.4.0)
|
||||
minitest
|
||||
minitest-reporters (1.4.3)
|
||||
ansi
|
||||
builder
|
||||
minitest (>= 5.0)
|
||||
ruby-progressbar
|
||||
multi_json (1.15.0)
|
||||
pry (0.14.0)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
rake (13.0.3)
|
||||
ruby-jq (0.2.1)
|
||||
mini_portile2 (>= 2.2.0)
|
||||
multi_json
|
||||
ruby-progressbar (1.11.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
m
|
||||
minitest
|
||||
minitest-implicit-subject
|
||||
minitest-reporters
|
||||
pry
|
||||
ruby-jq
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
@@ -19,4 +19,4 @@ name: common
|
||||
sources:
|
||||
- https://github.com/truecharts/apps/tree/master/library/common
|
||||
type: library
|
||||
version: 4.0.1
|
||||
version: 4.1.0
|
||||
|
||||
@@ -7,26 +7,31 @@ Main entrypoint for the common library chart. It will render all underlying temp
|
||||
|
||||
{{- /* Build the templates */ -}}
|
||||
{{- include "common.pvc" . }}
|
||||
{{- print "---" | nindent 0 -}}
|
||||
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{- include "common.serviceAccount" . }}
|
||||
{{- print "---" | nindent 0 -}}
|
||||
{{- end -}}
|
||||
{{- if eq .Values.controllerType "deployment" }}
|
||||
|
||||
{{- if eq .Values.controller.type "deployment" }}
|
||||
{{- include "common.deployment" . | nindent 0 }}
|
||||
{{ else if eq .Values.controllerType "daemonset" }}
|
||||
{{ else if eq .Values.controller.type "daemonset" }}
|
||||
{{- include "common.daemonset" . | nindent 0 }}
|
||||
{{ else if eq .Values.controllerType "statefulset" }}
|
||||
{{ else if eq .Values.controller.type "statefulset" }}
|
||||
{{- include "common.statefulset" . | nindent 0 }}
|
||||
{{ else }}
|
||||
{{- fail (printf "Not a valid controller.type (%s)" .Values.controller.type) }}
|
||||
{{- end -}}
|
||||
|
||||
{{ include "common.classes.hpa" . | nindent 0 }}
|
||||
{{ include "common.services" . | nindent 0 }}
|
||||
|
||||
{{ include "common.service" . | nindent 0 }}
|
||||
|
||||
{{ include "common.ingress" . | nindent 0 }}
|
||||
|
||||
{{- if .Values.secret -}}
|
||||
{{- print "---" | nindent 0 -}}
|
||||
{{ include "common.secret" . | nindent 0 }}
|
||||
{{- end -}}
|
||||
{{ include "common.classes.mountPermissions" . | nindent 0 }}
|
||||
{{ include "common.classes.portal" . | nindent 0 }}
|
||||
|
||||
{{ include "common.class.mountPermissions" . | nindent 0 }}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,52 +1,35 @@
|
||||
{{/*
|
||||
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 DaemonSet objects that are created
|
||||
within the common library.
|
||||
*/}}
|
||||
{{- define "common.daemonset" -}}
|
||||
apiVersion: {{ include "common.capabilities.daemonset.apiVersion" . }}
|
||||
{{- define "common.daemonset" }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: {{ include "common.names.fullname" . }}
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
{{- with .Values.controllerLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- with .Values.controller.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controllerAnnotations }}
|
||||
{{- with .Values.controller.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- include "common.controller.pod" . | nindent 6 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,56 +1,53 @@
|
||||
{{/*
|
||||
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 Deployment objects that are created
|
||||
within the common library.
|
||||
*/}}
|
||||
{{- define "common.deployment" -}}
|
||||
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
|
||||
{{- define "common.deployment" }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "common.names.fullname" . }}
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
{{- with .Values.controllerLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- with .Values.controller.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controllerAnnotations }}
|
||||
{{- with .Values.controller.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
{{- with .Values.strategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }}
|
||||
replicas: {{ .Values.controller.replicas }}
|
||||
{{- $strategy := default "Recreate" .Values.controller.strategy }}
|
||||
{{- if and (ne $strategy "Recreate") (ne $strategy "RollingUpdate") }}
|
||||
{{- fail (printf "Not a valid strategy type for Deployment (%s)" $strategy) }}
|
||||
{{- end }}
|
||||
strategy:
|
||||
type: {{ $strategy }}
|
||||
{{- with .Values.controller.rollingUpdate }}
|
||||
{{- if and (eq $strategy "RollingUpdate") (or .surge .unavailable) }}
|
||||
rollingUpdate:
|
||||
{{- with .unavailable }}
|
||||
maxUnavailable: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .surge }}
|
||||
maxSurge: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- include "common.controller.pod" . | nindent 6 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,34 +1,48 @@
|
||||
{{/*
|
||||
Renders the Ingress objects required by the chart by returning a concatinated list
|
||||
of the main Ingress and any additionalIngresses.
|
||||
*/}}
|
||||
{{/* Renders the Ingress objects required by the chart */}}
|
||||
{{- define "common.ingress" -}}
|
||||
{{- /* Generate named ingresses as required */ -}}
|
||||
{{- range $name, $ingress := .Values.ingress }}
|
||||
{{- if $ingress.enabled -}}
|
||||
{{- print ("---\n") | nindent 0 -}}
|
||||
{{- $ingressValues := $ingress -}}
|
||||
{{- /* Generate named ingresses as required */ -}}
|
||||
{{- range $name, $ingress := .Values.ingress }}
|
||||
{{- if $ingress.enabled -}}
|
||||
{{- $ingressValues := $ingress -}}
|
||||
|
||||
{{/* set defaults */}}
|
||||
{{- if not $ingressValues.nameSuffix -}}
|
||||
{{- $_ := set $ingressValues "nameSuffix" $name -}}
|
||||
{{ end -}}
|
||||
{{/* set defaults */}}
|
||||
{{- if and (not $ingressValues.nameOverride) (ne $name (include "common.ingress.primary" $)) -}}
|
||||
{{- $_ := set $ingressValues "nameOverride" $name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
|
||||
{{- include "common.classes.ingress" $ }}
|
||||
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
|
||||
{{- include "common.classes.ingress" $ }}
|
||||
|
||||
|
||||
{{- range $index, $tlsValues := $ingressValues.tls }}
|
||||
{{- if .scaleCert }}
|
||||
{{- $nameSuffix := ( printf "%v-%v-%v" $ingressValues.nameSuffix "tls" $index ) -}}
|
||||
{{- $_ := set $tlsValues "nameSuffix" $nameSuffix -}}
|
||||
{{- $_ := set $ "ObjectValues" (dict "certHolder" $tlsValues) -}}
|
||||
{{- print ("---\n") | nindent 0 -}}
|
||||
{{- include "common.cert.secret" $ -}}
|
||||
{{- end }}
|
||||
{{- range $name, $tlsValues := $ingressValues.tls }}
|
||||
{{- if .scaleCert }}
|
||||
{{- $nameOverride := ( printf "%v-%v-%v" $ingressValues.nameOverride "tls" $name ) -}}
|
||||
{{- $_ := set $tlsValues "nameOverride" $nameOverride -}}
|
||||
{{- $_ := set $ "ObjectValues" (dict "certHolder" $tlsValues) -}}
|
||||
{{- include "common.cert.secret" $ -}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Return the name of the primary ingress object */}}
|
||||
{{- define "common.ingress.primary" -}}
|
||||
{{- $enabledIngresses := dict -}}
|
||||
{{- range $name, $ingress := .Values.ingress -}}
|
||||
{{- if $ingress.enabled -}}
|
||||
{{- $_ := set $enabledIngresses $name . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $result := "" -}}
|
||||
{{- range $name, $ingress := $enabledIngresses -}}
|
||||
{{- if and (hasKey $ingress "primary") $ingress.primary -}}
|
||||
{{- $result = $name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if not $result -}}
|
||||
{{- $result = keys $enabledIngresses | first -}}
|
||||
{{- end -}}
|
||||
{{- $result -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -32,11 +32,10 @@ of all the entries of the persistence key.
|
||||
|
||||
{{- if and $PVC.enabled (not (or $emptyDir $PVC.existingClaim)) -}}
|
||||
{{- $persistenceValues := $PVC -}}
|
||||
{{- if not $persistenceValues.nameSuffix -}}
|
||||
{{- $_ := set $persistenceValues "nameSuffix" $index -}}
|
||||
{{- if not $persistenceValues.nameOverride -}}
|
||||
{{- $_ := set $persistenceValues "nameOverride" $index -}}
|
||||
{{- end -}}
|
||||
{{- $_ := set $ "ObjectValues" (dict "persistence" $persistenceValues) -}}
|
||||
{{- print ("---") | nindent 0 -}}
|
||||
{{- include "common.classes.pvc" $ | nindent 0 -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{{/*
|
||||
The Secret object to be created.
|
||||
*/}}
|
||||
{{- define "common.secret" -}}
|
||||
{{- define "common.secret" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
|
||||
43
charts/library/common/templates/_service.tpl
Normal file
43
charts/library/common/templates/_service.tpl
Normal file
@@ -0,0 +1,43 @@
|
||||
{{/*
|
||||
Renders the Service objects required by the chart.
|
||||
*/}}
|
||||
{{- define "common.service" -}}
|
||||
{{- /* Generate named services as required */ -}}
|
||||
{{- range $name, $service := .Values.service }}
|
||||
{{- if $service.enabled -}}
|
||||
{{- $serviceValues := $service -}}
|
||||
|
||||
{{/* set the default nameOverride to the service name */}}
|
||||
{{- if and (not $serviceValues.nameOverride) (ne $name (include "common.service.primary" $)) -}}
|
||||
{{- $_ := set $serviceValues "nameOverride" $name -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}}
|
||||
{{- include "common.classes.service" $ }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Return the name of the primary service object
|
||||
*/}}
|
||||
{{- define "common.service.primary" -}}
|
||||
{{- $enabledServices := dict -}}
|
||||
{{- range $name, $service := .Values.service -}}
|
||||
{{- if $service.enabled -}}
|
||||
{{- $_ := set $enabledServices $name . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $result := "" -}}
|
||||
{{- range $name, $service := $enabledServices -}}
|
||||
{{- if and (hasKey $service "primary") $service.primary -}}
|
||||
{{- $result = $name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if not $result -}}
|
||||
{{- $result = keys $enabledServices | first -}}
|
||||
{{- end -}}
|
||||
{{- $result -}}
|
||||
{{- end -}}
|
||||
@@ -1,7 +1,8 @@
|
||||
{{/*
|
||||
The ServiceAccount object to be created.
|
||||
*/}}
|
||||
{{- define "common.serviceAccount" -}}
|
||||
{{- define "common.serviceAccount" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{{/*
|
||||
Renders the Service objects required by the chart by returning a concatinated list
|
||||
of the main Service and any additionalservice.
|
||||
*/}}
|
||||
{{- define "common.services" -}}
|
||||
{{- if .Values.services -}}
|
||||
{{- range $name, $service := .Values.services }}
|
||||
{{- if $service.enabled -}}
|
||||
{{- print ("---\n") | nindent 0 -}}
|
||||
{{- $serviceValues := $service -}}
|
||||
|
||||
{{- if $serviceValues.nameSuffix -}}
|
||||
{{- $_ := set $serviceValues "nameSuffix" $name -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}}
|
||||
{{- include "common.classes.service" $ -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -20,52 +20,60 @@ 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.
|
||||
*/}}
|
||||
{{- define "common.statefulset" -}}
|
||||
apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }}
|
||||
{{- define "common.statefulset" }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ include "common.names.fullname" . }}
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
{{- with .Values.controllerLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controllerAnnotations }}
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
{{- with .Values.controller.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.controller.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
{{- with .Values.strategy }}
|
||||
updateStrategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }}
|
||||
replicas: {{ .Values.controller.replicas }}
|
||||
{{- $strategy := default "RollingUpdate" .Values.controller.strategy }}
|
||||
{{- if and (ne $strategy "OnDelete") (ne $strategy "RollingUpdate") }}
|
||||
{{- fail (printf "Not a valid strategy type for StatefulSet (%s)" $strategy) }}
|
||||
{{- end }}
|
||||
updateStrategy:
|
||||
type: {{ $strategy }}
|
||||
{{- if and (eq $strategy "RollingUpdate") .Values.controller.rollingUpdate.partition }}
|
||||
rollingUpdate:
|
||||
partition: {{ .Values.controller.rollingUpdate.partition }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 6 }}
|
||||
serviceName: {{ include "common.names.fullname" . }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
{{- include "common.labels.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- include "common.controller.pod" . | nindent 6 }}
|
||||
volumeClaimTemplates:
|
||||
{{- range $index, $vct := .Values.volumeClaimTemplates }}
|
||||
- metadata:
|
||||
name: {{ $vct.name }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ required (printf "accessMode is required for vCT %v" $vct.name) $vct.accessMode | quote }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ required (printf "size is required for PVC %v" $vct.name) $vct.size | quote }}
|
||||
{{- if $vct.storageClass }}
|
||||
storageClassName: {{ if (eq "-" $vct.storageClass) }}""{{- else }}{{ $vct.storageClass | quote }}{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $index, $vct := .Values.volumeClaimTemplates }}
|
||||
- metadata:
|
||||
name: {{ $vct.name }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ required (printf "accessMode is required for vCT %v" $vct.name) $vct.accessMode | quote }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ required (printf "size is required for PVC %v" $vct.name) $vct.size | quote }}
|
||||
{{- if $vct.storageClass }}
|
||||
storageClassName: {{ if (eq "-" $vct.storageClass) }}""{{- else }}{{ $vct.storageClass | quote }}{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -3,12 +3,10 @@ This template serves as a blueprint for horizontal pod autoscaler objects that a
|
||||
using the common library.
|
||||
*/}}
|
||||
{{- define "common.classes.hpa" -}}
|
||||
{{- if .Values.autoscaling }}
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
{{- print "---" | nindent 0 -}}
|
||||
{{- $hpaName := include "common.names.fullname" . -}}
|
||||
{{- $targetName := include "common.names.fullname" . -}}
|
||||
|
||||
{{- if .Values.autoscaling.enabled -}}
|
||||
{{- $hpaName := include "common.names.fullname" . -}}
|
||||
{{- $targetName := include "common.names.fullname" . }}
|
||||
---
|
||||
apiVersion: autoscaling/v2beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
@@ -18,27 +16,22 @@ metadata:
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
{{- if eq .Values.controllerType "statefulset" }}
|
||||
kind: StatefulSet
|
||||
{{- else }}
|
||||
kind: Deployment
|
||||
{{- end }}
|
||||
kind: {{ include "common.names.controllerType" . }}
|
||||
name: {{ .Values.autoscaling.target | default $targetName }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas | default 1 }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas | default 3 }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -3,23 +3,24 @@ This template serves as a blueprint for all Ingress objects that are created
|
||||
within the common library.
|
||||
*/}}
|
||||
{{- define "common.classes.ingress" -}}
|
||||
{{- $ingressName := include "common.names.fullname" . -}}
|
||||
{{- $values := index .Values.ingress (keys .Values.ingress | first) -}}
|
||||
{{- $ingressName := include "common.names.fullname" . -}}
|
||||
{{- $values := .Values.ingress -}}
|
||||
|
||||
{{- if hasKey . "ObjectValues" -}}
|
||||
{{- with .ObjectValues.ingress -}}
|
||||
{{- $values = . -}}
|
||||
{{- if hasKey . "ObjectValues" -}}
|
||||
{{- with .ObjectValues.ingress -}}
|
||||
{{- $values = . -}}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
|
||||
{{- $ingressName = printf "%v-%v" $ingressName $values.nameOverride -}}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- if hasKey $values "nameSuffix" -}}
|
||||
{{- $ingressName = printf "%v-%v" $ingressName $values.nameSuffix -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- $svc := index .Values.services (keys .Values.services | first) -}}
|
||||
{{- $svcName := $values.serviceName | default (include "common.names.fullname" .) -}}
|
||||
{{- $svcPort := $values.servicePort | default $svc.port.port -}}
|
||||
|
||||
{{- $primaryService := get .Values.service (include "common.service.primary" .) }}
|
||||
{{- $primaryPort := get $primaryService.ports (include "common.classes.service.ports.primary" (dict "values" $primaryService)) -}}
|
||||
{{- $name := include "common.names.name" . -}}
|
||||
{{- $isStable := include "common.capabilities.ingress.isStable" . }}
|
||||
---
|
||||
apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
@@ -31,60 +32,49 @@ metadata:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
|
||||
{{- if $values.ingressClassName }}
|
||||
{{- if and $isStable $values.ingressClassName }}
|
||||
ingressClassName: {{ $values.ingressClassName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $values.tls }}
|
||||
tls:
|
||||
{{- range $index, $tlsValues := $values.tls }}
|
||||
- hosts:
|
||||
{{- range $tlsValues.hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- range $tlsValues.hostsTpl }}
|
||||
- {{ tpl . $ | quote }}
|
||||
{{- end }}
|
||||
{{- if or $tlsValues.secretNameTpl $tlsValues.secretName $tlsValues.scaleCert }}
|
||||
{{- if $tlsValues.scaleCert }}
|
||||
secretName: {{ ( printf "%v-%v-%v-%v-%v" $ingressName "tls" $index "ixcert" $tlsValues.scaleCert ) }}
|
||||
{{- else if $tlsValues.secretNameTpl }}
|
||||
secretName: {{ tpl $tlsValues.secretNameTpl $ | quote}}
|
||||
{{- else }}
|
||||
secretName: {{ $tlsValues.secretName }}
|
||||
{{- end }}
|
||||
{{- else if .secretName }}
|
||||
secretName: {{ tpl .secretName $ | quote}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range $values.hosts }}
|
||||
{{- if .hostTpl }}
|
||||
- host: {{ tpl .hostTpl $ | quote }}
|
||||
{{- else }}
|
||||
- host: {{ .host | quote }}
|
||||
{{- end }}
|
||||
- host: {{ tpl .host $ | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
{{- if .pathTpl }}
|
||||
- path: {{ tpl .pathTpl $ | quote }}
|
||||
{{- else }}
|
||||
- path: {{ .path | quote }}
|
||||
{{- $service := $name -}}
|
||||
{{- $port := $primaryPort.port -}}
|
||||
{{- if .service -}}
|
||||
{{- $service = default $name .service.name -}}
|
||||
{{- $port = default $primaryPort.port .service.port -}}
|
||||
{{- end }}
|
||||
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
|
||||
- path: {{ tpl .path $ | quote }}
|
||||
{{- if $isStable }}
|
||||
pathType: {{ default "Prefix" .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if eq (include "common.capabilities.ingress.apiVersion" $) "networking.k8s.io/v1" }}
|
||||
{{- if $isStable }}
|
||||
service:
|
||||
name: {{ .serviceName | default $svcName }}
|
||||
name: {{ $service }}
|
||||
port:
|
||||
number: {{ .servicePort | default $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ .serviceName | default $svcName }}
|
||||
servicePort: {{ .servicePort | default $svcPort }}
|
||||
{{- end }}
|
||||
number: {{ $port }}
|
||||
{{- else }}
|
||||
serviceName: {{ $service }}
|
||||
servicePort: {{ $port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -2,41 +2,37 @@
|
||||
This template serves as the blueprint for the mountPermissions job that is run
|
||||
before chart installation.
|
||||
*/}}
|
||||
{{- define "common.classes.mountPermissions" -}}
|
||||
{{- if .Values.hostPathMounts -}}
|
||||
|
||||
{{- $jobName := include "common.names.fullname" . -}}
|
||||
{{- $values := .Values -}}
|
||||
{{- $user := 568 -}}
|
||||
{{- $group := 568 -}}
|
||||
{{- print "---" | nindent 0 -}}
|
||||
|
||||
{{- if $values.podSecurityContext }}
|
||||
{{- if $values.podSecurityContext.runAsUser }}
|
||||
{{- $user = $values.podSecurityContext.runAsUser -}}
|
||||
{{- end -}}
|
||||
{{- if $values.podSecurityContext.fsGroup -}}
|
||||
{{- $group = $values.podSecurityContext.fsGroup -}}
|
||||
{{- end -}}
|
||||
{{- else if $values.env }}
|
||||
{{- if $values.env.PUID }}
|
||||
{{- $user = $values.env.PUID -}}
|
||||
{{- end -}}
|
||||
{{- if $values.env.PGID }}
|
||||
{{- $group = $values.env.PGID -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "common.class.mountPermissions" -}}
|
||||
{{- if .Values.hostPathMounts -}}
|
||||
{{- $jobName := include "common.names.fullname" . -}}
|
||||
{{- $user := 568 -}}
|
||||
{{- if .Values.env -}}
|
||||
{{- $user = dig "PUID" $user .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 -}}
|
||||
{{- if and $mount.enabled $mount.setPermissions -}}
|
||||
{{- $name = default $name $mount.name -}}
|
||||
{{- $_ := set $hostPathMounts $name $mount -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ $jobName }}-autopermissions
|
||||
name: {{ printf "%s-auto-permissions" $jobName }}
|
||||
labels:
|
||||
{{- include "common.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-10"
|
||||
"helm.sh/hook-delete-policy": hook-succeeded,hook-failed,before-hook-creation
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-10"
|
||||
"helm.sh/hook-delete-policy": hook-succeeded,hook-failed,before-hook-creation
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
@@ -44,48 +40,31 @@ spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: set-mount-permissions
|
||||
image: "alpine:3.3"
|
||||
image: alpine:3.3
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- | {{ range $index, $hpm := .Values.hostPathMounts}}{{ if and $hpm.enabled $hpm.setPermissions}}
|
||||
chown -R {{ print $user }}:{{ print $group }} {{ print $hpm.mountPath }}{{ end }}{{ end }}
|
||||
#args:
|
||||
#
|
||||
#securityContext:
|
||||
#
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
{{- range $_, $hpm := $hostPathMounts }}
|
||||
chown -R {{ printf "%d:%d %s" (int $user) (int $group) $hpm.mountPath }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
{{ range $name, $hpmm := .Values.hostPathMounts }}
|
||||
{{- if $hpmm.enabled -}}
|
||||
{{- if $hpmm.setPermissions -}}
|
||||
{{ if $hpmm.name }}
|
||||
{{ $name = $hpmm.name }}
|
||||
{{ end }}
|
||||
- name: hostpathmounts-{{ $name }}
|
||||
mountPath: {{ $hpmm.mountPath }}
|
||||
{{ if $hpmm.subPath }}
|
||||
subPath: {{ $hpmm.subPath }}
|
||||
{{ end }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
{{- range $name, $hpm := $hostPathMounts }}
|
||||
- name: {{ printf "hostpathmounts-%s" $name }}
|
||||
mountPath: {{ $hpm.mountPath }}
|
||||
{{- if $hpm.subPath }}
|
||||
subPath: {{ $hpm.subPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- range $name, $hpm := .Values.hostPathMounts -}}
|
||||
{{ if $hpm.enabled }}
|
||||
{{ if $hpm.setPermissions }}
|
||||
{{ if $hpm.name }}
|
||||
{{ $name = $hpm.name }}
|
||||
{{ end }}
|
||||
- name: hostpathmounts-{{ $name }}
|
||||
{{ if $hpm.emptyDir }}
|
||||
emptyDir: {}
|
||||
{{- else -}}
|
||||
hostPath:
|
||||
path: {{ required "hostPath not set" $hpm.hostPath }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $name, $hpm := $hostPathMounts }}
|
||||
- name: {{ printf "hostpathmounts-%s" $name }}
|
||||
{{- if $hpm.emptyDir }}
|
||||
emptyDir: {}
|
||||
{{- else }}
|
||||
hostPath:
|
||||
path: {{ required "hostPath not set" $hpm.hostPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -28,13 +28,12 @@ within the common library.
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
{{- $pvcName := include "common.names.fullname" . -}}
|
||||
{{- if hasKey $values "nameOverride" -}}
|
||||
{{- $pvcName = $values.nameOverride -}}
|
||||
{{- else if hasKey $values "nameSuffix" -}}
|
||||
{{- if not (eq $values.nameSuffix "-") -}}
|
||||
{{- $pvcName = printf "%v-%v" $pvcName $values.nameSuffix -}}
|
||||
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
|
||||
{{- if not (eq $values.nameOverride "-") -}}
|
||||
{{- $pvcName = printf "%v-%v" $pvcName $values.nameOverride -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
---
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
|
||||
@@ -21,17 +21,20 @@ This template serves as a blueprint for all Service objects that are created
|
||||
within the common library.
|
||||
*/}}
|
||||
{{- define "common.classes.service" -}}
|
||||
{{- $values := index .Values.services (keys .Values.services | first) -}}
|
||||
{{- $values := .Values.service -}}
|
||||
{{- if hasKey . "ObjectValues" -}}
|
||||
{{- with .ObjectValues.service -}}
|
||||
{{- $values = . -}}
|
||||
{{- end -}}
|
||||
{{ end -}}
|
||||
|
||||
{{- $serviceName := include "common.names.fullname" . -}}
|
||||
{{- if hasKey $values "nameSuffix" -}}
|
||||
{{- $serviceName = printf "%v-%v" $serviceName $values.nameSuffix -}}
|
||||
{{- if and (hasKey $values "nameOverride") $values.nameOverride -}}
|
||||
{{- $serviceName = printf "%v-%v" $serviceName $values.nameOverride -}}
|
||||
{{ end -}}
|
||||
{{- $svcType := $values.type | default "" -}}
|
||||
{{- $primaryPort := get $values.ports (include "common.classes.service.ports.primary" (dict "values" $values)) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
@@ -42,7 +45,7 @@ metadata:
|
||||
{{ toYaml $values.labels | nindent 4 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
{{- if eq ( $values.port.protocol | default "" ) "HTTPS" }}
|
||||
{{- if eq ( $primaryPort.protocol | default "" ) "HTTPS" }}
|
||||
traefik.ingress.kubernetes.io/service.serversscheme: https
|
||||
{{- end }}
|
||||
{{- with $values.annotations }}
|
||||
@@ -83,7 +86,26 @@ spec:
|
||||
{{- if $values.publishNotReadyAddresses }}
|
||||
publishNotReadyAddresses: {{ $values.publishNotReadyAddresses }}
|
||||
{{- end }}
|
||||
{{- include "common.classes.service.ports" (dict "svcType" $svcType "values" $values ) | trim | nindent 2 }}
|
||||
ports:
|
||||
{{- range $name, $port := $values.ports }}
|
||||
{{- if $port.enabled }}
|
||||
- port: {{ $port.port }}
|
||||
targetPort: {{ $port.targetPort | default $name }}
|
||||
{{- if $port.protocol }}
|
||||
{{- if or ( eq $port.protocol "HTTP" ) ( eq $port.protocol "HTTPS" ) ( eq $port.protocol "TCP" ) }}
|
||||
protocol: TCP
|
||||
{{- else }}
|
||||
protocol: {{ $port.protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
name: {{ $name }}
|
||||
{{- if (and (eq $svcType "NodePort") (not (empty $port.nodePort))) }}
|
||||
nodePort: {{ $port.nodePort }}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "common.labels.selectorLabels" . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -17,33 +17,29 @@ This file is considered to be modified by the TrueCharts Project.
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Render all the ports and additionalPorts for a Service object.
|
||||
Return the name of the primary port for a given Service object.
|
||||
*/}}
|
||||
{{- define "common.classes.service.ports" -}}
|
||||
{{- $ports := list -}}
|
||||
{{- $values := .values -}}
|
||||
{{- $ports = mustAppend $ports $values.port -}}
|
||||
{{- range $_ := $values.additionalPorts -}}
|
||||
{{- $ports = mustAppend $ports . -}}
|
||||
{{- define "common.classes.service.ports.primary" -}}
|
||||
{{- $enabledPorts := dict -}}
|
||||
{{- range $name, $port := .values.ports -}}
|
||||
{{- if $port.enabled -}}
|
||||
{{- $_ := set $enabledPorts $name . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if eq 0 (len $enabledPorts) }}
|
||||
{{- fail (printf "No ports are enabled for service \"%s\"!" .serviceName) }}
|
||||
{{- end }}
|
||||
{{- if $ports -}}
|
||||
ports:
|
||||
{{- range $_ := $ports }}
|
||||
- port: {{ .port }}
|
||||
targetPort: {{ .targetPort | default .name | default "http" }}
|
||||
{{- if .protocol }}
|
||||
{{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) ( eq .protocol "TCP" ) }}
|
||||
protocol: TCP
|
||||
{{- else }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
name: {{ .name | default "http" }}
|
||||
{{- if (and (eq $.svcType "NodePort") (not (empty .nodePort))) }}
|
||||
nodePort: {{ .nodePort }}
|
||||
{{ end }}
|
||||
|
||||
{{- $result := "" -}}
|
||||
{{- range $name, $port := $enabledPorts -}}
|
||||
{{- if and (hasKey $port "primary") $port.primary -}}
|
||||
{{- $result = $name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if not $result -}}
|
||||
{{- $result = keys $enabledPorts | first -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
{{- $result -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
{{ end -}}
|
||||
|
||||
{{- if eq (include "common.cert.available" $ ) "true" -}}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
|
||||
@@ -1,110 +1,19 @@
|
||||
{{/*
|
||||
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 appropriate apiVersion for DaemonSet objects.
|
||||
*/}}
|
||||
{{- define "common.capabilities.daemonset.apiVersion" -}}
|
||||
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- end -}}
|
||||
{{/* Allow KubeVersion to be overridden. */}}
|
||||
{{- define "common.capabilities.ingress.kubeVersion" -}}
|
||||
{{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Waiting on https://github.com/helm/helm/pull/8608
|
||||
{{- define "common.capabilities.daemonset.apiVersion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "apps/v1/DaemonSet" -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- else -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Return the appropriate apiVersion for Deployment objects.
|
||||
*/}}
|
||||
{{- define "common.capabilities.deployment.apiVersion" -}}
|
||||
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Waiting on https://github.com/helm/helm/pull/8608
|
||||
{{- define "common.capabilities.deployment.apiVersion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "apps/v1/Deployment" -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- else -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Return the appropriate apiVersion for StatefulSet objects.
|
||||
*/}}
|
||||
{{- define "common.capabilities.statefulset.apiVersion" -}}
|
||||
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "apps/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Waiting on https://github.com/helm/helm/pull/8608
|
||||
{{- define "common.capabilities.statefulset.apiVersion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "apps/v1/StatefulSet" -}}
|
||||
{{- print "apps/v1" -}}
|
||||
{{- else -}}
|
||||
{{- print "apps/v1beta1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Return the appropriate apiVersion for Ingress objects.
|
||||
*/}}
|
||||
|
||||
{{/* Return the appropriate apiVersion for Ingress objects */}}
|
||||
{{- define "common.capabilities.ingress.apiVersion" -}}
|
||||
{{- if semverCompare "<1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- else if semverCompare "<1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
{{- print "networking.k8s.io/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "networking.k8s.io/v1" -}}
|
||||
{{- end }}
|
||||
{{- print "networking.k8s.io/v1" -}}
|
||||
{{- if semverCompare "<1.19" (include "common.capabilities.ingress.kubeVersion" .) -}}
|
||||
{{- print "beta1" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Waiting on https://github.com/helm/helm/pull/8608
|
||||
{{- define "common.capabilities.ingress.apiVersion" -}}
|
||||
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress" -}}
|
||||
{{- print "networking.k8s.io/v1" -}}
|
||||
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress" -}}
|
||||
{{- print "networking.k8s.io/v1beta1" -}}
|
||||
{{- else -}}
|
||||
{{- print "extensions/v1beta1" -}}
|
||||
{{- end }}
|
||||
{{/* Check Ingress stability */}}
|
||||
{{- define "common.capabilities.ingress.isStable" -}}
|
||||
{{- if eq (include "common.capabilities.ingress.apiVersion" .) "networking.k8s.io/v1" -}}
|
||||
{{- true -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
*/}}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Through error when upgrading using empty passwords values that must not be empty.
|
||||
|
||||
Usage:
|
||||
{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}}
|
||||
{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}}
|
||||
{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }}
|
||||
|
||||
Required password params:
|
||||
- validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error.
|
||||
- context - Context - Required. Parent context.
|
||||
*/}}
|
||||
{{- define "common.errors.upgrade.passwords.empty" -}}
|
||||
{{- $validationErrors := join "" .validationErrors -}}
|
||||
{{- if and $validationErrors .context.Release.IsUpgrade -}}
|
||||
{{- $errorString := "\nPASSWORDS ERROR: you must provide your current passwords when upgrade the release%s" -}}
|
||||
{{- printf $errorString $validationErrors | fail -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -1,65 +0,0 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Return the proper image name
|
||||
{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }}
|
||||
*/}}
|
||||
{{- define "common.images.image" -}}
|
||||
{{- $registryName := .imageRoot.registry -}}
|
||||
{{- $repositoryName := .imageRoot.repository -}}
|
||||
{{- $tag := .imageRoot.tag | toString -}}
|
||||
{{- if .global }}
|
||||
{{- if .global.imageRegistry }}
|
||||
{{- $registryName = .global.imageRegistry -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if $registryName }}
|
||||
{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repositoryName $tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the proper Docker Image Registry Secret Names
|
||||
{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }}
|
||||
*/}}
|
||||
{{- define "common.images.pullSecrets" -}}
|
||||
{{- $pullSecrets := list }}
|
||||
|
||||
{{- if .global }}
|
||||
{{- range .global.imagePullSecrets -}}
|
||||
{{- $pullSecrets = append $pullSecrets . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range .images -}}
|
||||
{{- range .pullSecrets -}}
|
||||
{{- $pullSecrets = append $pullSecrets . -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if (not (empty $pullSecrets)) }}
|
||||
imagePullSecrets:
|
||||
{{- range $pullSecrets }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
@@ -1,37 +1,15 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Common labels shared across objects.
|
||||
*/}}
|
||||
{{/* Common labels shared across objects */}}
|
||||
{{- define "common.labels" -}}
|
||||
helm.sh/chart: {{ include "common.names.chart" . }}
|
||||
{{ include "common.labels.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Selector labels shared across objects.
|
||||
*/}}
|
||||
{{/* Selector labels shared across objects */}}
|
||||
{{- define "common.labels.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "common.names.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
@@ -16,13 +16,10 @@ limitations under the License.
|
||||
This file is considered to be modified by the TrueCharts Project.
|
||||
*/}}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{/* Expand the name of the chart */}}
|
||||
{{- define "common.names.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- default .Chart.Name (default .Values.nameOverride .Values.global.nameOverride) | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
@@ -30,32 +27,42 @@ We truncate at 63 chars because some Kubernetes name fields are limited to this
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "common.names.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $name := include "common.names.name" . -}}
|
||||
{{- if or .Values.fullnameOverride .Values.global.fullnameOverride -}}
|
||||
{{- $name = default .Values.fullnameOverride .Values.global.fullnameOverride -}}
|
||||
{{- else -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- $name := .Release.Name -}}
|
||||
{{- else -}}
|
||||
{{- $name := printf "%s-%s" .Release.Name $name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- trunc 63 $name | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{/* Create chart name and version as used by the chart label */}}
|
||||
{{- define "common.names.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the ServiceAccount to use.
|
||||
*/}}
|
||||
{{/* Create the name of the ServiceAccount to use */}}
|
||||
{{- define "common.names.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "common.names.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{- default (include "common.names.fullname" .) .Values.serviceAccount.name -}}
|
||||
{{- else -}}
|
||||
{{- default "default" .Values.serviceAccount.name -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Return the properly cased version of the controller type */}}
|
||||
{{- define "common.names.controllerType" -}}
|
||||
{{- if eq .Values.controller.type "deployment" -}}
|
||||
{{- print "Deployment" -}}
|
||||
{{- else if eq .Values.controller.type "daemonset" -}}
|
||||
{{- print "DaemonSet" -}}
|
||||
{{- else if eq .Values.controller.type "statefulset" -}}
|
||||
{{- print "StatefulSet" -}}
|
||||
{{- else -}}
|
||||
{{- fail (printf "Not a valid controller.type (%s)" .Values.controller.type) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Print instructions to get a secret value.
|
||||
Usage:
|
||||
{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }}
|
||||
*/}}
|
||||
{{- define "common.utils.secret.getvalue" -}}
|
||||
{{- $varname := include "common.utils.fieldToEnvVar" . -}}
|
||||
export {{ $varname }}=$(kubectl get secret --namespace {{ .context.Release.Namespace | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 --decode)
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Build env var name given a field
|
||||
Usage:
|
||||
{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }}
|
||||
*/}}
|
||||
{{- define "common.utils.fieldToEnvVar" -}}
|
||||
{{- $fieldNameSplit := splitList "-" .field -}}
|
||||
{{- $upperCaseFieldNameSplit := list -}}
|
||||
|
||||
{{- range $fieldNameSplit -}}
|
||||
{{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{ join "_" $upperCaseFieldNameSplit }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Gets a value from .Values given
|
||||
Usage:
|
||||
{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }}
|
||||
*/}}
|
||||
{{- define "common.utils.getValueFromKey" -}}
|
||||
{{- $splitKey := splitList "." .key -}}
|
||||
{{- $value := "" -}}
|
||||
{{- $latestObj := $.context.Values -}}
|
||||
{{- range $splitKey -}}
|
||||
{{- if not $latestObj -}}
|
||||
{{- printf "please review the entire path of '%s' exists in values" $.key | fail -}}
|
||||
{{- end -}}
|
||||
{{- $value = ( index $latestObj . ) -}}
|
||||
{{- $latestObj = $value -}}
|
||||
{{- end -}}
|
||||
{{- printf "%v" (default "" $value) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Returns first .Values key with a defined value or first of the list if all non-defined
|
||||
Usage:
|
||||
{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }}
|
||||
*/}}
|
||||
{{- define "common.utils.getKeyFromList" -}}
|
||||
{{- $key := first .keys -}}
|
||||
{{- $reverseKeys := reverse .keys }}
|
||||
{{- range $reverseKeys }}
|
||||
{{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }}
|
||||
{{- if $value -}}
|
||||
{{- $key = . }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s" $key -}}
|
||||
{{- end -}}
|
||||
@@ -1,29 +1,9 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/*
|
||||
Merge the local chart values and the common chart defaults.
|
||||
*/}}
|
||||
{{/* Merge the local chart values and the common chart defaults */}}
|
||||
{{- define "common.values.setup" -}}
|
||||
{{- if .Values.common -}}
|
||||
{{- $defaultValues := deepCopy .Values.common -}}
|
||||
{{- $userValues := deepCopy (omit .Values "common") -}}
|
||||
{{- $mergedValues := mustMergeOverwrite $defaultValues $userValues -}}
|
||||
{{- $_ := set . "Values" (deepCopy $mergedValues) -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,44 +1,23 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
|
||||
{{- /*
|
||||
The main container included in the controller.
|
||||
*/ -}}
|
||||
{{- /* The main container included in the controller */ -}}
|
||||
{{- define "common.controller.mainContainer" -}}
|
||||
- name: {{ include "common.names.fullname" . }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
image: {{ printf "%s:%s" .Values.image.repository (default .Chart.AppVersion .Values.image.tag) | quote }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
{{- with .Values.command }}
|
||||
{{- if kindIs "string" . }}
|
||||
command: {{ . }}
|
||||
{{- else }}
|
||||
command:
|
||||
{{ toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if kindIs "string" . }}
|
||||
- {{ . }}
|
||||
{{- else }}
|
||||
{{ toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.args }}
|
||||
{{- if kindIs "string" . }}
|
||||
args: {{ . }}
|
||||
{{- else }}
|
||||
args:
|
||||
{{ toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if kindIs "string" . }}
|
||||
- {{ . }}
|
||||
{{- else }}
|
||||
{{ toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.securityContext }}
|
||||
securityContext:
|
||||
@@ -46,53 +25,68 @@ The main container included in the controller.
|
||||
{{- end }}
|
||||
{{- with .Values.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
|
||||
env:
|
||||
{{- if .Values.timezone }}
|
||||
- name: TZ
|
||||
value: {{ .Values.timezone | quote }}
|
||||
{{- end }}
|
||||
{{- if or .Values.env .Values.envTpl .Values.envValueFrom .Values.envVariable .Values.envList }}
|
||||
{{- range $key, $value := .Values.envTpl }}
|
||||
- name: {{ $key }}
|
||||
value: {{ tpl $value $ | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $value := .Values.envValueFrom }}
|
||||
- name: {{ $key }}
|
||||
valueFrom:
|
||||
{{- $value | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- range $envList := .Values.envList }}
|
||||
{{- if and $envList.name $envList.value }}
|
||||
- name: {{ $envList.name }}
|
||||
value: {{ $envList.value | quote }}
|
||||
{{- else }}
|
||||
{{- if and $envList.name $envList.value }}
|
||||
- name: {{ $envList.name }}
|
||||
value: {{ $envList.value | quote }}
|
||||
{{- else }}
|
||||
{{- fail "Please specify name/value for environment variable" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
{{- range $key, $value := .Values.env }}
|
||||
- name: {{ $key }}
|
||||
value: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $value := .Values.envTpl }}
|
||||
- name: {{ $key }}
|
||||
value: {{ tpl $value $ | quote }}
|
||||
{{- end }}
|
||||
{{- range $key, $value := .Values.envValueFrom }}
|
||||
- name: {{ $key }}
|
||||
valueFrom:
|
||||
{{- $value | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .Values.env }}
|
||||
{{- range $k, $v := . }}
|
||||
{{- $name := $k }}
|
||||
{{- $value := $v }}
|
||||
{{- if kindIs "int" $name }}
|
||||
{{- $name = required "environment variables as a list of maps require a name field" $value.name }}
|
||||
{{- end }}
|
||||
- name: {{ quote $name }}
|
||||
{{- if kindIs "map" $value -}}
|
||||
{{- if hasKey $value "value" }}
|
||||
{{- $value = $value.value -}}
|
||||
{{- else if hasKey $value "valueFrom" }}
|
||||
{{- toYaml $value | nindent 6 }}
|
||||
{{- else }}
|
||||
{{- dict "valueFrom" $value | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "map" $value) }}
|
||||
{{- if kindIs "string" $value }}
|
||||
{{- $value = tpl $value $ }}
|
||||
{{- end }}
|
||||
value: {{ quote $value }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if or .Values.envFrom .Values.secret }}
|
||||
envFrom:
|
||||
{{- with .Values.envFrom }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.secret }}
|
||||
- secretRef:
|
||||
name: {{ include "common.names.fullname" . }}
|
||||
{{- end }}
|
||||
{{- with .Values.envFrom }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if .Values.secret }}
|
||||
- secretRef:
|
||||
name: {{ include "common.names.fullname" . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- include "common.controller.ports" . | trim | nindent 2 }}
|
||||
{{- with (include "common.controller.volumeMounts" . | trim) }}
|
||||
volumeMounts:
|
||||
{{- . | nindent 2 }}
|
||||
{{ nindent 4 . }}
|
||||
{{- end }}
|
||||
{{- include "common.controller.probes" . | nindent 2 }}
|
||||
|
||||
{{- include "common.controller.probes" . | trim | nindent 2 }}
|
||||
{{/*
|
||||
Merges the TrueNAS SCALE generated GPU info with the .Values.resources dict
|
||||
*/}}
|
||||
|
||||
@@ -2,66 +2,66 @@
|
||||
The pod definition included in the controller.
|
||||
*/ -}}
|
||||
{{- define "common.controller.pod" -}}
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "common.names.serviceAccountName" . }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.schedulerName }}
|
||||
schedulerName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostNetwork }}
|
||||
hostNetwork: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostname }}
|
||||
hostname: {{ . }}
|
||||
{{- end }}
|
||||
{{- if .Values.dnsPolicy }}
|
||||
dnsPolicy: {{ .Values.dnsPolicy }}
|
||||
{{- else if .Values.hostNetwork }}
|
||||
dnsPolicy: "ClusterFirstWithHostNet"
|
||||
{{- else }}
|
||||
dnsPolicy: ClusterFirst
|
||||
{{- end }}
|
||||
{{- with .Values.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
enableServiceLinks: {{ .Values.enableServiceLinks }}
|
||||
{{- with .Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- include "common.controller.mainContainer" . | nindent 0 }}
|
||||
{{- with .Values.additionalContainers }}
|
||||
{{- tpl (toYaml .) $ | nindent 0 }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with (include "common.controller.volumes" . | trim) }}
|
||||
serviceAccountName: {{ include "common.names.serviceAccountName" . }}
|
||||
{{- with .Values.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.priorityClassName }}
|
||||
priorityClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.schedulerName }}
|
||||
schedulerName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostNetwork }}
|
||||
hostNetwork: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostname }}
|
||||
hostname: {{ . }}
|
||||
{{- end }}
|
||||
{{- if .Values.dnsPolicy }}
|
||||
dnsPolicy: {{ .Values.dnsPolicy }}
|
||||
{{- else if .Values.hostNetwork }}
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
{{- else }}
|
||||
dnsPolicy: ClusterFirst
|
||||
{{- end }}
|
||||
{{- with .Values.dnsConfig }}
|
||||
dnsConfig:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
enableServiceLinks: {{ .Values.enableServiceLinks }}
|
||||
{{- with .Values.initContainers }}
|
||||
initContainers:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
{{- include "common.controller.mainContainer" . | nindent 2 }}
|
||||
{{- with .Values.additionalContainers }}
|
||||
{{- tpl (toYaml .) $ | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with (include "common.controller.volumes" . | trim) }}
|
||||
volumes:
|
||||
{{- . | nindent 0 }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostAliases }}
|
||||
{{- nindent 2 . }}
|
||||
{{- end }}
|
||||
{{- with .Values.hostAliases }}
|
||||
hostAliases:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
@@ -2,41 +2,36 @@
|
||||
Ports included by the controller.
|
||||
*/}}
|
||||
{{- define "common.controller.ports" -}}
|
||||
{{- $ports := list -}}
|
||||
{{/* append the ports for each service */}}
|
||||
{{- if $.Values.services -}}
|
||||
{{- range $name, $_ := $.Values.services }}
|
||||
{{- if .enabled -}}
|
||||
{{- if kindIs "string" $name -}}
|
||||
{{- $_ := set .port "name" (default .port.name | default $name) -}}
|
||||
{{- else -}}
|
||||
{{- $_ := set .port "name" (required "Missing port.name" .port.name) -}}
|
||||
{{- end -}}
|
||||
{{- $ports = mustAppend $ports .port -}}
|
||||
{{- range $_ := .additionalPorts -}}
|
||||
{{/* append the additonalPorts for each additional service */}}
|
||||
{{- $ports = mustAppend $ports . -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $ports := list -}}
|
||||
{{- range .Values.service -}}
|
||||
{{- if .enabled -}}
|
||||
{{- range $name, $port := .ports -}}
|
||||
{{- $_ := set $port "name" $name -}}
|
||||
{{- $ports = mustAppend $ports $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/* export/render the list of ports */}}
|
||||
{{- if $ports -}}
|
||||
ports:
|
||||
{{- range $_ := $ports }}
|
||||
{{- $protocol := "" -}}
|
||||
{{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) }}
|
||||
{{- $protocol = "TCP" -}}
|
||||
{{- else }}
|
||||
{{- $protocol = .protocol | default "TCP" -}}
|
||||
{{- end }}
|
||||
- name: {{ required "The port's 'name' is not defined" .name }}
|
||||
{{- if .enabled }}
|
||||
- name: {{ .name }}
|
||||
{{- if and .targetPort (kindIs "string" .targetPort) }}
|
||||
{{- fail (printf "Our charts do not support named ports for targetPort. (port name %s, targetPort %s)" .name .targetPort) }}
|
||||
{{- end }}
|
||||
containerPort: {{ .targetPort | default .port }}
|
||||
protocol: {{ $protocol | default "TCP" }}
|
||||
{{- if .protocol }}
|
||||
{{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) ( eq .protocol "TCP" ) }}
|
||||
protocol: TCP
|
||||
{{- else }}
|
||||
protocol: {{ .protocol }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -21,8 +21,12 @@ This file is considered to be modified by the TrueCharts Project.
|
||||
Probes selection logic.
|
||||
*/}}
|
||||
{{- define "common.controller.probes" -}}
|
||||
{{- $svc := index .Values.services (keys .Values.services | first) -}}
|
||||
{{- $svcPort := $svc.port.name -}}
|
||||
{{- $primaryService := get .Values.service (include "common.service.primary" .) -}}
|
||||
{{- $primaryPort := "" -}}
|
||||
{{- if $primaryService -}}
|
||||
{{- $primaryPort = get $primaryService.ports (include "common.classes.service.ports.primary" (dict "serviceName" (include "common.service.primary" .) "values" $primaryService)) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- range $probeName, $probe := .Values.probes }}
|
||||
{{- if $probe.enabled -}}
|
||||
{{- "" | nindent 0 }}
|
||||
@@ -30,12 +34,14 @@ Probes selection logic.
|
||||
{{- if $probe.custom -}}
|
||||
{{- $probe.spec | toYaml | nindent 2 }}
|
||||
{{- else }}
|
||||
{{- "tcpSocket:" | nindent 2 }}
|
||||
{{- printf "port: %v" $svcPort | nindent 4 }}
|
||||
{{- printf "initialDelaySeconds: %v" $probe.spec.initialDelaySeconds | nindent 2 }}
|
||||
{{- printf "failureThreshold: %v" $probe.spec.failureThreshold | nindent 2 }}
|
||||
{{- printf "timeoutSeconds: %v" $probe.spec.timeoutSeconds | nindent 2 }}
|
||||
{{- printf "periodSeconds: %v" $probe.spec.periodSeconds | nindent 2 }}
|
||||
{{- if and $primaryService $primaryPort -}}
|
||||
{{- "tcpSocket:" | nindent 2 }}
|
||||
{{- printf "port: %v" $primaryPort.port | nindent 4 }}
|
||||
{{- printf "initialDelaySeconds: %v" $probe.spec.initialDelaySeconds | nindent 2 }}
|
||||
{{- printf "failureThreshold: %v" $probe.spec.failureThreshold | nindent 2 }}
|
||||
{{- printf "timeoutSeconds: %v" $probe.spec.timeoutSeconds | nindent 2 }}
|
||||
{{- printf "periodSeconds: %v" $probe.spec.periodSeconds | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
{{/*
|
||||
Volumes included by the controller.
|
||||
*/}}
|
||||
{{/* Volumes included by the controller */}}
|
||||
{{- define "common.controller.volumeMounts" -}}
|
||||
|
||||
{{- range $index, $PVC := .Values.persistence }}
|
||||
{{- if $PVC.enabled }}
|
||||
{{- range $index, $PVC := .Values.persistence }}
|
||||
{{- if $PVC.enabled }}
|
||||
- mountPath: {{ $PVC.mountPath | default (printf "/%v" $index) }}
|
||||
name: {{ $index }}
|
||||
{{- if $PVC.subPath }}
|
||||
{{- if $PVC.subPath }}
|
||||
subPath: {{ $PVC.subPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Creates mountpoints to mount devices directly to the same path inside the container
|
||||
@@ -28,38 +25,32 @@ Creates mountpoints to mount devices directly to the same path inside the contai
|
||||
{{ end }}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
{{- if .Values.additionalVolumeMounts }}
|
||||
{{- toYaml .Values.additionalVolumeMounts | nindent 0 }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Creates mountpoints to mount hostPaths directly to the container
|
||||
*/}}
|
||||
{{ range $name, $hpm := .Values.hostPathMounts }}
|
||||
{{- if $hpm.enabled -}}
|
||||
{{ if $hpm.name }}
|
||||
{{ $name = $hpm.name }}
|
||||
{{ end }}
|
||||
- name: hostpathmounts-{{ $name }}
|
||||
mountPath: {{ $hpm.mountPath }}
|
||||
{{ if $hpm.subPath }}
|
||||
subPath: {{ $hpm.subPath }}
|
||||
{{ end }}
|
||||
{{ if $hpm.readOnly }}
|
||||
readOnly: {{ $hpm.readOnly }}
|
||||
{{ end }}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{- if .Values.additionalVolumeMounts }}
|
||||
{{- toYaml .Values.additionalVolumeMounts | nindent 0 }}
|
||||
{{- end }}
|
||||
|
||||
{{- if eq .Values.controllerType "statefulset" }}
|
||||
{{- range $index, $vct := .Values.volumeClaimTemplates }}
|
||||
{{- if eq .Values.controller.type "statefulset" }}
|
||||
{{- range $index, $vct := .Values.volumeClaimTemplates }}
|
||||
- mountPath: {{ $vct.mountPath }}
|
||||
name: {{ $vct.name }}
|
||||
{{- if $vct.subPath }}
|
||||
{{- if $vct.subPath }}
|
||||
subPath: {{ $vct.subPath }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- 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 -}}
|
||||
|
||||
@@ -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.
|
||||
*/}}
|
||||
|
||||
|
||||
{{/*
|
||||
Volumes included by the controller.
|
||||
*/}}
|
||||
@@ -52,10 +33,8 @@ Volumes included by the controller.
|
||||
{{- /* Otherwise refer to the PVC name */}}
|
||||
{{- $pvcName := (include "common.names.fullname" $) -}}
|
||||
{{- if $persistence.nameOverride -}}
|
||||
{{- $pvcName = $persistence.nameOverride -}}
|
||||
{{- else if $persistence.nameSuffix -}}
|
||||
{{- if not (eq $persistence.nameSuffix "-") -}}
|
||||
{{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $persistence.nameSuffix) -}}
|
||||
{{- 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) -}}
|
||||
|
||||
346
charts/library/common/tests/container_test.go
Normal file
346
charts/library/common/tests/container_test.go
Normal file
@@ -0,0 +1,346 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
)
|
||||
|
||||
type ContainerTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *ContainerTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
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))
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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()
|
||||
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))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ContainerTestSuite) TestPorts() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedPortName string
|
||||
expectedPort int
|
||||
expectedProtocol string
|
||||
}{
|
||||
"Default": {values: nil, expectedPortName: "http", expectedPort: 0, expectedProtocol: "TCP"},
|
||||
"CustomName": {values: []string{"service.main.ports.http.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.http.protocol=HTTP"}, expectedPortName: "http", expectedPort: 0, expectedProtocol: "TCP"},
|
||||
"ProtocolHTTPS": {values: []string{"service.main.ports.http.protocol=HTTP"}, expectedPortName: "http", expectedPort: 0, expectedProtocol: "TCP"},
|
||||
"ProtocolUDP": {values: []string{"service.main.ports.http.protocol=UDP"}, expectedPortName: "http", 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())
|
||||
|
||||
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 := `
|
||||
persistence:
|
||||
config:
|
||||
enabled: true
|
||||
cache:
|
||||
enabled: true
|
||||
emptyDir:
|
||||
enabled: true
|
||||
claimWithCustomMountPath:
|
||||
enabled: true
|
||||
mountPath: /custom
|
||||
accessMode: ReadWriteMany
|
||||
size: 1G
|
||||
claimWithSubPath:
|
||||
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
|
||||
`
|
||||
tests := map[string]struct {
|
||||
values *string
|
||||
volumeToTest string
|
||||
expectedMountPath string
|
||||
expectedSubPath string
|
||||
}{
|
||||
"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())
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
59
charts/library/common/tests/controller_test.go
Normal file
59
charts/library/common/tests/controller_test.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type ControllerTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *ControllerTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestController(t *testing.T) {
|
||||
suite.Run(t, new(ControllerTestSuite))
|
||||
}
|
||||
|
||||
func (suite *ControllerTestSuite) TestTypes() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedRenderFailure bool
|
||||
expectedController string
|
||||
}{
|
||||
"Default": {values: nil, expectedRenderFailure: false, expectedController: "deployment"},
|
||||
"DaemonSet": {values: []string{"controller.type=daemonset"}, expectedRenderFailure: false, expectedController: "daemonset"},
|
||||
"Deployment": {values: []string{"controller.type=deployment"}, expectedRenderFailure: false, expectedController: "deployment"},
|
||||
"StatefulSet": {values: []string{"controller.type=statefulset"}, expectedRenderFailure: false, expectedController: "statefulset"},
|
||||
"Custom": {values: []string{"controller.type=custom"}, expectedRenderFailure: true, expectedController: ""},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
suite.Suite.Run(name, func() {
|
||||
err := suite.Chart.Render(nil, tc.values, nil)
|
||||
if tc.expectedRenderFailure {
|
||||
suite.Assertions.Error(err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
manifest := suite.Chart.Manifests.Get(tc.expectedController, "common-test")
|
||||
suite.Assertions.NotEmpty(manifest)
|
||||
|
||||
types := map[string]interface{}{"deployment": nil, "statefulset": nil, "daemonset": nil}
|
||||
delete(types, tc.expectedController)
|
||||
for k := range types {
|
||||
suite.Assertions.Empty(suite.Chart.Manifests.Get(k, "common-test"))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
107
charts/library/common/tests/horizontal_pod_autoscaler_test.go
Normal file
107
charts/library/common/tests/horizontal_pod_autoscaler_test.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type HorizontalPodAutoscalerTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *HorizontalPodAutoscalerTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestHorizontalPodAutoscaler(t *testing.T) {
|
||||
suite.Run(t, new(HorizontalPodAutoscalerTestSuite))
|
||||
}
|
||||
|
||||
func (suite *HorizontalPodAutoscalerTestSuite) TestValues() {
|
||||
baseValues := []string{"autoscaling.enabled=true"}
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedHorizontalPodAutoscaler bool
|
||||
expectedTarget string
|
||||
expectedMinReplicas int
|
||||
expectedMaxReplicas int
|
||||
}{
|
||||
"Default": {
|
||||
values: nil,
|
||||
expectedHorizontalPodAutoscaler: false,
|
||||
},
|
||||
"Enabled": {
|
||||
values: baseValues,
|
||||
expectedHorizontalPodAutoscaler: true, expectedTarget: "common-test", expectedMinReplicas: 1, expectedMaxReplicas: 3,
|
||||
},
|
||||
"CustomSettings": {
|
||||
values: append(baseValues, "autoscaling.target=common-custom", "autoscaling.minReplicas=4", "autoscaling.maxReplicas=8"),
|
||||
expectedHorizontalPodAutoscaler: true, expectedTarget: "common-custom", expectedMinReplicas: 4, expectedMaxReplicas: 8,
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
manifest := suite.Chart.Manifests.Get("HorizontalPodAutoscaler", "common-test")
|
||||
if tc.expectedHorizontalPodAutoscaler {
|
||||
suite.Assertions.NotEmpty(manifest)
|
||||
suite.Assertions.EqualValues(tc.expectedTarget, manifest.Path("spec.scaleTargetRef.name").Data())
|
||||
suite.Assertions.EqualValues(tc.expectedMinReplicas, manifest.Path("spec.minReplicas").Data())
|
||||
suite.Assertions.EqualValues(tc.expectedMaxReplicas, manifest.Path("spec.maxReplicas").Data())
|
||||
} else {
|
||||
suite.Assertions.Empty(manifest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *HorizontalPodAutoscalerTestSuite) TestMetrics() {
|
||||
baseValues := []string{"autoscaling.enabled=true"}
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedResources map[string]int
|
||||
}{
|
||||
"targetCPUUtilizationPercentage": {
|
||||
values: append(baseValues, "autoscaling.targetCPUUtilizationPercentage=60"),
|
||||
expectedResources: map[string]int{"cpu": 60},
|
||||
},
|
||||
"targetMemoryUtilizationPercentage": {
|
||||
values: append(baseValues, "autoscaling.targetMemoryUtilizationPercentage=70"),
|
||||
expectedResources: map[string]int{"memory": 70},
|
||||
},
|
||||
"Combined": {
|
||||
values: append(baseValues, "autoscaling.targetCPUUtilizationPercentage=60", "autoscaling.targetMemoryUtilizationPercentage=70"),
|
||||
expectedResources: map[string]int{"cpu": 60, "memory": 70},
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
manifest := suite.Chart.Manifests.Get("HorizontalPodAutoscaler", "common-test")
|
||||
suite.Assertions.NotEmpty(manifest)
|
||||
|
||||
manifestMetrics, _ := manifest.Path("spec.metrics").Children()
|
||||
|
||||
metricsMap := make(map[string]int)
|
||||
for _, manifestMetric := range manifestMetrics {
|
||||
metricsMap[manifestMetric.Path("resource.name").Data().(string)] = int(manifestMetric.Path("resource.targetAverageUtilization").Data().(float64))
|
||||
}
|
||||
|
||||
suite.Assertions.EqualValues(tc.expectedResources, metricsMap)
|
||||
})
|
||||
}
|
||||
}
|
||||
222
charts/library/common/tests/ingress_test.go
Normal file
222
charts/library/common/tests/ingress_test.go
Normal file
@@ -0,0 +1,222 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type IngressTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *IngressTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestIngress(t *testing.T) {
|
||||
suite.Run(t, new(IngressTestSuite))
|
||||
}
|
||||
|
||||
func (suite *IngressTestSuite) TestValues() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedIngress bool
|
||||
expectedHostName string
|
||||
expectedPath string
|
||||
}{
|
||||
"Default": {
|
||||
values: nil,
|
||||
expectedIngress: false,
|
||||
},
|
||||
"Disabled": {
|
||||
values: []string{"ingress.main.enabled=false"},
|
||||
expectedIngress: false,
|
||||
},
|
||||
"CustomHostAndPath": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.hosts[0].host=chart-test.local",
|
||||
"ingress.main.hosts[0].paths[0].path=/test",
|
||||
},
|
||||
expectedIngress: true,
|
||||
expectedHostName: "chart-test.local",
|
||||
expectedPath: "/test",
|
||||
},
|
||||
"Multiple": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.secondary.enabled=true",
|
||||
},
|
||||
expectedIngress: true,
|
||||
},
|
||||
"PathTemplate": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.hosts[0].host=chart-example.local",
|
||||
`ingress.main.hosts[0].paths[0].path=\{\{ .Release.Name \}\}.path`,
|
||||
},
|
||||
expectedIngress: true,
|
||||
expectedPath: "common-test.path",
|
||||
},
|
||||
"HostTemplate": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
`ingress.main.hosts[0].host=\{\{ .Release.Name \}\}.hostname`,
|
||||
"ingress.main.hosts[0].paths[0].path=/",
|
||||
},
|
||||
expectedIngress: true,
|
||||
expectedHostName: "common-test.hostname",
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
ingressManifest := suite.Chart.Manifests.Get("Ingress", "common-test")
|
||||
if tc.expectedIngress {
|
||||
suite.Assertions.NotEmpty(ingressManifest)
|
||||
|
||||
ingressRules, _ := ingressManifest.Path("spec.rules").Children()
|
||||
if tc.expectedHostName != "" {
|
||||
suite.Assertions.EqualValues(tc.expectedHostName, ingressRules[0].Path("host").Data())
|
||||
}
|
||||
|
||||
if tc.expectedPath != "" {
|
||||
paths, _ := ingressRules[0].Path("http.paths").Children()
|
||||
suite.Assertions.EqualValues(tc.expectedPath, paths[0].Path("path").Data())
|
||||
}
|
||||
} else {
|
||||
suite.Assertions.Empty(ingressManifest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IngressTestSuite) TestPathServices() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedServiceName string
|
||||
expectedServicePort int
|
||||
}{
|
||||
"Default": {
|
||||
values: []string{"ingress.main.enabled=true"},
|
||||
expectedServiceName: "common-test",
|
||||
},
|
||||
"CustomService": {
|
||||
values: []string{
|
||||
"service.main.ports.http.targetPort=80",
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.hosts[0].host=test.local",
|
||||
"ingress.main.hosts[0].paths[0].path=/second/",
|
||||
"ingress.main.hosts[0].paths[0].service.name=pathService",
|
||||
"ingress.main.hosts[0].paths[0].service.port=1234",
|
||||
},
|
||||
expectedServiceName: "pathService",
|
||||
expectedServicePort: 1234,
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
ingressManifest := suite.Chart.Manifests.Get("Ingress", "common-test")
|
||||
suite.Assertions.NotEmpty(ingressManifest)
|
||||
|
||||
ingressRules, _ := ingressManifest.Path("spec.rules").Children()
|
||||
paths, _ := ingressRules[0].Path("http.paths").Children()
|
||||
primaryPath := paths[0]
|
||||
|
||||
if tc.expectedServiceName == "" {
|
||||
suite.Assertions.Empty(primaryPath.Path("backend.service.name").Data())
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedServiceName, primaryPath.Path("backend.service.name").Data())
|
||||
}
|
||||
|
||||
if tc.expectedServicePort == 0 {
|
||||
suite.Assertions.Empty(primaryPath.Path("backend.service.port.number").Data())
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedServicePort, primaryPath.Path("backend.service.port.number").Data())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IngressTestSuite) TestTLS() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedTLS bool
|
||||
expectedHostName string
|
||||
expectedSecretName string
|
||||
}{
|
||||
"Default": {
|
||||
values: nil,
|
||||
expectedTLS: false,
|
||||
},
|
||||
"Provided": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.tls[0].hosts[0]=hostname",
|
||||
"ingress.main.tls[0].secretName=secret-name",
|
||||
},
|
||||
expectedTLS: true,
|
||||
expectedHostName: "hostname",
|
||||
expectedSecretName: "secret-name",
|
||||
},
|
||||
"NoSecret": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.tls[0].hosts[0]=hostname",
|
||||
},
|
||||
expectedTLS: true,
|
||||
expectedHostName: "hostname",
|
||||
expectedSecretName: "",
|
||||
},
|
||||
"SecretTemplate": {
|
||||
values: []string{
|
||||
"ingress.main.enabled=true",
|
||||
"ingress.main.tls[0].hosts[0]=hostname",
|
||||
`ingress.main.tls[0].secretName=\{\{ .Release.Name \}\}-secret`,
|
||||
},
|
||||
expectedTLS: true,
|
||||
expectedHostName: "hostname",
|
||||
expectedSecretName: "common-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())
|
||||
}
|
||||
|
||||
ingressManifest := suite.Chart.Manifests.Get("Ingress", "common-test")
|
||||
|
||||
if tc.expectedTLS {
|
||||
suite.Assertions.NotEmpty(ingressManifest.Path("spec.tls").Data())
|
||||
tlsSpec, _ := ingressManifest.Path("spec.tls").Children()
|
||||
tlsHostsSpec, _ := tlsSpec[0].Path("hosts").Children()
|
||||
suite.Assertions.EqualValues(tc.expectedHostName, tlsHostsSpec[0].Data())
|
||||
|
||||
if tc.expectedSecretName == "" {
|
||||
suite.Assertions.Empty(tlsSpec[0].Path("secretName").Data())
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedSecretName, tlsSpec[0].Path("secretName").Data())
|
||||
}
|
||||
} else {
|
||||
suite.Assertions.Empty(ingressManifest.Path("spec.tls").Data())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
216
charts/library/common/tests/permissions_job_test.go
Normal file
216
charts/library/common/tests/permissions_job_test.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type PermissionsJobTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *PermissionsJobTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestPermissionsJob(t *testing.T) {
|
||||
suite.Run(t, new(PermissionsJobTestSuite))
|
||||
}
|
||||
|
||||
func (suite *PermissionsJobTestSuite) TestPresence() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedJob bool
|
||||
}{
|
||||
"Default": {
|
||||
values: nil,
|
||||
expectedJob: false,
|
||||
},
|
||||
"WithHostPathMount": {
|
||||
values: []string{
|
||||
"hostPathMounts[0].name=data",
|
||||
"hostPathMounts[0].enabled=true",
|
||||
"hostPathMounts[0].mountPath=/data",
|
||||
"hostPathMounts[0].hostPath=/tmp",
|
||||
},
|
||||
expectedJob: 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())
|
||||
}
|
||||
|
||||
jobManifest := suite.Chart.Hooks.Get("Job", "common-test-auto-permissions")
|
||||
if tc.expectedJob {
|
||||
suite.Assertions.NotEmpty(jobManifest)
|
||||
} else {
|
||||
suite.Assertions.Empty(jobManifest)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PermissionsJobTestSuite) TestVolumesAndMounts() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedVolumes []string
|
||||
}{
|
||||
"Default": {
|
||||
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",
|
||||
},
|
||||
expectedVolumes: []string{"hostpathmounts-config", "hostpathmounts-data"},
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
jobManifest := suite.Chart.Hooks.Get("Job", "common-test-auto-permissions")
|
||||
suite.Assertions.NotEmpty(jobManifest)
|
||||
|
||||
jobVolumes, _ := jobManifest.Path("spec.template.spec.volumes").Search("name").Children()
|
||||
containers, _ := jobManifest.Path("spec.template.spec.containers").Children()
|
||||
jobVolumeMounts, _ := containers[0].Path("volumeMounts").Search("name").Children()
|
||||
if tc.expectedVolumes != nil {
|
||||
actualVolumes := []string{}
|
||||
actualVolumeMounts := []string{}
|
||||
|
||||
for _, v := range jobVolumes {
|
||||
actualVolumes = append(actualVolumes, v.Data().(string))
|
||||
}
|
||||
for _, v := range jobVolumeMounts {
|
||||
actualVolumeMounts = append(actualVolumeMounts, v.Data().(string))
|
||||
}
|
||||
|
||||
suite.Assertions.EqualValues(tc.expectedVolumes, actualVolumeMounts)
|
||||
suite.Assertions.EqualValues(tc.expectedVolumes, actualVolumes)
|
||||
} else {
|
||||
suite.Assertions.Empty(jobVolumes)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
}
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedCommand []string
|
||||
}{
|
||||
"DefaultPermissionsForMultipleMounts": {
|
||||
values: baseValues,
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 568:568 /config\nchown -R 568:568 /data\n",
|
||||
},
|
||||
},
|
||||
"DefaultPermissionsForDisabledpodSecurityContext": {
|
||||
values: append(baseValues,
|
||||
"podSecurityContext.allowPrivilegeEscalation=false",
|
||||
),
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 568:568 /config\nchown -R 568:568 /data\n",
|
||||
},
|
||||
},
|
||||
"PermissionsForFsGroup": {
|
||||
values: append(baseValues,
|
||||
"podSecurityContext.fsGroup=666",
|
||||
),
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 568:666 /config\nchown -R 568:666 /data\n",
|
||||
},
|
||||
},
|
||||
"PermissionsForRunAsUser": {
|
||||
values: append(baseValues,
|
||||
"podSecurityContext.runAsUser=999",
|
||||
),
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 999:568 /config\nchown -R 999:568 /data\n",
|
||||
},
|
||||
},
|
||||
"PermissionsForRunAsUserAndFsGroup": {
|
||||
values: append(baseValues,
|
||||
"podSecurityContext.runAsUser=999",
|
||||
"podSecurityContext.fsGroup=666",
|
||||
),
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 999:666 /config\nchown -R 999:666 /data\n",
|
||||
},
|
||||
},
|
||||
"PermissionsForPgidPuid": {
|
||||
values: append(baseValues,
|
||||
"env.PUID=999",
|
||||
"env.PGID=666",
|
||||
),
|
||||
expectedCommand: []string{
|
||||
"/bin/sh", "-c", "chown -R 999:666 /config\nchown -R 999:666 /data\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
jobManifest := suite.Chart.Hooks.Get("Job", "common-test-auto-permissions")
|
||||
suite.Assertions.NotEmpty(jobManifest)
|
||||
|
||||
containers, _ := jobManifest.Path("spec.template.spec.containers").Children()
|
||||
command, _ := containers[0].Path("command").Children()
|
||||
if tc.expectedCommand != nil {
|
||||
actualCommand := []string{}
|
||||
|
||||
for _, v := range command {
|
||||
actualCommand = append(actualCommand, v.Data().(string))
|
||||
}
|
||||
|
||||
suite.Assertions.EqualValues(tc.expectedCommand, actualCommand)
|
||||
} else {
|
||||
suite.Assertions.Empty(command)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
75
charts/library/common/tests/persistentvolumeclaim_test.go
Normal file
75
charts/library/common/tests/persistentvolumeclaim_test.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type PersistenceVolumeClaimTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *PersistenceVolumeClaimTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestPersistenceVolumeClaim(t *testing.T) {
|
||||
suite.Run(t, new(PersistenceVolumeClaimTestSuite))
|
||||
}
|
||||
|
||||
func (suite *PersistenceVolumeClaimTestSuite) TestName() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedName string
|
||||
}{
|
||||
"Default": {values: []string{"persistence.config.enabled=true"}, expectedName: "common-test-config"},
|
||||
"WithoutSuffix": {values: []string{"persistence.config.enabled=true", "persistence.config.nameOverride=-"}, expectedName: "common-test"},
|
||||
"WithNameOverride": {values: []string{"persistence.config.enabled=true", "persistence.config.nameOverride=custom"}, expectedName: "common-test-custom"},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
pvcManifest := suite.Chart.Manifests.Get("PersistentVolumeClaim", tc.expectedName)
|
||||
suite.Assertions.NotEmpty(pvcManifest)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PersistenceVolumeClaimTestSuite) TestStorageClass() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedStorageClass string
|
||||
}{
|
||||
"Default": {values: []string{"persistence.config.enabled=true"}, expectedStorageClass: "-"},
|
||||
"CustomClass": {values: []string{"persistence.config.enabled=true", "persistence.config.storageClass=custom"}, expectedStorageClass: "custom"},
|
||||
"ScaleZFS": {values: []string{"persistence.config.enabled=true", "persistence.config.storageClass=SCALE-ZFS"}, expectedStorageClass: "ix-storage-class-common-test"},
|
||||
"Empty": {values: []string{"persistence.config.enabled=true", "persistence.config.storageClass=-"}, expectedStorageClass: ""},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
pvcManifest := suite.Chart.Manifests.Get("PersistentVolumeClaim", "common-test-config")
|
||||
suite.Assertions.NotEmpty(pvcManifest)
|
||||
|
||||
if tc.expectedStorageClass == "-" {
|
||||
suite.Assertions.Empty(pvcManifest.Path("spec.storageClassName").Data())
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedStorageClass, pvcManifest.Path("spec.storageClassName").Data())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
407
charts/library/common/tests/pod_test.go
Normal file
407
charts/library/common/tests/pod_test.go
Normal file
@@ -0,0 +1,407 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type PodTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestPod(t *testing.T) {
|
||||
suite.Run(t, new(PodTestSuite))
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestReplicas() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedValue interface{}
|
||||
}{
|
||||
"Default": {values: nil, expectedValue: 1},
|
||||
"Specified": {values: []string{"controller.replicas=3"}, expectedValue: 3},
|
||||
}
|
||||
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)
|
||||
suite.Assertions.EqualValues(tc.expectedValue, deploymentManifest.Path("spec.replicas").Data())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestHostNetwork() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedValue interface{}
|
||||
}{
|
||||
"Default": {values: nil, expectedValue: nil},
|
||||
"SpecifiedTrue": {values: []string{"hostNetwork=true"}, expectedValue: true},
|
||||
"SpecifiedFalse": {values: []string{"hostNetwork=false"}, expectedValue: nil},
|
||||
}
|
||||
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)
|
||||
suite.Assertions.EqualValues(tc.expectedValue, deploymentManifest.Path("spec.template.spec.hostNetwork").Data())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestDnsPolicy() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedValue interface{}
|
||||
}{
|
||||
"Default": {values: nil, expectedValue: "ClusterFirst"},
|
||||
"HostnetworkFalse": {values: []string{"hostNetwork=false"}, expectedValue: "ClusterFirst"},
|
||||
"HostnetworkTrue": {values: []string{"hostNetwork=true"}, expectedValue: "ClusterFirstWithHostNet"},
|
||||
"ManualOverride": {values: []string{"dnsPolicy=None"}, expectedValue: "None"},
|
||||
}
|
||||
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)
|
||||
suite.Assertions.EqualValues(tc.expectedValue, deploymentManifest.Path("spec.template.spec.dnsPolicy").Data())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestAdditionalContainers() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedContainer interface{}
|
||||
}{
|
||||
"Static": {values: []string{"additionalContainers[0].name=template-test"}, expectedContainer: "template-test"},
|
||||
"DynamicTemplate": {values: []string{`additionalContainers[0].name=\{\{ .Release.Name \}\}-container`}, expectedContainer: "common-test-container"},
|
||||
}
|
||||
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")
|
||||
containers := deploymentManifest.Path("spec.template.spec.containers")
|
||||
suite.Assertions.Contains(containers.Search("name").Data(), tc.expectedContainer)
|
||||
})
|
||||
}
|
||||
}
|
||||
func (suite *PodTestSuite) TestPersistenceItems() {
|
||||
values := `
|
||||
persistence:
|
||||
cache:
|
||||
enabled: true
|
||||
emptyDir:
|
||||
enabled: true
|
||||
config:
|
||||
enabled: true
|
||||
emptyDir:
|
||||
enabled: false
|
||||
data:
|
||||
enabled: true
|
||||
existingClaim: dataClaim
|
||||
`
|
||||
|
||||
tests := map[string]struct {
|
||||
values *string
|
||||
expectedVolumes []string
|
||||
}{
|
||||
"Default": {values: nil, expectedVolumes: nil},
|
||||
"MultipleItems": {values: &values, expectedVolumes: []string{"config", "cache", "data"}},
|
||||
}
|
||||
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")
|
||||
|
||||
if tc.expectedVolumes == nil {
|
||||
suite.Assertions.EqualValues(nil, volumes.Data())
|
||||
} else {
|
||||
suite.Assertions.NotEmpty(volumes)
|
||||
searchVolumes := volumes.Search("name").Data()
|
||||
for _, expectedVolume := range tc.expectedVolumes {
|
||||
suite.Assertions.Contains(searchVolumes, expectedVolume)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestPersistenceClaimNames() {
|
||||
values := `
|
||||
persistence:
|
||||
config:
|
||||
enabled: true
|
||||
existingClaim:
|
||||
enabled: true
|
||||
existingClaim: myClaim
|
||||
claimWithoutSuffix:
|
||||
enabled: true
|
||||
nameOverride: "-"
|
||||
accessMode: ReadWriteMany
|
||||
size: 1G
|
||||
claimWithNameOverride:
|
||||
enabled: true
|
||||
nameOverride: suffix
|
||||
accessMode: ReadWriteMany
|
||||
size: 1G
|
||||
`
|
||||
tests := map[string]struct {
|
||||
values *string
|
||||
volumeToTest string
|
||||
expectedClaimName string
|
||||
}{
|
||||
"DefaultClaimName": {values: &values, volumeToTest: "config", expectedClaimName: "common-test-config"},
|
||||
"ClaimNameWithoutSuffix": {values: &values, volumeToTest: "claimWithoutSuffix", expectedClaimName: "common-test"},
|
||||
"ClaimNameWithNameOverride": {values: &values, volumeToTest: "claimWithNameOverride", expectedClaimName: "common-test-suffix"},
|
||||
"ExistingClaim": {values: &values, volumeToTest: "existingClaim", expectedClaimName: "myClaim"},
|
||||
}
|
||||
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 {
|
||||
suite.Assertions.EqualValues(tc.expectedClaimName, volume.Path("persistentVolumeClaim.claimName").Data())
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestPersistenceEmptyDir() {
|
||||
baseValues := `
|
||||
persistence:
|
||||
config:
|
||||
enabled: true
|
||||
emptyDir:
|
||||
enabled: true
|
||||
`
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedMedium string
|
||||
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"},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
suite.Suite.Run(name, func() {
|
||||
err := suite.Chart.Render(nil, tc.values, &baseValues)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
deploymentManifest := suite.Chart.Manifests.Get("Deployment", "common-test")
|
||||
volumes, _ := deploymentManifest.Path("spec.template.spec.volumes").Children()
|
||||
volume := volumes[0]
|
||||
suite.Assertions.NotEmpty(volume.Data())
|
||||
|
||||
if tc.expectedMedium == "" {
|
||||
suite.Assertions.Nil(volume.Path("emptyDir.medium"))
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedMedium, volume.Path("emptyDir.medium").Data())
|
||||
}
|
||||
|
||||
if tc.expectedSizeLimit == "" {
|
||||
suite.Assertions.Nil(volume.Path("emptyDir.sizeLimit"))
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedSizeLimit, volume.Path("emptyDir.sizeLimit").Data())
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestHostPathVolumes() {
|
||||
values := `
|
||||
hostPathMounts:
|
||||
- name: data
|
||||
enabled: true
|
||||
mountPath: "/data"
|
||||
hostPath: "/tmp1"
|
||||
- name: config
|
||||
enabled: true
|
||||
emptyDir: true
|
||||
mountPath: "/data"
|
||||
`
|
||||
tests := map[string]struct {
|
||||
values *string
|
||||
expectedVolumes []string
|
||||
}{
|
||||
"Default": {values: nil, expectedVolumes: nil},
|
||||
"MultipleItems": {values: &values, expectedVolumes: []string{"hostpathmounts-data", "hostpathmounts-config"}},
|
||||
}
|
||||
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")
|
||||
|
||||
if tc.expectedVolumes == nil {
|
||||
suite.Assertions.EqualValues(nil, volumes.Data())
|
||||
} else {
|
||||
suite.Assertions.NotEmpty(volumes)
|
||||
searchVolumes := volumes.Search("name").Data()
|
||||
for _, expectedVolume := range tc.expectedVolumes {
|
||||
suite.Assertions.Contains(searchVolumes, expectedVolume)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *PodTestSuite) TestHostPathVolumePaths() {
|
||||
values := `
|
||||
hostPathMounts:
|
||||
- name: data
|
||||
enabled: true
|
||||
mountPath: "/data"
|
||||
hostPath: "/tmp1"
|
||||
- name: config
|
||||
enabled: true
|
||||
emptyDir: 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:
|
||||
- name: 'storage'
|
||||
accessMode: 'ReadWriteOnce'
|
||||
size: '10Gi'
|
||||
storageClass: 'storage'
|
||||
`
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
volumeClaimToTest string
|
||||
expectedAccessMode string
|
||||
expectedSize string
|
||||
expectedStorageClassName string
|
||||
}{
|
||||
"StatefulSet": {values: []string{"controller.type=statefulset"}, volumeClaimToTest: "storage", expectedAccessMode: "ReadWriteOnce", expectedSize: "10Gi", expectedStorageClassName: "storage"},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
suite.Suite.Run(name, func() {
|
||||
err := suite.Chart.Render(nil, tc.values, &values)
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
controllerManifest := suite.Chart.Manifests.Get("StatefulSet", "common-test")
|
||||
suite.Assertions.NotEmpty(controllerManifest)
|
||||
|
||||
volumeClaimTemplates, _ := controllerManifest.Path("spec.volumeClaimTemplates").Children()
|
||||
suite.Assertions.NotEmpty(volumeClaimTemplates)
|
||||
|
||||
for _, volumeClaimTemplate := range volumeClaimTemplates {
|
||||
volumeClaimName := volumeClaimTemplate.Path("metadata.name").Data()
|
||||
if volumeClaimName == tc.volumeClaimToTest {
|
||||
if tc.expectedAccessMode == "" {
|
||||
suite.Assertions.Empty(controllerManifest)
|
||||
} else {
|
||||
accessModes, _ := volumeClaimTemplate.Path("spec.accessModes").Children()
|
||||
suite.Assertions.EqualValues(tc.expectedAccessMode, accessModes[0].Data())
|
||||
}
|
||||
|
||||
if tc.expectedSize == "" {
|
||||
suite.Assertions.Empty(controllerManifest)
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedSize, volumeClaimTemplate.Path("spec.resources.requests.storage").Data())
|
||||
}
|
||||
|
||||
if tc.expectedStorageClassName == "" {
|
||||
suite.Assertions.Empty(controllerManifest)
|
||||
} else {
|
||||
suite.Assertions.EqualValues(tc.expectedStorageClassName, volumeClaimTemplate.Path("spec.storageClassName").Data())
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
138
charts/library/common/tests/service_test.go
Normal file
138
charts/library/common/tests/service_test.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/truecharts/apps/tests/helmunit"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type ServiceTestSuite struct {
|
||||
suite.Suite
|
||||
Chart helmunit.HelmChart
|
||||
}
|
||||
|
||||
func (suite *ServiceTestSuite) SetupSuite() {
|
||||
suite.Chart = helmunit.New("common-test", "../../common-test")
|
||||
suite.Chart.UpdateDependencies()
|
||||
}
|
||||
|
||||
// We need this function to kick off the test suite, otherwise
|
||||
// "go test" won't know about our tests
|
||||
func TestService(t *testing.T) {
|
||||
suite.Run(t, new(ServiceTestSuite))
|
||||
}
|
||||
|
||||
func (suite *ServiceTestSuite) TestServiceName() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedName string
|
||||
}{
|
||||
"Default": {values: nil, expectedName: "common-test"},
|
||||
"CustomName": {values: []string{"service.main.nameOverride=http"}, expectedName: "common-test-http"},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
serviceManifest := suite.Chart.Manifests.Get("Service", tc.expectedName)
|
||||
suite.Assertions.NotEmpty(serviceManifest)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ServiceTestSuite) TestPortNames() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedRenderFailure bool
|
||||
expectedName string
|
||||
expectedTargetPort interface{}
|
||||
}{
|
||||
"Default": {values: nil, expectedRenderFailure: false, expectedName: "http", expectedTargetPort: "http"},
|
||||
"CustomName": {values: []string{"service.main.ports.http.enabled=false", "service.main.ports.server.enabled=true", "service.main.ports.server.port=8080"}, expectedRenderFailure: false, expectedName: "server", expectedTargetPort: "server"},
|
||||
"CustomTargetPort": {values: []string{"service.main.ports.http.targetPort=80"}, expectedRenderFailure: false, expectedName: "http", expectedTargetPort: 80},
|
||||
"NamedTargetPort": {values: []string{"service.main.ports.http.targetPort=name"}, expectedRenderFailure: true, expectedName: "", expectedTargetPort: nil},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
suite.Suite.Run(name, func() {
|
||||
err := suite.Chart.Render(nil, tc.values, nil)
|
||||
if tc.expectedRenderFailure {
|
||||
suite.Assertions.Error(err)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
suite.FailNow(err.Error())
|
||||
}
|
||||
|
||||
serviceManifest := suite.Chart.Manifests.Get("Service", "common-test")
|
||||
suite.Assertions.NotEmpty(serviceManifest)
|
||||
servicePorts, _ := serviceManifest.Path("spec.ports").Children()
|
||||
suite.Assertions.EqualValues(tc.expectedName, servicePorts[0].Path("name").Data())
|
||||
suite.Assertions.EqualValues(tc.expectedTargetPort, servicePorts[0].Path("targetPort").Data())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ServiceTestSuite) TestPortProtocol() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedProtocol string
|
||||
}{
|
||||
"Default": {values: nil, expectedProtocol: "TCP"},
|
||||
"ExplicitTCP": {values: []string{"service.main.ports.http.protocol=TCP"}, expectedProtocol: "TCP"},
|
||||
"ExplicitHTTP": {values: []string{"service.main.ports.http.protocol=HTTP"}, expectedProtocol: "TCP"},
|
||||
"ExplicitHTTPS": {values: []string{"service.main.ports.http.protocol=HTTPS"}, expectedProtocol: "TCP"},
|
||||
"ExplicitUDP": {values: []string{"service.main.ports.http.protocol=UDP"}, 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())
|
||||
}
|
||||
|
||||
serviceManifest := suite.Chart.Manifests.Get("Service", "common-test")
|
||||
suite.Assertions.NotEmpty(serviceManifest)
|
||||
servicePorts, _ := serviceManifest.Path("spec.ports").Children()
|
||||
suite.Assertions.EqualValues(tc.expectedProtocol, servicePorts[0].Path("protocol").Data())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ServiceTestSuite) TestAnnotations() {
|
||||
tests := map[string]struct {
|
||||
values []string
|
||||
expectedAnnotations map[string]string
|
||||
}{
|
||||
"Default": {values: nil, expectedAnnotations: nil},
|
||||
"ExplicitTCP": {values: []string{"service.main.ports.http.protocol=TCP"}, expectedAnnotations: nil},
|
||||
"ExplicitHTTP": {values: []string{"service.main.ports.http.protocol=HTTP"}, expectedAnnotations: nil},
|
||||
"ExplicitHTTPS": {values: []string{"service.main.ports.http.protocol=HTTPS"}, expectedAnnotations: map[string]string{"traefik.ingress.kubernetes.io/service.serversscheme": "https"}},
|
||||
"ExplicitUDP": {values: []string{"service.main.ports.http.protocol=UDP"}, expectedAnnotations: nil},
|
||||
}
|
||||
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())
|
||||
}
|
||||
|
||||
serviceManifest := suite.Chart.Manifests.Get("Service", "common-test")
|
||||
suite.Assertions.NotEmpty(serviceManifest)
|
||||
serviceAnnotations, _ := serviceManifest.Path("metadata.annotations").Children()
|
||||
if tc.expectedAnnotations == nil {
|
||||
suite.Assertions.Empty(serviceAnnotations)
|
||||
} else {
|
||||
for annotation, value := range tc.expectedAnnotations {
|
||||
serviceAnnotation := serviceManifest.Path("metadata.annotations").Search(annotation)
|
||||
suite.Assertions.NotEmpty(serviceAnnotation, fmt.Sprintf("Annotation %s not found", annotation))
|
||||
suite.Assertions.EqualValues(value, serviceAnnotation.Data(), fmt.Sprintf("Invalid value for annotation %s", annotation))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,89 @@
|
||||
# type: options are deployment, daemonset or statefulset
|
||||
controllerType: deployment
|
||||
# Set annotations on the deployment/statefulset/daemonset
|
||||
controllerAnnotations: {}
|
||||
# Set labels on the deployment/statefulset/daemonset
|
||||
controllerLabels: {}
|
||||
global:
|
||||
# -- Set an override for the prefix of the fullname
|
||||
nameOverride:
|
||||
# -- Set the entire name definition
|
||||
fullnameOverride:
|
||||
|
||||
replicas: 1
|
||||
strategy:
|
||||
## For Deployments, valid values are Recreate and RollingUpdate
|
||||
## For StatefulSets, valid values are OnDelete and RollingUpdate
|
||||
## DaemonSets ignore this
|
||||
type: RollingUpdate
|
||||
controller:
|
||||
# -- Set the controller type.
|
||||
# Valid options are deployment, daemonset or statefulset
|
||||
type: deployment
|
||||
# -- Set annotations on the deployment/statefulset/daemonset
|
||||
annotations: {}
|
||||
# -- Set labels on the deployment/statefulset/daemonset
|
||||
labels: {}
|
||||
# -- Number of desired pods
|
||||
replicas: 1
|
||||
# -- Set the controller upgrade strategy
|
||||
# For Deployments, valid values are Recreate (default) and RollingUpdate.
|
||||
# For StatefulSets, valid values are OnDelete and RollingUpdate (default).
|
||||
# DaemonSets ignore this.
|
||||
strategy:
|
||||
rollingUpdate:
|
||||
# -- Set deployment RollingUpdate max unavailable
|
||||
unavailable:
|
||||
# -- Set deployment RollingUpdate max surge
|
||||
surge:
|
||||
# -- Set statefulset RollingUpdate partition
|
||||
partition:
|
||||
# -- ReplicaSet revision history limit
|
||||
revisionHistoryLimit: 3
|
||||
|
||||
# Override the default command
|
||||
image:
|
||||
# -- image repository
|
||||
repository:
|
||||
# -- image tag
|
||||
tag:
|
||||
# -- image pull policy
|
||||
pullPolicy:
|
||||
|
||||
# -- Override the command(s) for the default container
|
||||
command: []
|
||||
# Override the default args
|
||||
# -- Override the args for the default container
|
||||
args: []
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
# Set annotations on the pod
|
||||
# -- Set annotations on the pod
|
||||
podAnnotations: {}
|
||||
|
||||
# -- Add a Horizontal Pod Autoscaler
|
||||
# @default -- <disabled>
|
||||
autoscaling:
|
||||
enabled: false
|
||||
target: # deploymentname
|
||||
minReplicas: # 1
|
||||
maxReplicas: # 100
|
||||
targetCPUUtilizationPercentage: # 80
|
||||
targetMemoryUtilizationPercentage: # 80
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
# -- Specifies whether a service account should be created
|
||||
create: false
|
||||
# Annotations to add to the service account
|
||||
|
||||
# -- Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
|
||||
# -- The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
# -- Use this to populate a secret with the values you specify.
|
||||
# Be aware that these values are not encrypted by default, and could therefore visible
|
||||
# to anybody with access to the values.yaml file.
|
||||
secret: {}
|
||||
# PASSWORD: my-password
|
||||
|
||||
# -- Main environment variables. Template enabled.
|
||||
# Syntax options:
|
||||
# A) TZ: UTC
|
||||
# B) PASSWD: '{{ .Release.Name }}'
|
||||
# C) PASSWD:
|
||||
# envFrom:
|
||||
# ...
|
||||
# D) - name: TZ
|
||||
# value: UTC
|
||||
# E) - name: TZ
|
||||
# value: '{{ .Release.Name }}'
|
||||
env: {}
|
||||
# TZ: UTC
|
||||
|
||||
## Variables with values set from templates, example
|
||||
## With a release name of: demo, the example env value will be: demo-admin
|
||||
envTpl: {}
|
||||
@@ -53,170 +101,274 @@ envFrom: []
|
||||
# name: config-map-name
|
||||
# - secretRef:
|
||||
# name: secret-name
|
||||
# -- Custom priority class for different treatment by the scheduler
|
||||
priorityClassName: # system-node-critical
|
||||
|
||||
# Custom priority class for different treatment by the scheduler
|
||||
# priorityClassName: system-node-critical
|
||||
# -- Allows specifying a custom scheduler name
|
||||
schedulerName: # awkward-dangerous-scheduler
|
||||
|
||||
# Allow specifying a custom scheduler name
|
||||
# schedulerName: awkward-dangerous-scheduler
|
||||
# -- Allows specifying explicit hostname setting
|
||||
hostname:
|
||||
|
||||
# Allow specifying explicit hostname setting
|
||||
# hostname:
|
||||
|
||||
# When using hostNetwork make sure you set dnsPolicy to ClusterFirstWithHostNet
|
||||
# -- When using hostNetwork make sure you set dnsPolicy to `ClusterFirstWithHostNet`
|
||||
hostNetwork: false
|
||||
|
||||
## Default get based on hostNetwork setting
|
||||
# dnsPolicy: ClusterFirst
|
||||
# -- Defaults to "ClusterFirst" if hostNetwork is false and "ClusterFirstWithHostNet" if hostNetwork is true.
|
||||
dnsPolicy: # ClusterFirst
|
||||
|
||||
# Optional DNS settings, configuring the ndots option may resolve
|
||||
# nslookup issues on some Kubernetes setups.
|
||||
# dnsConfig:
|
||||
# -- Optional DNS settings, configuring the ndots option may resolve nslookup issues on some Kubernetes setups.
|
||||
dnsConfig: {}
|
||||
# options:
|
||||
# - name: ndots
|
||||
# value: "1"
|
||||
|
||||
# Enable/disable the generation of environment variables for services.
|
||||
# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#accessing-the-service
|
||||
# for more information.
|
||||
# -- Enable/disable the generation of environment variables for services.
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#accessing-the-service)
|
||||
enableServiceLinks: true
|
||||
|
||||
# Configure the Security Context for the Pod
|
||||
# podSecurityContext:
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 568
|
||||
# runAsGroup: 568
|
||||
# fsGroup: 568
|
||||
# fsGroupChangePolicy: "OnRootMismatch"
|
||||
# -- Configure the Security Context for the Pod
|
||||
podSecurityContext: {}
|
||||
|
||||
# Configure the Security Context for the main container
|
||||
# -- Configure the Security Context for the main container
|
||||
securityContext: {}
|
||||
|
||||
# -- Configure the lifecycle for the main container
|
||||
lifecycle: {}
|
||||
|
||||
# -- Specify any initContainers here. Yaml will be passed in to the Pod as-is.
|
||||
initContainers: []
|
||||
|
||||
# -- Specify any additional containers here. Yaml will be passed in to the Pod as-is.
|
||||
additionalContainers: []
|
||||
|
||||
## Probes configuration
|
||||
# -- Probe configuration
|
||||
# -- [[ref]](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)
|
||||
# @default -- See below
|
||||
probes:
|
||||
# -- Liveness probe configuration
|
||||
# @default -- See below
|
||||
liveness:
|
||||
# -- Enable the liveness probe
|
||||
enabled: true
|
||||
## Set this to true if you wish to specify your own livenessProbe
|
||||
# -- Set this to `true` if you wish to specify your own livenessProbe
|
||||
custom: false
|
||||
## The spec field contains the values for the default livenessProbe.
|
||||
## If you selected custom: true, this field holds the definition of the livenessProbe.
|
||||
# -- The spec field contains the values for the default livenessProbe.
|
||||
# If you selected `custom: true`, this field holds the definition of the livenessProbe.
|
||||
# @default -- See below
|
||||
spec:
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 3
|
||||
|
||||
# -- Redainess probe configuration
|
||||
# @default -- See below
|
||||
readiness:
|
||||
# -- Enable the readiness probe
|
||||
enabled: true
|
||||
## Set this to true if you wish to specify your own readinessProbe
|
||||
# -- Set this to `true` if you wish to specify your own readinessProbe
|
||||
custom: false
|
||||
## The spec field contains the values for the default readinessProbe.
|
||||
## If you selected custom: true, this field holds the definition of the readinessProbe.
|
||||
# -- The spec field contains the values for the default readinessProbe.
|
||||
# If you selected `custom: true`, this field holds the definition of the readinessProbe.
|
||||
# @default -- See below
|
||||
spec:
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 3
|
||||
|
||||
# -- Startup probe configuration
|
||||
# @default -- See below
|
||||
startup:
|
||||
# -- Enable the startup probe
|
||||
enabled: true
|
||||
## Set this to true if you wish to specify your own startupProbe
|
||||
# -- Set this to `true` if you wish to specify your own startupProbe
|
||||
custom: false
|
||||
## The spec field contains the values for the default startupProbe.
|
||||
## If you selected custom: true, this field holds the definition of the startupProbe.
|
||||
# -- The spec field contains the values for the default startupProbe.
|
||||
# If you selected `custom: true`, this field holds the definition of the startupProbe.
|
||||
# @default -- See below
|
||||
spec:
|
||||
initialDelaySeconds: 0
|
||||
timeoutSeconds: 10
|
||||
timeoutSeconds: 1
|
||||
## This means it has a maximum of 5*30=150 seconds to start up before it fails
|
||||
periodSeconds: 10
|
||||
periodSeconds: 5
|
||||
failureThreshold: 30
|
||||
|
||||
services:
|
||||
# -- Configure the services for the chart here.
|
||||
# Additional services can be added by adding a dictionary key similar to the 'main' service.
|
||||
# @default -- See below
|
||||
service:
|
||||
main:
|
||||
# -- Enables or disables the service
|
||||
enabled: true
|
||||
type: ClusterIP
|
||||
## Specify the default port information
|
||||
## It is adviced not to mix different port protocols on the same service
|
||||
port:
|
||||
port:
|
||||
## name defaults to http
|
||||
name:
|
||||
## Accepts: HTTP, HTTPS, TCP and UDP
|
||||
## HTTPS and HTTPS spawn a TCP service and get used for internal URL and name generation
|
||||
protocol: HTTP
|
||||
## Specify a service targetPort if you wish to differ the service port from the application port.
|
||||
## If targetPort is specified, this port number is used in the container definition instead of
|
||||
## service.port.port. Therefore named ports are not supported for this field.
|
||||
targetPort:
|
||||
## Specify the nodePort value for the LoadBalancer and NodePort service types.
|
||||
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
|
||||
##
|
||||
# nodePort:
|
||||
additionalPorts: []
|
||||
|
||||
## Provide any additional annotations which may be required. This can be used to
|
||||
## set the LoadBalancer service type to internal only.
|
||||
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer
|
||||
##
|
||||
# -- Make this the primary service (used in probes, notes, etc...).
|
||||
# If there is more than 1 service, make sure that only 1 service is marked as primary.
|
||||
primary: true
|
||||
|
||||
# -- Override the name suffix that is used for this service
|
||||
nameOverride:
|
||||
|
||||
# -- Set the service type
|
||||
type: ClusterIP
|
||||
|
||||
# -- Provide additional annotations which may be required.
|
||||
annotations: {}
|
||||
|
||||
# -- Provide additional labels which may be required.
|
||||
labels: {}
|
||||
|
||||
## additionalServices can be created as either a dict.
|
||||
# additionalService:
|
||||
# type: ClusterIP
|
||||
# # Specify the default port information
|
||||
# port:
|
||||
# port:
|
||||
# # name defaults to http
|
||||
# name:
|
||||
# protocol: TCP
|
||||
# # targetPort defaults to http
|
||||
# targetPort:
|
||||
# # nodePort:
|
||||
# additionalPorts: []
|
||||
# annotations: {}
|
||||
# labels: {}
|
||||
# -- Configure the Service port information here.
|
||||
# Additional ports can be added by adding a dictionary key similar to the 'http' service.
|
||||
# @default -- See below
|
||||
ports:
|
||||
http:
|
||||
# -- Enables or disables the port
|
||||
enabled: true
|
||||
|
||||
persistence:
|
||||
config:
|
||||
# -- Make this the primary port (used in probes, notes, etc...)
|
||||
# If there is more than 1 service, make sure that only 1 port is marked as primary.
|
||||
primary: true
|
||||
|
||||
# -- The port number
|
||||
port:
|
||||
|
||||
# -- Port protocol.
|
||||
# Support values are `HTTP`, `HTTPS`, `TCP` and `UDP`.
|
||||
# HTTPS and HTTPS spawn a TCP service and get used for internal URL and name generation
|
||||
protocol: HTTP
|
||||
|
||||
# -- Specify a service targetPort if you wish to differ the service port from the application port.
|
||||
# If `targetPort` is specified, this port number is used in the container definition instead of
|
||||
# the `port` value. Therefore named ports are not supported for this field.
|
||||
targetPort:
|
||||
|
||||
# -- Specify the nodePort value for the LoadBalancer and NodePort service types.
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport)
|
||||
nodePort:
|
||||
|
||||
# -- Configure the ingresses for the chart here.
|
||||
# Additional ingresses can be added by adding a dictionary key similar to the 'main' ingress.
|
||||
# @default -- See below
|
||||
ingress:
|
||||
main:
|
||||
# -- Enables or disables the ingress
|
||||
enabled: false
|
||||
|
||||
# -- Make this the primary ingress (used in probes, notes, etc...).
|
||||
# If there is more than 1 ingress, make sure that only 1 ingress is marked as primary.
|
||||
primary: true
|
||||
|
||||
# -- Override the name suffix that is used for this ingress.
|
||||
nameOverride:
|
||||
|
||||
# -- Provide additional annotations which may be required.
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
|
||||
# -- Provide additional labels which may be required.
|
||||
labels: {}
|
||||
|
||||
# -- Set the ingressClass that is used for this ingress.
|
||||
# Requires Kubernetes >=1.19
|
||||
ingressClassName: # "nginx"
|
||||
|
||||
## Configure the hosts for the ingress
|
||||
hosts:
|
||||
- # -- Host address. Helm template can be passed.
|
||||
host: chart-example.local
|
||||
## Configure the paths for the host
|
||||
paths:
|
||||
- # -- Path. Helm template can be passed.
|
||||
path: /
|
||||
# -- Ignored if not kubeVersion >= 1.14-0
|
||||
pathType: Prefix
|
||||
service:
|
||||
# -- Overrides the service name reference for this path
|
||||
name:
|
||||
# -- Overrides the service port reference for this path
|
||||
port:
|
||||
|
||||
# -- Configure TLS for the ingress. Both secretName and hosts can process a Helm template.
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# -- Create a secret from a GUI selected TrueNAS SCALE certificate
|
||||
# scaleCert: true
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
# -- Configure the persistent volumes 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
|
||||
enabled: false
|
||||
|
||||
# -- Where to mount the volume in the main container.
|
||||
mountPath: /config
|
||||
## configuration data Persistent Volume Storage Class
|
||||
## If defined, storageClassName: <storageClass>
|
||||
## If set to "-", storageClassName: "", which disables dynamic provisioning
|
||||
## If undefined (the default) or set to null, no storageClassName spec is
|
||||
## set, choosing the default provisioner. (gp2 on AWS, standard on
|
||||
## GKE, AWS & OpenStack)
|
||||
##
|
||||
# storageClass: "-"
|
||||
##
|
||||
## If you want to reuse an existing claim, you can pass the name of the PVC using
|
||||
## the existingClaim variable
|
||||
# existingClaim: your-claim
|
||||
# subPath: some-subpath
|
||||
|
||||
# -- 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.
|
||||
# If set to something else, the given storageClass is used.
|
||||
# If undefined (the default) or set to null, no storageClassName spec is set, choosing the default provisioner.
|
||||
storageClass: # "-"
|
||||
|
||||
# -- If you want to reuse an existing claim, the name of the existing PVC can be passed here.
|
||||
existingClaim: # your-claim
|
||||
|
||||
# -- Used in conjunction with `existingClaim`. Specifies a sub-path inside the referenced volume instead of its root
|
||||
subPath: # some-subpath
|
||||
|
||||
# -- AccessMode for the persistent volume.
|
||||
# Make sure to select an access mode that is supported by your storage provider!
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes)
|
||||
accessMode: ReadWriteOnce
|
||||
|
||||
# -- The amount of storage that is requested for the persistent volume.
|
||||
size: 1Gi
|
||||
## Set to true to retain the PVC upon helm uninstall
|
||||
|
||||
# - Set to true to retain the PVC upon `helm uninstall`
|
||||
skipuninstall: false
|
||||
|
||||
# Create an emptyDir volume to share between all containers
|
||||
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.
|
||||
mountPath: /shared
|
||||
|
||||
# -- Mount a path on the host to the main container.
|
||||
hostPathMounts: []
|
||||
# - name: "data"
|
||||
# enabled: false
|
||||
# emptyDir: false
|
||||
# mountPath: "/data"
|
||||
# subPath: some-subpath
|
||||
# hostPath: ""
|
||||
# readOnly: false
|
||||
|
||||
# -- Specify any additional volumes here. (e.g. to mount nfs volumes directly)
|
||||
additionalVolumes: []
|
||||
|
||||
# -- Specify any additional volume mounts for the main container here.
|
||||
additionalVolumeMounts: []
|
||||
|
||||
# -- Used in conjunction with `controller.type: statefulset` to create individual disks for each instance.
|
||||
volumeClaimTemplates: []
|
||||
# Used in statefulset to create individual disks for each instance
|
||||
# - name: data
|
||||
# mountPath: /data
|
||||
# accessMode: "ReadWriteOnce"
|
||||
@@ -228,107 +380,271 @@ volumeClaimTemplates: []
|
||||
# size: 2Gi
|
||||
# storageClass: cheap-storage-class
|
||||
|
||||
# -- Node selection constraint
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector)
|
||||
nodeSelector: {}
|
||||
|
||||
# -- Defines affinity constraint rules.
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)
|
||||
affinity: {}
|
||||
|
||||
# -- Specify taint tolerations
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)
|
||||
tolerations: []
|
||||
|
||||
# -- Use hostAliases to add custom entries to /etc/hosts - mapping IP addresses to hostnames.
|
||||
# [[ref]](https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/)
|
||||
hostAliases: []
|
||||
# Use hostAliases to add custom entries to /etc/hosts - mapping IP addresses to hostnames.
|
||||
# ref: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/
|
||||
# - ip: "192.168.1.100"
|
||||
# hostnames:
|
||||
# - "example.com"
|
||||
# - "www.example.com"
|
||||
|
||||
# -- Set the resource requests / limits for the main container.
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
## We usually recommend not to specify default resources and to leave this as a conscious
|
||||
## choice for the user. This also increases chances charts run on environments with little
|
||||
## resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
## lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
## Used by TrueNAS SCALE to easily set add GPU's to Apps
|
||||
# scaleGPU: {}
|
||||
# -- The common chart supports several add-ons. These can be configured under this key.
|
||||
# @default -- See below
|
||||
addons:
|
||||
|
||||
## TrueCharts Specific
|
||||
|
||||
# deviceMounts:
|
||||
# config:
|
||||
# enabled: false
|
||||
# emptyDir: false
|
||||
# hostPath: "/config"
|
||||
# setPermissions: true
|
||||
|
||||
# customStorage:
|
||||
# - name: "data"
|
||||
# enabled: false
|
||||
# emptyDir: false
|
||||
# mountPath: "/data"
|
||||
# subPath: some-subpath
|
||||
# hostPath: ""
|
||||
# readOnly: false
|
||||
# setPermissions: true
|
||||
|
||||
ingress:
|
||||
main:
|
||||
# -- 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
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
labels: {}
|
||||
# ingressClassName: "nginx"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
## Or a tpl that is evaluated
|
||||
# hostTpl: '{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.ingress.domainname }}'
|
||||
paths:
|
||||
- path: /
|
||||
## Or a tpl that is evaluated
|
||||
# pathTpl: '{{ include "common.names.fullname" . }}'
|
||||
## Ignored if not kubeVersion >= 1.14-0
|
||||
pathType: Prefix
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
## Or if you need a dynamic secretname
|
||||
# - secretNameTpl: '{{ include "common.names.fullname" . }}-ingress'
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
## Or a tpl that is evaluated
|
||||
# hostsTpl:
|
||||
# - '{{ include "common.names.fullname" . }}.{{ .Release.Namespace }}.{{ .Values.ingress.domainname }}'
|
||||
# additionalIngress:
|
||||
# annotations: {}
|
||||
# # kubernetes.io/ingress.class: nginx
|
||||
# # kubernetes.io/tls-acme: "true"
|
||||
# labels: {}
|
||||
# hosts:
|
||||
# - host: chart-example.local
|
||||
# paths:
|
||||
# - path: /api
|
||||
# # Ignored if not kubeVersion >= 1.14-0
|
||||
# pathType: Prefix
|
||||
# serviceName: # optionally target a specific service
|
||||
# servicePort: # optionally target a specific service port
|
||||
# tls: []
|
||||
# # - secretName: chart-example-tls
|
||||
# # hosts:
|
||||
# # - chart-example.local
|
||||
|
||||
# ## Adds a portal configmap for use with TrueNAS SCALE
|
||||
# ## This should not be enabled on other systems than TrueNAS SCALE,
|
||||
# ## Because it requires a seperate namespace for each chart.
|
||||
# portal:
|
||||
# enabled: false
|
||||
# ## Override default port used for the portal button when using ingress.
|
||||
# # ingressPort: 80
|
||||
# ## Override hostname used for the portal button when using nodePort
|
||||
# # host: 192.168.0.2
|
||||
# ## Override the path used in the url
|
||||
# # path: /example
|
||||
# -- 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
|
||||
|
||||
@@ -1,322 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
describe @@chart.name do
|
||||
describe 'scaleCertificate' do
|
||||
it 'disabled by default' do
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
assert_nil(resource('Secret'))
|
||||
end
|
||||
it 'can be enabled and selected' do
|
||||
values = {
|
||||
"ixCertificateAuthorities": {},
|
||||
"ixCertificates": {
|
||||
"1": {
|
||||
"CA_type_existing": false,
|
||||
"CA_type_intermediate": false,
|
||||
"CA_type_internal": false,
|
||||
"CSR": "",
|
||||
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
|
||||
"cert_type": "CERTIFICATE",
|
||||
"cert_type_CSR": false,
|
||||
"cert_type_existing": true,
|
||||
"cert_type_internal": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
|
||||
"certificate_path": "/etc/certificates/freenas_default.crt",
|
||||
"chain": false,
|
||||
"chain_list": [
|
||||
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
|
||||
],
|
||||
"city": "Maryville",
|
||||
"common": "localhost",
|
||||
"country": "US",
|
||||
"csr_path": "/etc/certificates/freenas_default.csr",
|
||||
"digest_algorithm": "SHA256",
|
||||
"email": "info@ixsystems.com",
|
||||
"extensions": {
|
||||
"ExtendedKeyUsage": "TLS Web Server Authentication",
|
||||
"SubjectAltName": "DNS:localhost"
|
||||
},
|
||||
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
|
||||
"from": "Fri Sep 25 16:05:38 2020",
|
||||
"id": 1,
|
||||
"internal": "NO",
|
||||
"issuer": "external",
|
||||
"key_length": 2048,
|
||||
"key_type": "RSA",
|
||||
"lifetime": 825,
|
||||
"name": "freenas_default",
|
||||
"organization": "iXsystems",
|
||||
"organizational_unit": "",
|
||||
"parsed": true,
|
||||
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
|
||||
"privatekey_path": "/etc/certificates/freenas_default.key",
|
||||
"revoked": false,
|
||||
"revoked_date": "",
|
||||
"root_path": "/etc/certificates",
|
||||
"san": [
|
||||
"DNS:localhost"
|
||||
],
|
||||
"serial": 1,
|
||||
"signedby": "",
|
||||
"state": "Tennessee",
|
||||
"subject_name_hash": 3193428416,
|
||||
"type": 8,
|
||||
"until": "Thu Dec 29 15:05:38 2022"
|
||||
}
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
scaleCert: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
refute_nil(resource('Secret'))
|
||||
secret = chart.resources(kind: "Secret").first
|
||||
assert_equal("common-test-main-tls-0-ixcert-1", secret["metadata"]["name"])
|
||||
refute_nil(secret["data"]["tls.crt"])
|
||||
refute_nil(secret["data"]["tls.key"])
|
||||
end
|
||||
|
||||
it 'secret can be used for TLS ingress' do
|
||||
values = {
|
||||
"ixCertificateAuthorities": {},
|
||||
"ixCertificates": {
|
||||
"1": {
|
||||
"CA_type_existing": false,
|
||||
"CA_type_intermediate": false,
|
||||
"CA_type_internal": false,
|
||||
"CSR": "",
|
||||
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
|
||||
"cert_type": "CERTIFICATE",
|
||||
"cert_type_CSR": false,
|
||||
"cert_type_existing": true,
|
||||
"cert_type_internal": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
|
||||
"certificate_path": "/etc/certificates/freenas_default.crt",
|
||||
"chain": false,
|
||||
"chain_list": [
|
||||
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
|
||||
],
|
||||
"city": "Maryville",
|
||||
"common": "localhost",
|
||||
"country": "US",
|
||||
"csr_path": "/etc/certificates/freenas_default.csr",
|
||||
"digest_algorithm": "SHA256",
|
||||
"email": "info@ixsystems.com",
|
||||
"extensions": {
|
||||
"ExtendedKeyUsage": "TLS Web Server Authentication",
|
||||
"SubjectAltName": "DNS:localhost"
|
||||
},
|
||||
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
|
||||
"from": "Fri Sep 25 16:05:38 2020",
|
||||
"id": 1,
|
||||
"internal": "NO",
|
||||
"issuer": "external",
|
||||
"key_length": 2048,
|
||||
"key_type": "RSA",
|
||||
"lifetime": 825,
|
||||
"name": "freenas_default",
|
||||
"organization": "iXsystems",
|
||||
"organizational_unit": "",
|
||||
"parsed": true,
|
||||
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
|
||||
"privatekey_path": "/etc/certificates/freenas_default.key",
|
||||
"revoked": false,
|
||||
"revoked_date": "",
|
||||
"root_path": "/etc/certificates",
|
||||
"san": [
|
||||
"DNS:localhost"
|
||||
],
|
||||
"serial": 1,
|
||||
"signedby": "",
|
||||
"state": "Tennessee",
|
||||
"subject_name_hash": 3193428416,
|
||||
"type": 8,
|
||||
"until": "Thu Dec 29 15:05:38 2022"
|
||||
}
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
hosts: [ 'hostname' ],
|
||||
scaleCert: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
refute_nil(resource('Secret'))
|
||||
secret = chart.resources(kind: "Secret").first
|
||||
assert_equal("common-test-main-tls-0-ixcert-1", secret["metadata"]["name"])
|
||||
refute_nil(secret["data"]["tls.crt"])
|
||||
refute_nil(secret["data"]["tls.key"])
|
||||
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal("common-test-main-tls-0-ixcert-1", ingress["spec"]["tls"][0]["secretName"])
|
||||
end
|
||||
it 'multiple tls sections generate multiple secrets' do
|
||||
values = {
|
||||
"ixCertificateAuthorities": {},
|
||||
"ixCertificates": {
|
||||
"2": {
|
||||
"CA_type_existing": false,
|
||||
"CA_type_intermediate": false,
|
||||
"CA_type_internal": false,
|
||||
"CSR": "",
|
||||
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
|
||||
"cert_type": "CERTIFICATE",
|
||||
"cert_type_CSR": false,
|
||||
"cert_type_existing": true,
|
||||
"cert_type_internal": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
|
||||
"certificate_path": "/etc/certificates/freenas_default.crt",
|
||||
"chain": false,
|
||||
"chain_list": [
|
||||
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
|
||||
],
|
||||
"city": "Maryville",
|
||||
"common": "localhost",
|
||||
"country": "US",
|
||||
"csr_path": "/etc/certificates/freenas_default.csr",
|
||||
"digest_algorithm": "SHA256",
|
||||
"email": "info@ixsystems.com",
|
||||
"extensions": {
|
||||
"ExtendedKeyUsage": "TLS Web Server Authentication",
|
||||
"SubjectAltName": "DNS:localhost"
|
||||
},
|
||||
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
|
||||
"from": "Fri Sep 25 16:05:38 2020",
|
||||
"id": 2,
|
||||
"internal": "NO",
|
||||
"issuer": "external",
|
||||
"key_length": 2048,
|
||||
"key_type": "RSA",
|
||||
"lifetime": 825,
|
||||
"name": "freenas_default",
|
||||
"organization": "iXsystems",
|
||||
"organizational_unit": "",
|
||||
"parsed": true,
|
||||
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
|
||||
"privatekey_path": "/etc/certificates/freenas_default.key",
|
||||
"revoked": false,
|
||||
"revoked_date": "",
|
||||
"root_path": "/etc/certificates",
|
||||
"san": [
|
||||
"DNS:localhost"
|
||||
],
|
||||
"serial": 1,
|
||||
"signedby": "",
|
||||
"state": "Tennessee",
|
||||
"subject_name_hash": 3193428416,
|
||||
"type": 8,
|
||||
"until": "Thu Dec 29 15:05:38 2022"
|
||||
},
|
||||
"1": {
|
||||
"CA_type_existing": false,
|
||||
"CA_type_intermediate": false,
|
||||
"CA_type_internal": false,
|
||||
"CSR": "",
|
||||
"DN": "/C=US/O=iXsystems/CN=localhost/emailAddress=info@ixsystems.com/ST=Tennessee/L=Maryville/subjectAltName=DNS:localhost",
|
||||
"cert_type": "CERTIFICATE",
|
||||
"cert_type_CSR": false,
|
||||
"cert_type_existing": true,
|
||||
"cert_type_internal": false,
|
||||
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n",
|
||||
"certificate_path": "/etc/certificates/freenas_default.crt",
|
||||
"chain": false,
|
||||
"chain_list": [
|
||||
"-----BEGIN CERTIFICATE-----\nMIIDqjCCApKgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx\nEjAQBgNVBAoMCWlYc3lzdGVtczESMBAGA1UEAwwJbG9jYWxob3N0MSEwHwYJKoZI\nhvcNAQkBFhJpbmZvQGl4c3lzdGVtcy5jb20xEjAQBgNVBAgMCVRlbm5lc3NlZTES\nMBAGA1UEBwwJTWFyeXZpbGxlMB4XDTIwMDkyNTE0MDUzOFoXDTIyMTIyOTE0MDUz\nOFowgYAxCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlpWHN5c3RlbXMxEjAQBgNVBAMM\nCWxvY2FsaG9zdDEhMB8GCSqGSIb3DQEJARYSaW5mb0BpeHN5c3RlbXMuY29tMRIw\nEAYDVQQIDAlUZW5uZXNzZWUxEjAQBgNVBAcMCU1hcnl2aWxsZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBALpoGliii6X8DeoFdLcR7jjsfJIn3nC8f1pT\nLQ3RURHUOEyhPT3Z6TkhaHeHoj8D6kiXROhyJJq3kw5OeqGZisfpGQhkxjpxkfh9\nfAhlvhuLwCWHaMvSh1TaT+h9+eHfcx3un5CIaH8b1KYRBMH+jmKFpr7jkPNkBXLS\nMA7jKIIa8pD9R6lF4gAsbqJafCbT3R7bqkd9xp3n3j2YhqQzETU2lmu4fra3BPio\nofK47kSkguUC6mtk6VrDf2+QtCKlY0dtbF3e2ZBNWo1aj86sjCtoEmqOCMsPRLc/\nXwQcfEqHY4XfafXwqk0G0UxV2ce18xKoR/pN3MpLBZ65NzPnpn0CAwEAAaMtMCsw\nFAYDVR0RBA0wC4IJbG9jYWxob3N0MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqG\nSIb3DQEBCwUAA4IBAQBFW1R037y7wllg/gRk9p2T1stiG8iIXosblmL4Ak1YToTQ\n/0to5GY2ZYW29+rbA4SDTS5eeu2YqZ0A/fF3wey7ggzMS7KyNBOvx5QBJRw3PJGn\n+THfhXvdfkOyeUC6KWRGLgl+/zBFvgh6vFDq3jmv0NI4ehVBTBMCJn7r6577S16T\nwtgKMCooizII0Odu5HIF10gTieFIH3PQYm9JBji9iyemb9Ht3wn7fXQptfGadz/l\nWz/Dv9+a6IOr7JVJMHnqAIvPzpkav4efuVPOX1zbhjg4K5g+nRYfjr5F5upOd0Y3\nznWTUBUyI7CXRkpHtSDXfEqKgnk/8uv7GWw+hyKr\n-----END CERTIFICATE-----\n"
|
||||
],
|
||||
"city": "Maryville",
|
||||
"common": "localhost",
|
||||
"country": "US",
|
||||
"csr_path": "/etc/certificates/freenas_default.csr",
|
||||
"digest_algorithm": "SHA256",
|
||||
"email": "info@ixsystems.com",
|
||||
"extensions": {
|
||||
"ExtendedKeyUsage": "TLS Web Server Authentication",
|
||||
"SubjectAltName": "DNS:localhost"
|
||||
},
|
||||
"fingerprint": "9C:5A:1D:1B:E7:9E:0B:89:2B:37:F4:19:83:ED:3C:6B:D8:14:0D:9B",
|
||||
"from": "Fri Sep 25 16:05:38 2020",
|
||||
"id": 1,
|
||||
"internal": "NO",
|
||||
"issuer": "external",
|
||||
"key_length": 2048,
|
||||
"key_type": "RSA",
|
||||
"lifetime": 825,
|
||||
"name": "freenas_default",
|
||||
"organization": "iXsystems",
|
||||
"organizational_unit": "",
|
||||
"parsed": true,
|
||||
"privatekey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC6aBpYooul/A3q\nBXS3Ee447HySJ95wvH9aUy0N0VER1DhMoT092ek5IWh3h6I/A+pIl0TociSat5MO\nTnqhmYrH6RkIZMY6cZH4fXwIZb4bi8Alh2jL0odU2k/offnh33Md7p+QiGh/G9Sm\nEQTB/o5ihaa+45DzZAVy0jAO4yiCGvKQ/UepReIALG6iWnwm090e26pHfcad5949\nmIakMxE1NpZruH62twT4qKHyuO5EpILlAuprZOlaw39vkLQipWNHbWxd3tmQTVqN\nWo/OrIwraBJqjgjLD0S3P18EHHxKh2OF32n18KpNBtFMVdnHtfMSqEf6TdzKSwWe\nuTcz56Z9AgMBAAECggEARwcb4uIs7BZbBu0FSCyg5TfXT6m5bKOmszg2VqmHho+i\n1DAsMcEyyP4d3E3mWLSZNQfOzfOQVxPUCQOGXsUuyHXdgAFGN0bHJDRMara59a0O\njj5GhEO4JXD6OdCmwpZuOt2OF3iiuKxWHuElOvZQMuJSYzI7LULTgKjufv23lbsf\nxMO/v9yi57c5EGgnQ8siLKOy/FQZapn4Z9qKn+lVyk5gfaKP0pDsvV4d7nGYMDD2\nYijfkSyNecApFdtWiLE5zLUlvF6oNj8o66z3YrVNKrCPzhA/5Rkkwwk32SNxvKU3\nVZFSNPeOZ60BicxYcWO+b2aAa0WF+uazJAZ4q52gUQKBgQDu88R+0wm76secYkzE\nQglteLNZKFcvth0kI5xH42Hmk9IXkGimFoDJCIrLAuopyGnfNmqmh2is3QUMUPdR\n/wDLnKc4MCezEidNoD2RBC+bzM1hB9oye/b5sOZUDFXSa0k4XSLu1UEuy1yWhkuS\n6JjY1KQfc4FN0K0Fjqqo7UCTCwKBgQDHtKQh/NvMJ2ok4YW+/QAsus4mEK9eCyUy\nOuyDszQYrGvjkS7STKJVNxGLhWb0XKSIAxMZ66b1MwOt+71h7xNn6pcancfVdK7F\n1Xl5J+76SwbXSgQwTZuoMDxPIvZn7v/2ep5Ni/BcOhMcPIcobWb/OmXrFN1brBvo\nlFNQyWWhlwKBgFDAyPMjVvLO0U6kWdUpjA4W8GV9IJnbLdX8wt/4lClcY2/bOcKH\ncFaAMIeTIJemR0FMHpbQxCtHNmGHK03mo9orwsdWXtRBmk69jJDpnT1F5VKZWMAe\n7MRNaEmXMZm+8CvALgIQx8qMp2mnUPsA6Ea+9gg6/MPTdeWe5UXZiC0pAoGAGtSt\nPJfBXBNrklruYjORo3DRo5GYThVHQRFjl2orNKltsVxfIwgCw1ortEgPBgOwY0mu\ndkwP2V+qPeTVk+PQAqUk+gF6yLXtiUzeDiYMWHpeB+y81VSH9jfM0oELA/m7T/03\naYnEmE+BI8kKC6dvMBlDeisKdneQJFZRP0hfrC8CgYEAgYIyCGwcydKpe2Nkj0Fz\nKTtCMC/k4DvJfd5Kb9AbmrPUfKgA9Xj4GT6yPG6uBMi8r5etvLCKJ2x2NtN024a8\nQJLATYPrSsaZkE+9zM0j5nYAgbKpxBhlDzDAzn//3ByVzfgJ25S80XhTI2lfbLH/\nU07ssxdZaQCo+WuD82OvNcg=\n-----END PRIVATE KEY-----\n",
|
||||
"privatekey_path": "/etc/certificates/freenas_default.key",
|
||||
"revoked": false,
|
||||
"revoked_date": "",
|
||||
"root_path": "/etc/certificates",
|
||||
"san": [
|
||||
"DNS:localhost"
|
||||
],
|
||||
"serial": 1,
|
||||
"signedby": "",
|
||||
"state": "Tennessee",
|
||||
"subject_name_hash": 3193428416,
|
||||
"type": 8,
|
||||
"until": "Thu Dec 29 15:05:38 2022"
|
||||
}
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
hosts: [ 'hostname1' ],
|
||||
scaleCert: 1
|
||||
},
|
||||
{
|
||||
hosts: [ 'hostname2' ],
|
||||
scaleCert: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
refute_nil(resource('Secret'))
|
||||
secret1 = chart.resources(kind: "Secret").first
|
||||
assert_equal("common-test-main-tls-0-ixcert-1", secret1["metadata"]["name"])
|
||||
refute_nil(secret1["data"]["tls.crt"])
|
||||
refute_nil(secret1["data"]["tls.key"])
|
||||
secret2 = chart.resources(kind: "Secret").find{ |s| s["metadata"]["name"] == "common-test-main-tls-1-ixcert-2" }
|
||||
refute_nil(secret2)
|
||||
refute_nil(secret2["data"]["tls.crt"])
|
||||
refute_nil(secret2["data"]["tls.key"])
|
||||
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal("common-test-main-tls-0-ixcert-1", ingress["spec"]["tls"][0]["secretName"])
|
||||
assert_equal("common-test-main-tls-1-ixcert-2", ingress["spec"]["tls"][1]["secretName"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,90 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'container::resources' do
|
||||
it 'no resources added by default' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{}}, mainContainer["resources"])
|
||||
end
|
||||
it 'resources can be added' do
|
||||
values = {
|
||||
resources: {
|
||||
testresourcename: "testresourcevalue"
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{}, "testresourcename"=>"testresourcevalue"}, mainContainer["resources"])
|
||||
end
|
||||
it 'resources.limits can be added' do
|
||||
values = {
|
||||
resources: {
|
||||
limits: {
|
||||
testlimitkey: "testlimitvalue"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{"testlimitkey"=>"testlimitvalue"}}, mainContainer["resources"])
|
||||
end
|
||||
it 'resources and resources.limits can both be added' do
|
||||
values = {
|
||||
resources: {
|
||||
testresourcekey: "testresourcevalue",
|
||||
limits: {
|
||||
testlimitkey: "testlimitvalue"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{"testlimitkey"=>"testlimitvalue"}, "testresourcekey"=>"testresourcevalue"}, mainContainer["resources"])
|
||||
end
|
||||
end
|
||||
describe 'container::resources-scaleGPU' do
|
||||
it 'scaleGPU can be set' do
|
||||
values = {
|
||||
scaleGPU: {
|
||||
intelblabla: 1
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{"intelblabla"=>1}}, mainContainer["resources"])
|
||||
end
|
||||
it 'scaleGPU can be combined with resources and resource values' do
|
||||
values = {
|
||||
resources: {
|
||||
testresourcekey: "testresourcevalue",
|
||||
limits: {
|
||||
testlimitkey: "testlimitvalue"
|
||||
}
|
||||
},
|
||||
scaleGPU: {
|
||||
intelblabla: 1
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal({"limits"=>{"intelblabla"=>1, "testlimitkey"=>"testlimitvalue"}, "testresourcekey"=>"testresourcevalue"}, mainContainer["resources"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,380 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'container::command' do
|
||||
it 'defaults to nil' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_nil(mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'accepts a single string' do
|
||||
values = {
|
||||
command: "/bin/sh"
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:command], mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'accepts a list of strings' do
|
||||
values = {
|
||||
command: [
|
||||
"/bin/sh",
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:command], mainContainer["command"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'container::arguments' do
|
||||
it 'defaults to nil' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_nil(mainContainer["args"])
|
||||
end
|
||||
|
||||
it 'accepts a single string' do
|
||||
values = {
|
||||
args: "sleep infinity"
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:args], mainContainer["args"])
|
||||
end
|
||||
|
||||
it 'accepts a list of strings' do
|
||||
values = {
|
||||
args: [
|
||||
"sleep",
|
||||
"infinity"
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:args], mainContainer["args"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'container::environment settings' do
|
||||
it 'Check no environment variables' do
|
||||
values = {}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_nil(mainContainer["env"])
|
||||
end
|
||||
|
||||
it 'set "static" environment variables' do
|
||||
values = {
|
||||
env: {
|
||||
STATIC_ENV: 'value_of_env',
|
||||
TRUTHY_ENV: '0',
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal(values[:env].values[0].to_s, mainContainer["env"][0]["value"])
|
||||
assert_equal(values[:env].keys[1].to_s, mainContainer["env"][1]["name"])
|
||||
assert_equal(values[:env].values[1].to_s, mainContainer["env"][1]["value"])
|
||||
end
|
||||
|
||||
it 'set "list" of "static" environment variables' do
|
||||
values = {
|
||||
envList: [
|
||||
{
|
||||
name: 'STATIC_ENV_FROM_LIST',
|
||||
value: 'STATIC_ENV_VALUE_FROM_LIST'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:envList][0][:name].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal(values[:envList][0][:value].to_s, mainContainer["env"][0]["value"])
|
||||
end
|
||||
|
||||
it 'set both "list" AND "dict" of "static" environment variables' do
|
||||
values = {
|
||||
env: {
|
||||
STATIC_ENV: 'value_of_env'
|
||||
},
|
||||
envList: [
|
||||
{
|
||||
name: 'STATIC_ENV_FROM_LIST',
|
||||
value: 'STATIC_ENV_VALUE_FROM_LIST'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:envList][0][:name].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal(values[:envList][0][:value].to_s, mainContainer["env"][0]["value"])
|
||||
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][1]["name"])
|
||||
assert_equal(values[:env].values[0].to_s, mainContainer["env"][1]["value"])
|
||||
end
|
||||
|
||||
it 'set "valueFrom" environment variables' do
|
||||
values = {
|
||||
envValueFrom: {
|
||||
NODE_NAME: {
|
||||
fieldRef: {
|
||||
fieldPath: "spec.nodeName"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:envValueFrom].keys[0].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal(values[:envValueFrom].values[0][:fieldRef][:fieldPath], mainContainer["env"][0]["valueFrom"]["fieldRef"]["fieldPath"])
|
||||
end
|
||||
|
||||
it 'set "static" and "Dynamic/Tpl" environment variables' do
|
||||
values = {
|
||||
env: {
|
||||
STATIC_ENV: 'value_of_env'
|
||||
},
|
||||
envTpl: {
|
||||
DYN_ENV: "{{ .Release.Name }}-admin"
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:env].keys[0].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal(values[:env].values[0].to_s, mainContainer["env"][0]["value"])
|
||||
assert_equal(values[:envTpl].keys[0].to_s, mainContainer["env"][1]["name"])
|
||||
assert_equal("common-test-admin", mainContainer["env"][1]["value"])
|
||||
end
|
||||
|
||||
it 'set "Dynamic/Tpl" environment variables' do
|
||||
values = {
|
||||
envTpl: {
|
||||
DYN_ENV: "{{ .Release.Name }}-admin"
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:envTpl].keys[0].to_s, mainContainer["env"][0]["name"])
|
||||
assert_equal("common-test-admin", mainContainer["env"][0]["value"])
|
||||
end
|
||||
|
||||
it 'set "static" secret variables' do
|
||||
expectedSecretName = 'common-test'
|
||||
values = {
|
||||
secret: {
|
||||
STATIC_SECRET: 'value_of_secret'
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
secret = chart.resources(kind: "Secret").find{ |s| s["metadata"]["name"] == expectedSecretName }
|
||||
refute_nil(secret)
|
||||
assert_equal(values[:secret].values[0].to_s, secret["stringData"]["STATIC_SECRET"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(expectedSecretName, mainContainer["envFrom"][0]["secretRef"]["name"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'container::persistence' do
|
||||
it 'supports multiple volumeMounts' do
|
||||
values = {
|
||||
persistence: {
|
||||
cache: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
config: {
|
||||
enabled: true,
|
||||
existingClaim: "configClaim"
|
||||
},
|
||||
data: {
|
||||
enabled: true,
|
||||
existingClaim: "dataClaim"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
# Check that all persistent volumes have mounts
|
||||
values[:persistence].each { |key, value|
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == key.to_s }
|
||||
refute_nil(volumeMount)
|
||||
}
|
||||
end
|
||||
|
||||
it 'defaults mountPath to persistence key' do
|
||||
values = {
|
||||
persistence: {
|
||||
data: {
|
||||
enabled: true,
|
||||
existingClaim: "dataClaim"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("/data", volumeMount["mountPath"])
|
||||
end
|
||||
|
||||
it 'supports setting custom mountPath' do
|
||||
values = {
|
||||
persistence: {
|
||||
data: {
|
||||
enabled: true,
|
||||
existingClaim: "dataClaim",
|
||||
mountPath: "/myMountPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("/myMountPath", volumeMount["mountPath"])
|
||||
end
|
||||
|
||||
it 'supports setting subPath' do
|
||||
values = {
|
||||
persistence: {
|
||||
data: {
|
||||
enabled: true,
|
||||
existingClaim: "dataClaim",
|
||||
subPath: "mySubPath"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("mySubPath", volumeMount["subPath"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'container::hostPathMounts' do
|
||||
it 'supports multiple hostPathMounts' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
# Check that all hostPathMounts volumes have mounts
|
||||
values[:hostPathMounts].each { |value|
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-" + value[:name].to_s }
|
||||
refute_nil(volumeMount)
|
||||
}
|
||||
end
|
||||
|
||||
it 'supports setting mountPath' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("/data", volumeMount["mountPath"])
|
||||
end
|
||||
|
||||
it 'supports setting subPath' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp",
|
||||
subPath: "mySubPath"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("mySubPath", volumeMount["subPath"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,60 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'controller::type' do
|
||||
it 'defaults to "Deployment"' do
|
||||
assert_nil(resource('StatefulSet'))
|
||||
assert_nil(resource('DaemonSet'))
|
||||
refute_nil(resource('Deployment'))
|
||||
end
|
||||
|
||||
it 'accepts "statefulset"' do
|
||||
chart.value controllerType: 'statefulset'
|
||||
assert_nil(resource('Deployment'))
|
||||
assert_nil(resource('DaemonSet'))
|
||||
refute_nil(resource('StatefulSet'))
|
||||
end
|
||||
|
||||
it 'accepts "daemonset"' do
|
||||
chart.value controllerType: 'daemonset'
|
||||
assert_nil(resource('Deployment'))
|
||||
assert_nil(resource('StatefulSet'))
|
||||
refute_nil(resource('DaemonSet'))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'controller::statefulset::volumeClaimTemplates' do
|
||||
it 'volumeClaimTemplates should be empty by default' do
|
||||
chart.value controllerType: 'statefulset'
|
||||
statefulset = chart.resources(kind: "StatefulSet").first
|
||||
assert_nil(statefulset['spec']['volumeClaimTemplates'])
|
||||
end
|
||||
|
||||
it 'can set values for volumeClaimTemplates' do
|
||||
values = {
|
||||
controllerType: 'statefulset',
|
||||
volumeClaimTemplates: [
|
||||
{
|
||||
name: 'storage',
|
||||
accessMode: 'ReadWriteOnce',
|
||||
size: '10Gi',
|
||||
storageClass: 'storage'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
chart.value values
|
||||
statefulset = chart.resources(kind: "StatefulSet").first
|
||||
volumeClaimTemplate = statefulset["spec"]["volumeClaimTemplates"].find{ |v| v["metadata"]["name"] == values[:volumeClaimTemplates][0][:name]}
|
||||
refute_nil(volumeClaimTemplate)
|
||||
assert_equal(values[:volumeClaimTemplates][0][:accessMode], volumeClaimTemplate["spec"]["accessModes"][0])
|
||||
assert_equal(values[:volumeClaimTemplates][0][:size], volumeClaimTemplate["spec"]["resources"]["requests"]["storage"])
|
||||
assert_equal(values[:volumeClaimTemplates][0][:storageClass], volumeClaimTemplate["spec"]["storageClassName"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,120 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
|
||||
describe 'hpa::defaults' do
|
||||
it 'does not exist by default' do
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_nil(hpa)
|
||||
end
|
||||
|
||||
it 'can be enabled' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
refute_nil(hpa)
|
||||
end
|
||||
|
||||
it 'default target is common.names.fullname ' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal("common-test",hpa["spec"]["scaleTargetRef"]["name"])
|
||||
end
|
||||
|
||||
it 'default numer of replicas is min 1 max 3' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal(1,hpa["spec"]["minReplicas"])
|
||||
assert_equal(3,hpa["spec"]["maxReplicas"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'hpa::customsettings' do
|
||||
it 'can override target' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true,
|
||||
target: "targetname"
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal(values[:autoscaling][:target],hpa["spec"]["scaleTargetRef"]["name"])
|
||||
end
|
||||
|
||||
it 'can change min and max replicas' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true,
|
||||
minReplicas: 4,
|
||||
maxReplicas: 8
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal(values[:autoscaling][:minReplicas],hpa["spec"]["minReplicas"])
|
||||
assert_equal(values[:autoscaling][:maxReplicas],hpa["spec"]["maxReplicas"])
|
||||
end
|
||||
|
||||
it 'can set targetCPUUtilizationPercentage' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true,
|
||||
targetCPUUtilizationPercentage: 60
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal("cpu",hpa["spec"]["metrics"][0]["resource"]["name"])
|
||||
assert_equal(values[:autoscaling][:targetCPUUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
|
||||
end
|
||||
|
||||
it 'can set targetMemoryUtilizationPercentage' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true,
|
||||
targetMemoryUtilizationPercentage: 70
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal("memory",hpa["spec"]["metrics"][0]["resource"]["name"])
|
||||
assert_equal(values[:autoscaling][:targetMemoryUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
|
||||
end
|
||||
|
||||
it 'can set both targetCPU and targetMemoryUtilizationPercentage' do
|
||||
values = {
|
||||
autoscaling: {
|
||||
enabled: true,
|
||||
targetCPUUtilizationPercentage: 60,
|
||||
targetMemoryUtilizationPercentage: 70
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
hpa = chart.resources(kind: "HorizontalPodAutoscaler").first
|
||||
assert_equal("cpu",hpa["spec"]["metrics"][0]["resource"]["name"])
|
||||
assert_equal(values[:autoscaling][:targetCPUUtilizationPercentage],hpa["spec"]["metrics"][0]["resource"]["targetAverageUtilization"])
|
||||
assert_equal("memory",hpa["spec"]["metrics"][1]["resource"]["name"])
|
||||
assert_equal(values[:autoscaling][:targetMemoryUtilizationPercentage],hpa["spec"]["metrics"][1]["resource"]["targetAverageUtilization"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,281 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'ingress' do
|
||||
it 'disabled when ingress.main.enabled: false' do
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
assert_nil(resource('Ingress'))
|
||||
end
|
||||
|
||||
it 'enabled when ingress.main.enabled: true' do
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
refute_nil(resource('Ingress'))
|
||||
end
|
||||
|
||||
it 'tls can be provided' do
|
||||
expectedPath = 'common-test.path'
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
hosts: [ 'hostname' ],
|
||||
secretName: 'secret-name'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal(values[:ingress][:main][:tls][0][:hosts][0], ingress["spec"]["tls"][0]["hosts"][0])
|
||||
assert_equal(values[:ingress][:main][:tls][0][:secretName], ingress["spec"]["tls"][0]["secretName"])
|
||||
end
|
||||
|
||||
it 'tls secret can be left empty' do
|
||||
expectedPath = 'common-test.path'
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
hosts: [ 'hostname' ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal(values[:ingress][:main][:tls][0][:hosts][0], ingress["spec"]["tls"][0]["hosts"][0])
|
||||
assert_equal(false, ingress["spec"]["tls"][0].key?("secretName"))
|
||||
assert_nil(ingress["spec"]["tls"][0]["secretName"])
|
||||
end
|
||||
|
||||
it 'tls secret template can be provided' do
|
||||
expectedPath = 'common-test.path'
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
tls: [
|
||||
{
|
||||
secretNameTpl: '{{ .Release.Name }}-secret'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal('common-test-secret', ingress["spec"]["tls"][0]["secretName"])
|
||||
end
|
||||
|
||||
it 'path template can be provided' do
|
||||
expectedPath = 'common-test.path'
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
pathTpl: '{{ .Release.Name }}.path'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal(expectedPath, ingress["spec"]["rules"][0]["http"]["paths"][0]["path"])
|
||||
end
|
||||
|
||||
it 'hosts can be provided' do
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
host: 'hostname'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal(values[:ingress][:main][:hosts][0][:host], ingress["spec"]["rules"][0]["host"])
|
||||
end
|
||||
|
||||
it 'hosts template can be provided' do
|
||||
expectedHostName = 'common-test.hostname'
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
hostTpl: '{{ .Release.Name }}.hostname'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
refute_nil(ingress)
|
||||
assert_equal(expectedHostName, ingress["spec"]["rules"][0]["host"])
|
||||
end
|
||||
|
||||
it 'custom service name / port can optionally be set on path level' do
|
||||
values = {
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
path: '/second',
|
||||
serviceName: 'pathService',
|
||||
servicePort: 1234
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chart.value values
|
||||
ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-main" }
|
||||
firstPath = ingress["spec"]["rules"][0]["http"]["paths"][0]
|
||||
secondPath = ingress["spec"]["rules"][0]["http"]["paths"][1]
|
||||
assert_equal("common-test", firstPath["backend"]["service"]["name"])
|
||||
assert_equal(8080, firstPath["backend"]["service"]["port"]["number"])
|
||||
assert_equal("pathService", secondPath["backend"]["service"]["name"])
|
||||
assert_equal(1234, secondPath["backend"]["service"]["port"]["number"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'additionalIngress' do
|
||||
ingressValues = {
|
||||
ingress: {
|
||||
extra: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
path: '/'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it 'can be specified' do
|
||||
values = ingressValues
|
||||
chart.value values
|
||||
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
|
||||
refute_nil(additionalIngress)
|
||||
end
|
||||
|
||||
it 'refers to main Service by default' do
|
||||
values = ingressValues
|
||||
chart.value values
|
||||
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
|
||||
assert_equal("common-test", additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["name"])
|
||||
assert_equal(8080, additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["port"]["number"])
|
||||
end
|
||||
|
||||
it 'custom service name / port can be set on Ingress level' do
|
||||
values = ingressValues.deep_merge_override({
|
||||
ingress: {
|
||||
extra: {
|
||||
serviceName: "customService",
|
||||
servicePort: 8081
|
||||
}
|
||||
}
|
||||
})
|
||||
chart.value values
|
||||
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
|
||||
assert_equal("customService", additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["name"])
|
||||
assert_equal(8081, additionalIngress["spec"]["rules"][0]["http"]["paths"][0]["backend"]["service"]["port"]["number"])
|
||||
end
|
||||
|
||||
it 'custom service name / port can optionally be set on path level' do
|
||||
values = ingressValues.deep_merge_override({
|
||||
ingress: {
|
||||
extra: {
|
||||
hosts: [
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
path: '/'
|
||||
},
|
||||
{
|
||||
path: '/second',
|
||||
serviceName: 'pathService',
|
||||
servicePort: 1234
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
chart.value values
|
||||
additionalIngress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-extra" }
|
||||
firstPath = additionalIngress["spec"]["rules"][0]["http"]["paths"][0]
|
||||
secondPath = additionalIngress["spec"]["rules"][0]["http"]["paths"][1]
|
||||
assert_equal("common-test", firstPath["backend"]["service"]["name"])
|
||||
assert_equal(8080, firstPath["backend"]["service"]["port"]["number"])
|
||||
assert_equal("pathService", secondPath["backend"]["service"]["name"])
|
||||
assert_equal(1234, secondPath["backend"]["service"]["port"]["number"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,347 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'job::permissions' do
|
||||
it 'no job exists by default' do
|
||||
job = chart.resources(kind: "Job").first
|
||||
assert_nil(job)
|
||||
end
|
||||
|
||||
it 'hostPathMounts do not affect permissions job by default' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
assert_nil(job["spec"]["template"]["spec"]["volumes"])
|
||||
assert_nil(job["spec"]["template"]["spec"]["containers"][0]["volumeMounts"])
|
||||
end
|
||||
it 'hostPathMounts.setPermissions adds volume(mounts)' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
assert_equal("hostpathmounts-data", job["spec"]["template"]["spec"]["volumes"][0]["name"])
|
||||
assert_equal("hostpathmounts-data", job["spec"]["template"]["spec"]["containers"][0]["volumeMounts"][0]["name"])
|
||||
end
|
||||
it 'supports multiple hostPathMounts' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
|
||||
# Check that all hostPathMounts volumes have mounts
|
||||
values[:hostPathMounts].each { |value|
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-" + value[:name].to_s }
|
||||
refute_nil(volumeMount)
|
||||
}
|
||||
end
|
||||
|
||||
it 'supports setting mountPath' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
|
||||
volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == "hostpathmounts-data" }
|
||||
refute_nil(volumeMount)
|
||||
assert_equal("/data", volumeMount["mountPath"])
|
||||
end
|
||||
|
||||
it 'could mount multiple volumes' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
volumes = job["spec"]["template"]["spec"]["volumes"]
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
|
||||
refute_nil(volume)
|
||||
assert_equal('/tmp1', volume["hostPath"]["path"])
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('/tmp2', volume["hostPath"]["path"])
|
||||
end
|
||||
|
||||
it 'emptyDir can be enabled' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
emptyDir: true,
|
||||
mountPath: "/data"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
volumes = job["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
|
||||
refute_nil(volume)
|
||||
assert_equal(Hash.new, volume["emptyDir"])
|
||||
end
|
||||
|
||||
it 'can process default (568:568) permissions for multiple volumes' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 568:568 /data
|
||||
chown -R 568:568 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'outputs default permissions with irrelevant podSecurityContext' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 568:568 /data
|
||||
chown -R 568:568 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
podSecurityContext: {
|
||||
allowPrivilegeEscalation: false
|
||||
},
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'outputs fsgroup permissions for multiple volumes when set' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 568:666 /data
|
||||
chown -R 568:666 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
podSecurityContext: {
|
||||
fsGroup: 666
|
||||
},
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'outputs runAsUser permissions for multiple volumes when set' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 999:568 /data
|
||||
chown -R 999:568 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
podSecurityContext: {
|
||||
runAsUser: 999
|
||||
},
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
|
||||
it 'outputs fsGroup AND runAsUser permissions for multiple volumes when both are set' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 999:666 /data
|
||||
chown -R 999:666 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
podSecurityContext: {
|
||||
fsGroup: 666,
|
||||
runAsUser: 999
|
||||
},
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
it 'outputs PUID AND PGID permissions for multiple volumes when both are set' do
|
||||
results= {
|
||||
command: ["/bin/sh", "-c", "chown -R 999:666 /data
|
||||
chown -R 999:666 /config
|
||||
"]
|
||||
}
|
||||
values = {
|
||||
env: {
|
||||
PGID: 666,
|
||||
PUID: 999
|
||||
},
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
setPermissions: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
job = chart.resources(kind: "Job").first
|
||||
mainContainer = job["spec"]["template"]["spec"]["containers"][0]
|
||||
assert_equal(results[:command], mainContainer["command"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,316 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'pod::replicas' do
|
||||
it 'defaults to 1' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal(1, deployment["spec"]["replicas"])
|
||||
end
|
||||
|
||||
it 'accepts integer as value' do
|
||||
chart.value replicas: 3
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal(3, deployment["spec"]["replicas"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::hostNetwork' do
|
||||
it 'defaults to nil' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_nil(deployment["spec"]["template"]["spec"]["hostNetwork"])
|
||||
end
|
||||
|
||||
it 'can be enabled' do
|
||||
values = {
|
||||
hostNetwork: true
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal(true, deployment["spec"]["template"]["spec"]["hostNetwork"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::dnsPolicy' do
|
||||
it 'defaults to "ClusterFirst" without hostNetwork' do
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal("ClusterFirst", deployment["spec"]["template"]["spec"]["dnsPolicy"])
|
||||
end
|
||||
|
||||
it 'defaults to "ClusterFirst" when hostNetwork: false' do
|
||||
values = {
|
||||
hostNetwork: false
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal("ClusterFirst", deployment["spec"]["template"]["spec"]["dnsPolicy"])
|
||||
end
|
||||
|
||||
it 'defaults to "ClusterFirstWithHostNet" when hostNetwork: true' do
|
||||
values = {
|
||||
hostNetwork: true
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal("ClusterFirstWithHostNet", deployment["spec"]["template"]["spec"]["dnsPolicy"])
|
||||
end
|
||||
|
||||
it 'accepts manual override' do
|
||||
values = {
|
||||
dnsPolicy: "None"
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
assert_equal("None", deployment["spec"]["template"]["spec"]["dnsPolicy"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::additional containers' do
|
||||
it 'accepts static additionalContainers' do
|
||||
values = {
|
||||
additionalContainers: [
|
||||
{
|
||||
name: "template-test"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
additionalContainer = containers.find{ |c| c["name"] == values[:additionalContainers][0][:name] }
|
||||
refute_nil(additionalContainer)
|
||||
end
|
||||
|
||||
it 'accepts "Dynamic/Tpl" additionalContainers' do
|
||||
expectedContainerName = "common-test-container"
|
||||
values = {
|
||||
additionalContainers: [
|
||||
{
|
||||
name: "{{ .Release.Name }}-container",
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
additionalContainer = containers.find{ |c| c["name"] == expectedContainerName }
|
||||
refute_nil(additionalContainer)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::persistence' do
|
||||
it 'multiple volumes' do
|
||||
values = {
|
||||
persistence: {
|
||||
cache: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
config: {
|
||||
enabled: true,
|
||||
existingClaim: "configClaim",
|
||||
emptyDir: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
data: {
|
||||
enabled: true,
|
||||
existingClaim: "dataClaim"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "cache"}
|
||||
refute_nil(volume)
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('configClaim', volume["persistentVolumeClaim"]["claimName"])
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "data"}
|
||||
refute_nil(volume)
|
||||
assert_equal('dataClaim', volume["persistentVolumeClaim"]["claimName"])
|
||||
end
|
||||
|
||||
it 'default nameSuffix' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('common-test-config', volume["persistentVolumeClaim"]["claimName"])
|
||||
end
|
||||
|
||||
it 'custom nameSuffix' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
nameSuffix: "test",
|
||||
emptyDir: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('common-test-test', volume["persistentVolumeClaim"]["claimName"])
|
||||
end
|
||||
|
||||
it 'no nameSuffix' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
nameSuffix: "-",
|
||||
emptyDir: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('common-test', volume["persistentVolumeClaim"]["claimName"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::persistence::emptyDir' do
|
||||
it 'can be configured' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal(Hash.new, volume["emptyDir"])
|
||||
end
|
||||
|
||||
it 'medium can be configured' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: true,
|
||||
medium: "memory"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal("memory", volume["emptyDir"]["medium"])
|
||||
end
|
||||
|
||||
it 'sizeLimit can be configured' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
emptyDir: {
|
||||
enabled: true,
|
||||
medium: "memory",
|
||||
sizeLimit: "1Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "config"}
|
||||
refute_nil(volume)
|
||||
assert_equal("1Gi", volume["emptyDir"]["sizeLimit"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'pod::hostPathMounts' do
|
||||
it 'multiple volumes' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
mountPath: "/data",
|
||||
hostPath: "/tmp1"
|
||||
},
|
||||
{
|
||||
name: "config",
|
||||
enabled: true,
|
||||
mountPath: "/config",
|
||||
hostPath: "/tmp2"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
|
||||
refute_nil(volume)
|
||||
assert_equal('/tmp1', volume["hostPath"]["path"])
|
||||
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-config"}
|
||||
refute_nil(volume)
|
||||
assert_equal('/tmp2', volume["hostPath"]["path"])
|
||||
end
|
||||
|
||||
it 'emptyDir can be enabled' do
|
||||
values = {
|
||||
hostPathMounts: [
|
||||
{
|
||||
name: "data",
|
||||
enabled: true,
|
||||
emptyDir: true,
|
||||
mountPath: "/data"
|
||||
}
|
||||
]
|
||||
}
|
||||
chart.value values
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
volumes = deployment["spec"]["template"]["spec"]["volumes"]
|
||||
volume = volumes.find{ |v| v["name"] == "hostpathmounts-data"}
|
||||
refute_nil(volume)
|
||||
assert_equal(Hash.new, volume["emptyDir"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,313 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'configmap::portal-defaults' do
|
||||
it 'no configmap exists by default' do
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_nil(configmap)
|
||||
end
|
||||
|
||||
it 'creates configmap whe enabled' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
refute_nil(configmap)
|
||||
end
|
||||
|
||||
it 'is named "portal"' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("portal", configmap["metadata"]["name"])
|
||||
end
|
||||
|
||||
it 'uses "$node_ip" by default' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("$node_ip", configmap["data"]["host"])
|
||||
end
|
||||
|
||||
it 'uses port "443" by default' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("443", configmap["data"]["port"])
|
||||
end
|
||||
|
||||
it 'uses protocol "https" by default' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("https", configmap["data"]["protocol"])
|
||||
end
|
||||
|
||||
it 'uses path "/" by default' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("/", configmap["data"]["path"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'configmap::portal-overrides' do
|
||||
it 'ingressPort can be overridden' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true,
|
||||
ingressPort: "666"
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal(values[:portal][:ingressPort], configmap["data"]["port"])
|
||||
end
|
||||
|
||||
it 'nodePort Host can be overridden' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true,
|
||||
host: "test.host"
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal(values[:portal][:host], configmap["data"]["host"])
|
||||
end
|
||||
|
||||
it 'path can be overridden' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true,
|
||||
path: "/path"
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal(values[:portal][:path], configmap["data"]["path"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'configmap::portal-nodePort' do
|
||||
it 'nodePort host defaults to "$node_ip"' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
services: {
|
||||
main: {
|
||||
type: "NodePort",
|
||||
port: {
|
||||
nodePort: 666
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("$node_ip", configmap["data"]["host"])
|
||||
end
|
||||
|
||||
it 'nodePort port defaults to the nodePort' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
services: {
|
||||
main: {
|
||||
type: "NodePort",
|
||||
port: {
|
||||
nodePort: 666
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("666", configmap["data"]["port"])
|
||||
end
|
||||
|
||||
it 'uses nodeport port protocol as protocol (HTTPS)' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
services: {
|
||||
main: {
|
||||
type: "NodePort",
|
||||
port: {
|
||||
nodePort: 666,
|
||||
protocol: "HTTPS"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal(values[:services][:main][:port][:protocol], configmap["data"]["protocol"])
|
||||
end
|
||||
|
||||
it 'uses nodeport port protocol as protocol (HTTP)' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
services: {
|
||||
main: {
|
||||
type: "NodePort",
|
||||
port: {
|
||||
nodePort: 666,
|
||||
protocol: "HTTP"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal(values[:services][:main][:port][:protocol], configmap["data"]["protocol"])
|
||||
end
|
||||
end
|
||||
|
||||
describe 'configmap::portal-Ingress' do
|
||||
it 'uses ingress host' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
host: "test.domain",
|
||||
paths:
|
||||
[
|
||||
{
|
||||
path: "/test"
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("test.domain", configmap["data"]["host"])
|
||||
end
|
||||
|
||||
it 'uses ingress path' do
|
||||
values = {
|
||||
portal: {
|
||||
enabled: true
|
||||
},
|
||||
ingress: {
|
||||
main: {
|
||||
enabled: true,
|
||||
hosts: [
|
||||
{
|
||||
host: "test.domain",
|
||||
paths:
|
||||
[
|
||||
{
|
||||
path: "/test"
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
configmap = chart.resources(kind: "ConfigMap").first
|
||||
assert_equal("/test", configmap["data"]["path"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,110 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'pvc' do
|
||||
it 'nameSuffix defaults to persistence key' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
|
||||
refute_nil(pvc)
|
||||
end
|
||||
|
||||
it 'nameSuffix can be overridden' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
nameSuffix: 'customSuffix'
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-customSuffix" }
|
||||
refute_nil(pvc)
|
||||
end
|
||||
|
||||
it 'name can be overridden by nameOverride' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
nameOverride: 'customname'
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "customname" }
|
||||
refute_nil(pvc)
|
||||
end
|
||||
|
||||
it 'nameSuffix can be skipped' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
nameSuffix: '-'
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(pvc)
|
||||
end
|
||||
|
||||
it 'storageClass can be set' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
storageClass: "test"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
|
||||
refute_nil(pvc)
|
||||
assert_equal('test', pvc["spec"]["storageClassName"])
|
||||
end
|
||||
|
||||
it 'can generate TrueNAS SCALE zfs storageClass' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
storageClass: "SCALE-ZFS"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
|
||||
refute_nil(pvc)
|
||||
assert_equal('ix-storage-class-common-test', pvc["spec"]["storageClassName"])
|
||||
end
|
||||
|
||||
it 'storageClass can be set to an empty value' do
|
||||
values = {
|
||||
persistence: {
|
||||
config: {
|
||||
enabled: true,
|
||||
storageClass: "-"
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-config" }
|
||||
refute_nil(pvc)
|
||||
assert_equal('', pvc["spec"]["storageClassName"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,223 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
require_relative '../../test_helper'
|
||||
|
||||
class Test < ChartTest
|
||||
@@chart = Chart.new('charts/library/common-test')
|
||||
|
||||
describe @@chart.name do
|
||||
describe 'service::ports settings' do
|
||||
default_name = 'main'
|
||||
default_port = 8080
|
||||
|
||||
it 'defaults to name "servicename" on port 8080' do
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal(default_port, service["spec"]["ports"].first["port"])
|
||||
assert_equal(default_name, service["spec"]["ports"].first["targetPort"])
|
||||
assert_equal(default_name, service["spec"]["ports"].first["name"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(default_port, mainContainer["ports"].first["containerPort"])
|
||||
assert_equal(default_name, mainContainer["ports"].first["name"])
|
||||
end
|
||||
|
||||
it 'port name can be overridden' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
name: "server",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal(default_port, service["spec"]["ports"].first["port"])
|
||||
assert_equal(values[:services][:main][:port][:name], service["spec"]["ports"].first["targetPort"])
|
||||
assert_equal(values[:services][:main][:port][:name], service["spec"]["ports"].first["name"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(default_port, mainContainer["ports"].first["containerPort"])
|
||||
assert_equal(values[:services][:main][:port][:name], mainContainer["ports"].first["name"])
|
||||
end
|
||||
|
||||
it 'targetPort can be overridden' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
targetPort: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal(default_port, service["spec"]["ports"].first["port"])
|
||||
assert_equal(values[:services][:main][:port][:targetPort], service["spec"]["ports"].first["targetPort"])
|
||||
assert_equal(default_name, service["spec"]["ports"].first["name"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal(values[:services][:main][:port][:targetPort], mainContainer["ports"].first["containerPort"])
|
||||
assert_equal(default_name, mainContainer["ports"].first["name"])
|
||||
end
|
||||
|
||||
it 'targetPort cannot be a named port' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
targetPort: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
exception = assert_raises HelmCompileError do
|
||||
chart.execute_helm_template!
|
||||
end
|
||||
assert_match("Our charts do not support named ports for targetPort. (port name #{default_name}, targetPort #{values[:services][:main][:port][:targetPort]})", exception.message)
|
||||
end
|
||||
|
||||
it 'protocol defaults to TCP' do
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal("TCP", mainContainer["ports"].first["protocol"])
|
||||
end
|
||||
|
||||
it 'protocol is TCP when set to TCP explicitly' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: "TCP",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal("TCP", mainContainer["ports"].first["protocol"])
|
||||
end
|
||||
|
||||
it 'protocol is TCP when set to HTTP explicitly' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: "HTTP",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal("TCP", mainContainer["ports"].first["protocol"])
|
||||
end
|
||||
|
||||
it 'protocol is TCP when set to HTTPS explicitly' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: "HTTPS",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("TCP", service["spec"]["ports"].first["protocol"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal("TCP", mainContainer["ports"].first["protocol"])
|
||||
end
|
||||
|
||||
it 'protocol is UDP when set to UDP explicitly' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: "UDP",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("UDP", service["spec"]["ports"].first["protocol"])
|
||||
|
||||
deployment = chart.resources(kind: "Deployment").first
|
||||
containers = deployment["spec"]["template"]["spec"]["containers"]
|
||||
mainContainer = containers.find{ |c| c["name"] == "common-test" }
|
||||
assert_equal("UDP", mainContainer["ports"].first["protocol"])
|
||||
end
|
||||
|
||||
it 'No annotations get set by default' do
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_nil(service["metadata"]["annotations"])
|
||||
end
|
||||
it 'TCP port protocol does not set annotations' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: 'TCP'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_nil(service["metadata"]["annotations"])
|
||||
end
|
||||
it 'HTTPS port protocol sets traefik HTTPS annotation' do
|
||||
values = {
|
||||
services: {
|
||||
main: {
|
||||
port: {
|
||||
protocol: 'HTTPS'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chart.value values
|
||||
service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test" }
|
||||
refute_nil(service)
|
||||
assert_equal("https", service["metadata"]["annotations"]["traefik.ingress.kubernetes.io/service.serversscheme"])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,146 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'json'
|
||||
require 'yaml'
|
||||
require 'open3'
|
||||
|
||||
require 'minitest-implicit-subject'
|
||||
require "minitest/reporters"
|
||||
require 'minitest/autorun'
|
||||
require 'minitest/pride'
|
||||
|
||||
class HelmCompileError < StandardError
|
||||
end
|
||||
|
||||
class HelmDepsError < StandardError
|
||||
end
|
||||
|
||||
class Chart
|
||||
attr_reader :name, :path, :values
|
||||
|
||||
def initialize(chart)
|
||||
@name = chart.split('/').last
|
||||
|
||||
@path = File.expand_path(chart)
|
||||
|
||||
@values = default_values
|
||||
|
||||
update_deps!
|
||||
end
|
||||
|
||||
def update_deps!
|
||||
command = "helm dep update '#{path}'"
|
||||
stdout, stderr, status = Open3.capture3(command)
|
||||
raise HelmDepsError, stderr if status != 0
|
||||
end
|
||||
|
||||
def reset!
|
||||
@values = default_values
|
||||
@parsed_resources = nil
|
||||
end
|
||||
|
||||
def value(value)
|
||||
values.merge!(value)
|
||||
end
|
||||
|
||||
def configure_custom_name(name)
|
||||
@name = name
|
||||
end
|
||||
|
||||
def execute_helm_template!
|
||||
file = Tempfile.new(name)
|
||||
file.write(JSON.parse(values.to_json).to_yaml)
|
||||
file.close
|
||||
|
||||
begin
|
||||
command = "helm template '#{name}' '#{path}' --namespace='default' --values='#{file.path}'"
|
||||
stdout, stderr, status = Open3.capture3(command)
|
||||
|
||||
raise HelmCompileError, stderr if status != 0
|
||||
|
||||
stdout
|
||||
ensure
|
||||
file.unlink
|
||||
end
|
||||
end
|
||||
|
||||
def parsed_resources
|
||||
@parsed_resources ||= begin
|
||||
output = execute_helm_template!
|
||||
puts output if ENV.fetch('DEBUG', 'false') == 'true'
|
||||
YAML.load_stream(output)
|
||||
end
|
||||
end
|
||||
|
||||
def resources(matcher = nil)
|
||||
return parsed_resources unless matcher
|
||||
|
||||
parsed_resources.select do |r|
|
||||
r >= Hash[matcher.map { |k, v| [k.to_s, v] }]
|
||||
end
|
||||
end
|
||||
|
||||
def default_values
|
||||
{
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
class ExtendedMinitest < Minitest::Test
|
||||
extend MiniTest::Spec::DSL
|
||||
end
|
||||
|
||||
class ChartTest < ExtendedMinitest
|
||||
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
||||
|
||||
before do
|
||||
chart.reset!
|
||||
end
|
||||
|
||||
def chart
|
||||
self.class.class_variable_get('@@chart')
|
||||
end
|
||||
|
||||
def resource(name)
|
||||
chart.resources(kind: name).first
|
||||
end
|
||||
end
|
||||
|
||||
class Minitest::Result
|
||||
def name
|
||||
test_name = defined?(@name) ? @name : super
|
||||
test_name.to_s.gsub /\Atest_\d{4,}_/, ""
|
||||
end
|
||||
end
|
||||
|
||||
class ::Hash
|
||||
def deep_merge_override(second)
|
||||
merger = proc do |key, original, override|
|
||||
if original.instance_of?(Hash) && override.instance_of?(Hash)
|
||||
original.merge(override, &merger)
|
||||
else
|
||||
if original.instance_of?(Array) && override.instance_of?(Array)
|
||||
# if the lengths are different, prefer the override
|
||||
if original.length != override.length
|
||||
override
|
||||
else
|
||||
# if the first element in the override's Array is a Hash, then we assume they all are
|
||||
if override[0].instance_of?(Hash)
|
||||
original.map.with_index do |v, i|
|
||||
# deep merge everything between the two arrays
|
||||
original[i].merge(override[i], &merger)
|
||||
end
|
||||
else
|
||||
# if we don't have a Hash in the override,
|
||||
# override the whole array with our new one
|
||||
override
|
||||
end
|
||||
end
|
||||
else
|
||||
override
|
||||
end
|
||||
end
|
||||
end
|
||||
self.merge(second.to_h, &merger)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user