From f267828efef0c2e1fc0f22f7be0de114c5bc3387 Mon Sep 17 00:00:00 2001 From: Kjeld Schouten-Lebbing Date: Sun, 5 Jun 2022 17:33:38 +0200 Subject: [PATCH] BREAKING CHANGE: Common Refactor (#110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split and reorganise some file for refactorign and add docs (#15) * refactor(general): initial restructure, renaming, documenting changes and splitting some files for clearity * bump to make clear this is refactor work * fix(deviceList): fix perdict missing var * fix(common-test): rename loader * remove targz from common-test * different perdict name * reshuffle * reorder more * fix device and persistence lists * no message * Add secret spawner (#17) * add secret spawner (cherry picked from commit 19be71210adb17534da3a380630c8a6548d6c2fd) * move secret spawner * some more cleanup * whoopps * minor env cleanup * more * certs * update test * misc fixes * Move hpa to class (#18) * Move hpa to class * use spawner instead of direct class * Fix some tests * Allow for multiple networkPolicies (#19) * Allow for multiple networkPolicies * also update values.yaml * fix mistake * update tests * lowercase * hmm * refactor serviceAccount creation (#77) * make serviceAccounts more flexible * fixup * fixup * fixup 3 * refactor RBAC creation (#76) * Add support for more than one RBAC to be configured * adapt values.yaml * fixup * fixup2 * rbac tweak * hmmm * work on cleaning things up (#81) * restructure folders a bit * cleanup some references * merge autopermissions with hostpatch and remove docker-compose disable * fixup * SCALE->scale * portal to scale folder * remove dep-common * hmm * render prep as script * fix some permission mistakes * patch auto-permissions tests * More TPL usage for containers and pods (#82) * tpl pod content * fix * fix2 * more mainContainer tpl support * fix again * volume and volumemount tpl options expansion * missing space * readonly fix * finish tpl addition to non-class files * fix port * no tpl for group number * more tpl and test fixes * allow to disable inotify patch * no message * add nfs support to persistence and port a patch from KAH * allow externalTrafficPolicy on all types of services * change fix * Ensure SCALE specific code is not run outside of SCALE (#83) * only apply SCALE specific non-storage settings when running as SCALE App * fix ingress and portal tests * significantly simplify SCALE PVC naming and make it only run when used as SCALE App * fix certificate tests * use global ixChartContext where suitable * Add auto-permissions support for (NFSv4) ACL's (#84) * initial work on NFS4 ACL support * remove automatic permission tests for now... * more verbosity * test another solution * set rights for both user AND group * test auto permissions during run tests * hmmm * hmm2 * fix quoting issues * different quotes * ahhh * Update charts/common/templates/lib/controller/_prepare.tpl Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com> * improve acl detector * invert acl detector * stick to group permissions * ensure chown uses a path Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com> * Tests and small fixes Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com> --- .devcontainer/devcontainer.json | 38 -- .github/ct-lint.yaml | 2 +- .github/workflows/charts-lint-test.yaml | 99 +++++ .github/workflows/common.test.yaml | 78 ---- .gitignore | 4 + Gemfile | 12 - charts/common/Chart.yaml | 2 +- .../_externalInterfaces.tpl | 4 +- .../{configmaps => SCALE}/_portal.tpl | 13 +- .../{lib => SCALE}/cert/_certSecret.tpl | 12 +- .../templates/{lib => SCALE}/cert/_certs.tpl | 16 +- .../templates/_HorizontalPodAutoscaler.tpl | 37 -- charts/common/templates/_daemonset.tpl | 40 -- charts/common/templates/_postSetup.tpl | 63 --- charts/common/templates/_rbac.tpl | 52 --- charts/common/templates/_secret.tpl | 17 - charts/common/templates/_service.tpl | 43 -- charts/common/templates/_serviceaccount.tpl | 18 - .../addons/code-server/_codeserver.tpl | 14 +- .../addons/code-server/_container.tpl | 4 +- .../templates/addons/code-server/_secret.tpl | 6 +- .../templates/addons/code-server/_volume.tpl | 4 +- .../templates/addons/netshoot/_container.tpl | 2 +- .../templates/addons/netshoot/_netshoot.tpl | 4 +- .../templates/addons/promtail/_configmap.tpl | 6 +- .../templates/addons/promtail/_container.tpl | 4 +- .../templates/addons/promtail/_promtail.tpl | 8 +- .../templates/addons/promtail/_volume.tpl | 4 +- charts/common/templates/addons/vpn/_vpn.tpl | 6 +- .../templates/addons/vpn/openvpn/_addon.tpl | 6 +- .../addons/vpn/openvpn/_container.tpl | 4 +- .../templates/addons/vpn/openvpn/_secret.tpl | 6 +- .../templates/addons/vpn/wireguard/_addon.tpl | 4 +- .../addons/vpn/wireguard/_container.tpl | 2 +- .../class/_HorizontalPodAutoscaler.tpl | 47 +++ .../{classes => class}/_configmap.tpl | 16 +- .../templates/{classes => class}/_ingress.tpl | 26 +- .../templates/{ => class}/_networkPolicy.tpl | 52 ++- .../templates/{classes => class}/_pvc.tpl | 18 +- charts/common/templates/class/_rbac.tpl | 64 +++ charts/common/templates/class/_secret.tpl | 35 ++ .../templates/{classes => class}/_service.tpl | 28 +- .../templates/class/_serviceaccount.tpl | 31 ++ .../templates/lib/chart/_annotations.tpl | 18 +- .../templates/lib/chart/_capabilities.tpl | 10 +- charts/common/templates/lib/chart/_labels.tpl | 22 +- charts/common/templates/lib/chart/_names.tpl | 18 +- charts/common/templates/lib/chart/_setup.tpl | 17 - charts/common/templates/lib/chart/_values.tpl | 283 -------------- .../lib/controller/_autopermissions.tpl | 43 -- .../templates/lib/controller/_container.tpl | 72 ++-- .../templates/lib/controller/_hostpatch.tpl | 21 - .../common/templates/lib/controller/_pod.tpl | 51 ++- .../templates/lib/controller/_ports.tpl | 6 +- .../templates/lib/controller/_prepare.tpl | 70 ++++ .../templates/lib/controller/_probes.tpl | 6 +- .../lib/controller/_volumeMounts.tpl | 20 +- .../templates/lib/controller/_volumes.tpl | 26 +- .../lib/dependencies/_mariadbInit.tpl | 4 +- .../lib/dependencies/_mariadbInjector.tpl | 4 +- .../lib/dependencies/_mongodbInit.tpl | 4 +- .../lib/dependencies/_mongodbInjector.tpl | 4 +- .../lib/dependencies/_postgresInit.tpl | 4 +- .../lib/dependencies/_postgresInjector.tpl | 4 +- .../lib/dependencies/_redisInjector.tpl | 4 +- .../lib/{utils => util}/_affinities.tpl | 36 +- .../templates/lib/{utils => util}/_images.tpl | 18 +- .../templates/lib/{utils => util}/_labels.tpl | 8 +- .../templates/lib/util/_primary-ingress.tpl | 21 + .../templates/lib/util/_primary-rbac.tpl | 23 ++ .../templates/lib/util/_primary-service.tpl | 23 ++ .../lib/util/_primary-serviceAccount.tpl | 23 ++ .../{classes => lib/util}/_service_ports.tpl | 2 +- charts/common/templates/lib/util/_storage.tpl | 20 + .../lib/{utils => util}/_tplvalues.tpl | 4 +- .../lib/{utils => util}/_warnings.tpl | 4 +- .../common/templates/lib/utils/_storage.tpl | 41 -- .../templates/lib/values/_capabilities.tpl | 52 +++ .../lib/values/_persistenceSimple.tpl | 19 + .../templates/lib/values/_privileged.tpl | 8 + .../templates/lib/values/_serviceSimple.tpl | 10 + .../lib/values/_supplementalGroups.tpl | 28 ++ .../common/templates/lib/values/_values.tpl | 9 + .../templates/lib/values/_vctSimple.tpl | 10 + .../lists/_controllerAnnotationsList.tpl | 9 + .../values/lists/_controllerLabelsList.tpl | 9 + .../values/lists/_ingressAnnotationsList.tpl | 14 + .../lib/values/lists/_ingressLabelsList.tpl | 14 + .../lib/values/lists/_ingressList.tpl | 13 + .../lists/_persistenceAnnotationsList.tpl | 14 + .../values/lists/_persistenceLabelsList.tpl | 14 + .../lib/values/lists/_persistenceList.tpl | 21 + .../lib/values/lists/_podAnnotationsList.tpl | 9 + .../lib/values/lists/_podLabelsList.tpl | 9 + .../templates/lib/values/lists/_portsList.tpl | 20 + .../lib/values/lists/_serviceList.tpl | 15 + charts/common/templates/{ => loader}/_all.tpl | 6 +- charts/common/templates/loader/_apply.tpl | 62 +++ charts/common/templates/loader/_init.tpl | 30 ++ charts/common/templates/loader/_lists.tpl | 23 ++ charts/common/templates/pods/_daemonset.tpl | 36 ++ .../templates/{ => pods}/_deployment.tpl | 30 +- .../templates/{ => pods}/_statefulset.tpl | 41 +- .../templates/{ => spawner}/_configmap.tpl | 4 +- charts/common/templates/spawner/_hpa.tpl | 19 + .../templates/{ => spawner}/_ingress.tpl | 32 +- .../templates/spawner/_networkPolicy.tpl | 19 + .../common/templates/{ => spawner}/_pvc.tpl | 4 +- charts/common/templates/spawner/_rbac.tpl | 19 + charts/common/templates/spawner/_secret.tpl | 26 ++ charts/common/templates/spawner/_service.tpl | 19 + .../templates/spawner/_serviceaccount.tpl | 19 + charts/common/values.yaml | 241 +++++++----- helper-charts/common-test/Chart.yaml | 6 +- .../common-test/charts/common-9.1.0.tgz | Bin 42886 -> 0 bytes .../common-test/ci/configmap-values.yaml | 2 +- .../common-test/ci/networkpolicy-values.yaml | 87 +++-- .../common-test/ci/persistence-values.yaml | 19 + helper-charts/common-test/ci/rbac-values.yaml | 94 ++--- .../common-test/templates/common.yaml | 2 +- .../tests/addons/codeserver_test.yaml | 167 ++++++++ .../tests/addons/netshoot_test.yaml | 38 ++ .../common-test/tests/addons/vpn_test.yaml | 80 ++++ .../tests/configmap/metadata_test.yaml | 87 +++++ .../tests/configmap/names_test.yaml | 91 +++++ .../tests/container/args_test.yaml | 41 ++ .../tests/container/command_test.yaml | 41 ++ .../common-test/tests/container/env_test.yaml | 192 +++++++++ .../tests/container/envfrom_test.yaml | 43 ++ .../tests/container/ports_test.yaml | 95 +++++ .../tests/container/volumemounts_test.yaml | 129 ++++++ .../controller/metadata_daemonset_test.yaml | 83 ++++ .../controller/metadata_deployment_test.yaml | 83 ++++ .../controller/metadata_statefulset_test.yaml | 83 ++++ .../tests/controller/type_test.yaml | 56 +++ .../tests/ingress/metadata_test.yaml | 91 +++++ .../tests/ingress/presence_test.yaml | 71 ++++ .../tests/ingress/service_reference_test.yaml | 39 ++ .../common-test/tests/ingress/tls_test.yaml | 72 ++++ .../tests/ingress/values_test.yaml | 72 ++++ .../tests/persistence/claimnames_test.yaml | 78 ++++ .../tests/persistence/emptydir_test.yaml | 60 +++ .../tests/persistence/hostpath_test.yaml | 45 +++ .../tests/persistence/types_test.yaml | 127 ++++++ .../volumeclaimtemplates_test.yaml | 30 ++ .../tests/pod/additionalcontainers_test.yaml | 45 +++ .../tests/pod/initcontainers_test.yaml | 45 +++ .../tests/pod/installcontainers_test.yaml | 51 +++ .../common-test/tests/pod/network_test.yaml | 59 +++ .../common-test/tests/pod/replicas_test.yaml | 25 ++ .../tests/pod/upgradecontainers_test.yaml | 51 +++ .../tests/portal/defaults_test.yaml | 84 ++++ .../tests/portal/metadata_test.yaml | 96 +++++ .../tests/portal/nodeport_test.yaml | 27 ++ .../tests/portal/overrides_test.yaml | 66 ++++ .../common-test/tests/pvc/metadata_test.yaml | 106 +++++ .../common-test/tests/pvc/names_test.yaml | 66 ++++ .../tests/pvc/storageclass_test.yaml | 42 ++ .../tests/service/metadata_test.yaml | 81 ++++ .../common-test/tests/service/names_test.yaml | 29 ++ .../tests/service/port_names_test.yaml | 63 +++ .../tests/service/port_protocols_test.yaml | 71 ++++ .../tests/service/values_test.yaml | 33 ++ tests/library/common/addon_codeserver_spec.rb | 109 ------ tests/library/common/addon_netshoot_spec.rb | 35 -- tests/library/common/addon_promtail_spec.rb | 35 -- tests/library/common/addon_vpn_spec.rb | 106 ----- tests/library/common/autoPermissions_spec.rb | 288 -------------- tests/library/common/cert_spec.rb | 322 --------------- .../common/container_resources_spec.rb | 90 ----- tests/library/common/container_spec.rb | 276 ------------- tests/library/common/controller_spec.rb | 61 --- tests/library/common/hpa_spec.rb | 120 ------ tests/library/common/ingress_spec.rb | 240 ------------ tests/library/common/persistence_spec.rb | 368 ------------------ tests/library/common/pod_spec.rb | 109 ------ tests/library/common/portal_spec.rb | 311 --------------- tests/library/common/pvc_spec.rb | 181 --------- tests/library/common/service_spec.rb | 290 -------------- tests/test_helper.rb | 146 ------- 180 files changed, 4688 insertions(+), 4455 deletions(-) delete mode 100644 .devcontainer/devcontainer.json create mode 100644 .github/workflows/charts-lint-test.yaml delete mode 100644 .github/workflows/common.test.yaml delete mode 100644 Gemfile rename charts/common/templates/{classes => SCALE}/_externalInterfaces.tpl (78%) rename charts/common/templates/{configmaps => SCALE}/_portal.tpl (85%) rename charts/common/templates/{lib => SCALE}/cert/_certSecret.tpl (64%) rename charts/common/templates/{lib => SCALE}/cert/_certs.tpl (78%) delete mode 100644 charts/common/templates/_HorizontalPodAutoscaler.tpl delete mode 100644 charts/common/templates/_daemonset.tpl delete mode 100644 charts/common/templates/_postSetup.tpl delete mode 100644 charts/common/templates/_rbac.tpl delete mode 100644 charts/common/templates/_secret.tpl delete mode 100644 charts/common/templates/_service.tpl delete mode 100644 charts/common/templates/_serviceaccount.tpl create mode 100644 charts/common/templates/class/_HorizontalPodAutoscaler.tpl rename charts/common/templates/{classes => class}/_configmap.tpl (62%) rename charts/common/templates/{classes => class}/_ingress.tpl (83%) rename charts/common/templates/{ => class}/_networkPolicy.tpl (74%) rename charts/common/templates/{classes => class}/_pvc.tpl (69%) create mode 100644 charts/common/templates/class/_rbac.tpl create mode 100644 charts/common/templates/class/_secret.tpl rename charts/common/templates/{classes => class}/_service.tpl (82%) create mode 100644 charts/common/templates/class/_serviceaccount.tpl delete mode 100644 charts/common/templates/lib/chart/_setup.tpl delete mode 100644 charts/common/templates/lib/chart/_values.tpl delete mode 100644 charts/common/templates/lib/controller/_autopermissions.tpl delete mode 100644 charts/common/templates/lib/controller/_hostpatch.tpl create mode 100644 charts/common/templates/lib/controller/_prepare.tpl rename charts/common/templates/lib/{utils => util}/_affinities.tpl (61%) rename charts/common/templates/lib/{utils => util}/_images.tpl (54%) rename charts/common/templates/lib/{utils => util}/_labels.tpl (50%) create mode 100644 charts/common/templates/lib/util/_primary-ingress.tpl create mode 100644 charts/common/templates/lib/util/_primary-rbac.tpl create mode 100644 charts/common/templates/lib/util/_primary-service.tpl create mode 100644 charts/common/templates/lib/util/_primary-serviceAccount.tpl rename charts/common/templates/{classes => lib/util}/_service_ports.tpl (92%) create mode 100644 charts/common/templates/lib/util/_storage.tpl rename charts/common/templates/lib/{utils => util}/_tplvalues.tpl (64%) rename charts/common/templates/lib/{utils => util}/_warnings.tpl (77%) delete mode 100644 charts/common/templates/lib/utils/_storage.tpl create mode 100644 charts/common/templates/lib/values/_capabilities.tpl create mode 100644 charts/common/templates/lib/values/_persistenceSimple.tpl create mode 100644 charts/common/templates/lib/values/_privileged.tpl create mode 100644 charts/common/templates/lib/values/_serviceSimple.tpl create mode 100644 charts/common/templates/lib/values/_supplementalGroups.tpl create mode 100644 charts/common/templates/lib/values/_values.tpl create mode 100644 charts/common/templates/lib/values/_vctSimple.tpl create mode 100644 charts/common/templates/lib/values/lists/_controllerAnnotationsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_controllerLabelsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_ingressAnnotationsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_ingressLabelsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_ingressList.tpl create mode 100644 charts/common/templates/lib/values/lists/_persistenceAnnotationsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_persistenceLabelsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_persistenceList.tpl create mode 100644 charts/common/templates/lib/values/lists/_podAnnotationsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_podLabelsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_portsList.tpl create mode 100644 charts/common/templates/lib/values/lists/_serviceList.tpl rename charts/common/templates/{ => loader}/_all.tpl (65%) create mode 100644 charts/common/templates/loader/_apply.tpl create mode 100644 charts/common/templates/loader/_init.tpl create mode 100644 charts/common/templates/loader/_lists.tpl create mode 100644 charts/common/templates/pods/_daemonset.tpl rename charts/common/templates/{ => pods}/_deployment.tpl (57%) rename charts/common/templates/{ => pods}/_statefulset.tpl (53%) rename charts/common/templates/{ => spawner}/_configmap.tpl (85%) create mode 100644 charts/common/templates/spawner/_hpa.tpl rename charts/common/templates/{ => spawner}/_ingress.tpl (55%) create mode 100644 charts/common/templates/spawner/_networkPolicy.tpl rename charts/common/templates/{ => spawner}/_pvc.tpl (85%) create mode 100644 charts/common/templates/spawner/_rbac.tpl create mode 100644 charts/common/templates/spawner/_secret.tpl create mode 100644 charts/common/templates/spawner/_service.tpl create mode 100644 charts/common/templates/spawner/_serviceaccount.tpl delete mode 100644 helper-charts/common-test/charts/common-9.1.0.tgz create mode 100644 helper-charts/common-test/tests/addons/codeserver_test.yaml create mode 100644 helper-charts/common-test/tests/addons/netshoot_test.yaml create mode 100644 helper-charts/common-test/tests/addons/vpn_test.yaml create mode 100644 helper-charts/common-test/tests/configmap/metadata_test.yaml create mode 100644 helper-charts/common-test/tests/configmap/names_test.yaml create mode 100644 helper-charts/common-test/tests/container/args_test.yaml create mode 100644 helper-charts/common-test/tests/container/command_test.yaml create mode 100644 helper-charts/common-test/tests/container/env_test.yaml create mode 100644 helper-charts/common-test/tests/container/envfrom_test.yaml create mode 100644 helper-charts/common-test/tests/container/ports_test.yaml create mode 100644 helper-charts/common-test/tests/container/volumemounts_test.yaml create mode 100644 helper-charts/common-test/tests/controller/metadata_daemonset_test.yaml create mode 100644 helper-charts/common-test/tests/controller/metadata_deployment_test.yaml create mode 100644 helper-charts/common-test/tests/controller/metadata_statefulset_test.yaml create mode 100644 helper-charts/common-test/tests/controller/type_test.yaml create mode 100644 helper-charts/common-test/tests/ingress/metadata_test.yaml create mode 100644 helper-charts/common-test/tests/ingress/presence_test.yaml create mode 100644 helper-charts/common-test/tests/ingress/service_reference_test.yaml create mode 100644 helper-charts/common-test/tests/ingress/tls_test.yaml create mode 100644 helper-charts/common-test/tests/ingress/values_test.yaml create mode 100644 helper-charts/common-test/tests/persistence/claimnames_test.yaml create mode 100644 helper-charts/common-test/tests/persistence/emptydir_test.yaml create mode 100644 helper-charts/common-test/tests/persistence/hostpath_test.yaml create mode 100644 helper-charts/common-test/tests/persistence/types_test.yaml create mode 100644 helper-charts/common-test/tests/persistence/volumeclaimtemplates_test.yaml create mode 100644 helper-charts/common-test/tests/pod/additionalcontainers_test.yaml create mode 100644 helper-charts/common-test/tests/pod/initcontainers_test.yaml create mode 100644 helper-charts/common-test/tests/pod/installcontainers_test.yaml create mode 100644 helper-charts/common-test/tests/pod/network_test.yaml create mode 100644 helper-charts/common-test/tests/pod/replicas_test.yaml create mode 100644 helper-charts/common-test/tests/pod/upgradecontainers_test.yaml create mode 100644 helper-charts/common-test/tests/portal/defaults_test.yaml create mode 100644 helper-charts/common-test/tests/portal/metadata_test.yaml create mode 100644 helper-charts/common-test/tests/portal/nodeport_test.yaml create mode 100644 helper-charts/common-test/tests/portal/overrides_test.yaml create mode 100644 helper-charts/common-test/tests/pvc/metadata_test.yaml create mode 100644 helper-charts/common-test/tests/pvc/names_test.yaml create mode 100644 helper-charts/common-test/tests/pvc/storageclass_test.yaml create mode 100644 helper-charts/common-test/tests/service/metadata_test.yaml create mode 100644 helper-charts/common-test/tests/service/names_test.yaml create mode 100644 helper-charts/common-test/tests/service/port_names_test.yaml create mode 100644 helper-charts/common-test/tests/service/port_protocols_test.yaml create mode 100644 helper-charts/common-test/tests/service/values_test.yaml delete mode 100644 tests/library/common/addon_codeserver_spec.rb delete mode 100644 tests/library/common/addon_netshoot_spec.rb delete mode 100644 tests/library/common/addon_promtail_spec.rb delete mode 100644 tests/library/common/addon_vpn_spec.rb delete mode 100644 tests/library/common/autoPermissions_spec.rb delete mode 100644 tests/library/common/cert_spec.rb delete mode 100644 tests/library/common/container_resources_spec.rb delete mode 100644 tests/library/common/container_spec.rb delete mode 100644 tests/library/common/controller_spec.rb delete mode 100644 tests/library/common/hpa_spec.rb delete mode 100644 tests/library/common/ingress_spec.rb delete mode 100644 tests/library/common/persistence_spec.rb delete mode 100644 tests/library/common/pod_spec.rb delete mode 100644 tests/library/common/portal_spec.rb delete mode 100644 tests/library/common/pvc_spec.rb delete mode 100644 tests/library/common/service_spec.rb delete mode 100644 tests/test_helper.rb diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 26e47d46..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,38 +0,0 @@ -// 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", - "image": "tccr.io/truecharts/devcontainer:v2.2.1" - - // 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", - "github.vscode-pull-request-github", - "eamodio.gitlens", - "yzhang.markdown-all-in-one", - "davidanson.vscode-markdownlint", - "esbenp.prettier-vscode", - "2gua.rainbow-brackets", - "bmuskalla.vscode-tldr", - "visualstudioexptteam.vscodeintellicode", - "wingrunr21.vscode-ruby", - "redhat.vscode-yaml", - "spmeesseman.vscode-taskexplorer", - "formulahendry.code-runner" - ], - - // 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", - - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" -} diff --git a/.github/ct-lint.yaml b/.github/ct-lint.yaml index 583bff03..2bb8903f 100644 --- a/.github/ct-lint.yaml +++ b/.github/ct-lint.yaml @@ -4,4 +4,4 @@ helm-extra-args: --timeout 600s chart-dirs: - charts chart-repos: -- k8s-at-home-libraries=https://library-charts.truecharts.org +- truecharts-libraries=https://library-charts.truecharts.org diff --git a/.github/workflows/charts-lint-test.yaml b/.github/workflows/charts-lint-test.yaml new file mode 100644 index 00000000..60785e43 --- /dev/null +++ b/.github/workflows/charts-lint-test.yaml @@ -0,0 +1,99 @@ +name: "Charts: Lint and test" + +on: + pull_request: + paths: + - '.github/workflows/charts-lint-test.yaml' + - 'charts/**' + - 'helper-charts/**' + +jobs: + lint: + name: Lint charts + runs-on: ubuntu-20.04 + outputs: + changed: ${{ steps.list-changed.outputs.changed }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install Helm + uses: azure/setup-helm@v1 + with: + version: v3.5.4 + + - uses: actions/setup-python@v3 + with: + python-version: 3.7 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.2.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --config .github/ct-lint.yaml) + if [[ -n "$changed" ]]; then + echo "::set-output name=changed::true" + fi + - name: Run chart-testing (lint) + id: lint + if: steps.list-changed.outputs.changed == 'true' + run: ct lint --config .github/ct-lint.yaml + + unittest: + needs: + - lint + name: Run unit tests + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install Helm + uses: azure/setup-helm@v1 + with: + version: v3.5.4 + + - name: Run tests + run: | + helm plugin install https://github.com/vbehar/helm3-unittest --version v1.0.16 + cd helper-charts/common-test/ + helm dependency update + helm unittest -f "tests/**/*_test.yaml" . + install: + needs: + - lint + name: Install charts + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install Helm + uses: azure/setup-helm@v1 + with: + version: v3.5.4 + + - uses: actions/setup-python@v3 + with: + python-version: 3.7 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.2.1 + + - name: Create k3d cluster + uses: nolar/setup-k3d-k3s@v1 + with: + version: v1.22.4+k3s1 + if: needs.lint.outputs.changed == 'true' + + - name: Run chart-testing (install) + if: needs.lint.outputs.changed == 'true' + run: find ./ -type f -name *.yaml -exec sed -i 's/tccr.io/ghcr.io/gI' {} \; && ct install --config .github/ct-install.yaml diff --git a/.github/workflows/common.test.yaml b/.github/workflows/common.test.yaml deleted file mode 100644 index 1deb7cc5..00000000 --- a/.github/workflows/common.test.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: "common: Tests" - -on: - pull_request: - branches: - - '**' - tags-ignore: - - '**' - paths: - - 'charts/**' - - 'helper-charts/**' - - 'tests/**' - - '.github/workflows/common.test.yaml' - - '.github/ct-install.yaml' - - '.github/ct-lint.yaml' - -jobs: - unit-and-lint: - name: Unit and Lint tests - runs-on: ubuntu-latest - container: - image: tccr.io/truecharts/devcontainer:v2.2.1@sha256:4ace13c049bf00f85c63e0070f86b71656a7c3b2113aa3e21c3107f3d1f7bf87 - steps: - - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Checkout - with: - fetch-depth: 100 - - - name: Run chart-testing (lint) - run: ct lint --config .github/ct-lint.yaml --charts 'helper-charts/common-test' - - - name: Run common unit tests - run: | - bundle exec m -r tests - - run-tests: - name: Run tests - runs-on: ubuntu-latest - needs: [unit-and-lint] - steps: - - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # tag=v3 - name: Checkout - with: - fetch-depth: 100 - - - name: Install Helm - if: ${{ matrix.app != '.gitkee' }} - uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab # renovate: tag=v1 - with: - version: v3.7.1 - - - uses: actions/setup-python@98f2ad02fd48d057ee3b4d4f66525b231c3e52b6 # tag=v3 - if: ${{ matrix.app != '.gitkee' }} - with: - python-version: 3.7 - - - name: Set up chart-testing - if: ${{ matrix.app != '.gitkee' }} - uses: helm/chart-testing-action@dae259e86a35ff09145c0805e2d7dd3f7207064a # tag=v2.2.1 - - ## - # Chart-Testing Section - ## - - - uses: actions/setup-python@98f2ad02fd48d057ee3b4d4f66525b231c3e52b6 # tag=v3 - if: ${{ matrix.app != '.gitkee' }} - with: - python-version: 3.7 - - - name: Create k3d cluster - uses: nolar/setup-k3d-k3s@v1 - with: - version: v1.22.4+k3s1 - - - name: Run chart-testing (install) - run: find ./ -type f -name *.yaml -exec sed -i 's/tccr.io/ghcr.io/gI' {} \; && ct install --config .github/ct-install.yaml --charts 'helper-charts/common-test' diff --git a/.gitignore b/.gitignore index a1e5b79d..b3bc02af 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,7 @@ charts/**/charts/*.tgz charts/**/render/* catalog/ dh_catalog/ +charts/*/Chart.lock +charts/*/charts +helper-charts/*/Chart.lock +helper-charts/*/charts diff --git a/Gemfile b/Gemfile deleted file mode 100644 index ac5b8e73..00000000 --- a/Gemfile +++ /dev/null @@ -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 diff --git a/charts/common/Chart.yaml b/charts/common/Chart.yaml index 6105bcba..228998e4 100644 --- a/charts/common/Chart.yaml +++ b/charts/common/Chart.yaml @@ -15,4 +15,4 @@ maintainers: name: common sources: null type: library -version: 9.3.29 +version: 10.0.1 diff --git a/charts/common/templates/classes/_externalInterfaces.tpl b/charts/common/templates/SCALE/_externalInterfaces.tpl similarity index 78% rename from charts/common/templates/classes/_externalInterfaces.tpl rename to charts/common/templates/SCALE/_externalInterfaces.tpl index 524b4f26..db1224ca 100644 --- a/charts/common/templates/classes/_externalInterfaces.tpl +++ b/charts/common/templates/SCALE/_externalInterfaces.tpl @@ -2,7 +2,8 @@ This template serves as a blueprint for External Interface objects that are created using the SCALE GUI. */}} -{{- define "common.classes.externalInterfaces" -}} +{{- define "tc.common.scale.externalInterfaces" -}} +{{- if .Values.global.ixChartContext }} {{- range $index, $iface := .Values.ixExternalInterfacesConfiguration }} --- apiVersion: "k8s.cni.cncf.io/v1" @@ -12,4 +13,5 @@ metadata: spec: config: '{{ $iface }}' {{- end }} +{{- end }} {{- end -}} diff --git a/charts/common/templates/configmaps/_portal.tpl b/charts/common/templates/SCALE/_portal.tpl similarity index 85% rename from charts/common/templates/configmaps/_portal.tpl rename to charts/common/templates/SCALE/_portal.tpl index b81329bb..7c2a1c36 100644 --- a/charts/common/templates/configmaps/_portal.tpl +++ b/charts/common/templates/SCALE/_portal.tpl @@ -1,9 +1,9 @@ -{{- define "common.configmap.portal" -}} - +{{- define "tc.common.scale.portal" -}} +{{- if .Values.ixChartContext }} {{- if .Values.portal }} {{- if .Values.portal.enabled }} -{{- $primaryService := get .Values.service (include "common.service.primary" .) }} -{{- $primaryPort := get $primaryService.ports (include "common.classes.service.ports.primary" (dict "values" $primaryService)) -}} +{{- $primaryService := get .Values.service (include "tc.common.lib.util.service.primary" .) }} +{{- $primaryPort := get $primaryService.ports (include "tc.common.lib.util.service.ports.primary" (dict "values" $primaryService)) -}} {{- $ingr := index .Values.ingress (keys .Values.ingress | first) -}} {{- $host := "$node_ip" }} {{- $port := 443 }} @@ -80,9 +80,7 @@ kind: ConfigMap metadata: name: portal labels: - {{ include "common.labels" . | nindent 4 }} - annotations: - rollme: {{ randAlphaNum 5 | quote }} + {{ include "tc.common.labels" . | nindent 4 }} data: protocol: {{ $protocol }} host: {{ $host | quote }} @@ -91,4 +89,5 @@ data: url: {{ ( printf "%v://%v:%v%v" $protocol $host $port $path ) | quote }} {{- end }} {{- end }} +{{- end }} {{- end -}} diff --git a/charts/common/templates/lib/cert/_certSecret.tpl b/charts/common/templates/SCALE/cert/_certSecret.tpl similarity index 64% rename from charts/common/templates/lib/cert/_certSecret.tpl rename to charts/common/templates/SCALE/cert/_certSecret.tpl index 908edf39..fb2ff609 100644 --- a/charts/common/templates/lib/cert/_certSecret.tpl +++ b/charts/common/templates/SCALE/cert/_certSecret.tpl @@ -1,6 +1,6 @@ -{{- define "common.cert.secret" -}} +{{- define "tc.common.scale.cert.secret" -}} -{{- $secretName := include "common.names.fullname" . -}} +{{- $secretName := include "tc.common.names.fullname" . -}} {{- if .ObjectValues.certHolder -}} {{- if hasKey .ObjectValues.certHolder "nameOverride" -}} @@ -13,7 +13,7 @@ {{- $secretName = ( printf "%v-%v-%v-%v" $secretName "scalecert" "ixcert" .Values.scaleCert ) -}} {{ end -}} -{{- if eq (include "common.cert.available" $ ) "true" -}} +{{- if eq (include "tc.common.scale.cert.available" $ ) "true" -}} {{- printf "\n%s\n" "---" }} @@ -21,10 +21,10 @@ apiVersion: v1 kind: Secret metadata: name: {{ $secretName }}-{{ .Release.Revision }} - labels: {{ include "common.labels" . | nindent 4 }} + labels: {{ include "tc.common.labels" . | nindent 4 }} type: kubernetes.io/tls data: - tls.crt: {{ (include "common.cert.publicKey" $ ) | toString | b64enc | quote }} - tls.key: {{ (include "common.cert.privateKey" $ ) | toString | b64enc | quote }} + tls.crt: {{ (include "tc.common.scale.cert.publicKey" $ ) | toString | b64enc | quote }} + tls.key: {{ (include "tc.common.scale.cert.privateKey" $ ) | toString | b64enc | quote }} {{- end -}} {{- end -}} diff --git a/charts/common/templates/lib/cert/_certs.tpl b/charts/common/templates/SCALE/cert/_certs.tpl similarity index 78% rename from charts/common/templates/lib/cert/_certs.tpl rename to charts/common/templates/SCALE/cert/_certs.tpl index bc223d25..a86958b2 100644 --- a/charts/common/templates/lib/cert/_certs.tpl +++ b/charts/common/templates/SCALE/cert/_certs.tpl @@ -1,11 +1,11 @@ {{/* Retrieve true/false if certificate is configured */}} -{{- define "common.cert.available" -}} +{{- define "tc.common.scale.cert.available" -}} {{- if .ObjectValues.certHolder.scaleCert -}} {{- $values := (. | mustDeepCopy) -}} {{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert) -}} -{{- template "common.cert_present" $values -}} +{{- template "tc.common.scale.cert_present" $values -}} {{- else -}} {{- false -}} {{- end -}} @@ -15,26 +15,26 @@ Retrieve true/false if certificate is configured {{/* Retrieve public key of certificate */}} -{{- define "common.cert.publicKey" -}} +{{- define "tc.common.scale.cert.publicKey" -}} {{- $values := (. | mustDeepCopy) -}} {{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert "publicKey" true) -}} -{{ include "common.cert" $values }} +{{ include "tc.common.scale.cert" $values }} {{- end -}} {{/* Retrieve private key of certificate */}} -{{- define "common.cert.privateKey" -}} +{{- define "tc.common.scale.cert.privateKey" -}} {{- $values := (. | mustDeepCopy) -}} {{- $_ := set $values "commonCertOptions" (dict "certKeyName" $values.ObjectValues.certHolder.scaleCert) -}} -{{ include "common.cert" $values }} +{{ include "tc.common.scale.cert" $values }} {{- end -}} {{/* Retrieve true/false if certificate is available in ixCertificates */}} -{{- define "common.cert_present" -}} +{{- define "tc.common.scale.cert_present" -}} {{- $values := . -}} {{- hasKey $values.Values.ixCertificates ($values.commonCertOptions.certKeyName | toString) -}} {{- end -}} @@ -43,7 +43,7 @@ Retrieve true/false if certificate is available in ixCertificates {{/* Retrieve certificate from variable name */}} -{{- define "common.cert" -}} +{{- define "tc.common.scale.cert" -}} {{- $values := . -}} {{- $certKey := ($values.commonCertOptions.certKeyName | toString) -}} {{- if hasKey $values.Values.ixCertificates $certKey -}} diff --git a/charts/common/templates/_HorizontalPodAutoscaler.tpl b/charts/common/templates/_HorizontalPodAutoscaler.tpl deleted file mode 100644 index c7cbbb4c..00000000 --- a/charts/common/templates/_HorizontalPodAutoscaler.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{{/* -This template serves as a blueprint for horizontal pod autoscaler objects that are created -using the common library. -*/}} -{{- define "common.hpa" -}} - {{- if .Values.autoscaling.enabled -}} - {{- $hpaName := include "common.names.fullname" . -}} - {{- $targetName := include "common.names.fullname" . }} ---- -apiVersion: autoscaling/v2beta1 -kind: HorizontalPodAutoscaler -metadata: - name: {{ $hpaName }} - labels: - {{- include "common.labels" . | nindent 4 }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - 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 }} - - type: Resource - resource: - name: cpu - targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} - {{- end -}} -{{- end -}} diff --git a/charts/common/templates/_daemonset.tpl b/charts/common/templates/_daemonset.tpl deleted file mode 100644 index 05c29214..00000000 --- a/charts/common/templates/_daemonset.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{{/* -This template serves as the blueprint for the DaemonSet objects that are created -within the common library. -*/}} -{{- define "common.daemonset" }} ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.controller.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: - {{- include "common.annotations.workload" . | nindent 4 }} - {{- with .Values.controller.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} - selector: - matchLabels: - {{- include "common.labels.selectorLabels" . | nindent 6 }} - template: - metadata: - annotations: - {{- include "common.annotations.workload.spec" . | nindent 8 }} - {{- with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "common.labels.selectorLabels" . | nindent 8 }} - {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} - {{- end }} - spec: - {{- include "common.controller.pod" . | nindent 6 }} -{{- end }} diff --git a/charts/common/templates/_postSetup.tpl b/charts/common/templates/_postSetup.tpl deleted file mode 100644 index 73dde535..00000000 --- a/charts/common/templates/_postSetup.tpl +++ /dev/null @@ -1,63 +0,0 @@ -{{/* -Secondary entrypoint and primary loader for the common chart -*/}} -{{- define "common.postSetup" -}} - {{- /* Render the externalInterfaces */ -}} - {{ include "common.classes.externalInterfaces" . | nindent 0 }} - - {{- /* Enable code-server add-on if required */ -}} - {{- if .Values.addons.codeserver.enabled }} - {{- include "common.addon.codeserver" . }} - {{- end -}} - - {{- /* Enable VPN add-on if required */ -}} - {{- if ne "disabled" .Values.addons.vpn.type -}} - {{- include "common.addon.vpn" . }} - {{- end -}} - - {{- /* Enable promtail add-on if required */ -}} - {{- if .Values.addons.promtail.enabled }} - {{- include "common.addon.promtail" . }} - {{- end -}} - - {{- /* Enable netshoot add-on if required */ -}} - {{- if .Values.addons.netshoot.enabled }} - {{- include "common.addon.netshoot" . }} - {{- end -}} - - {{- /* Build the confimap */ -}} - {{ include "common.configmap" . | nindent 0 }} - - {{- /* Build the templates */ -}} - {{- include "common.pvc" . }} - - {{- include "common.serviceAccount" . }} - - {{- if .Values.controller.enabled }} - {{- if eq .Values.controller.type "deployment" }} - {{- include "common.deployment" . | nindent 0 }} - {{ else if eq .Values.controller.type "daemonset" }} - {{- include "common.daemonset" . | nindent 0 }} - {{ 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 -}} - {{- end -}} - - {{ include "common.rbac" . | nindent 0 }} - - {{ include "common.hpa" . | nindent 0 }} - - {{ include "common.service" . | nindent 0 }} - - {{ include "common.ingress" . | nindent 0 }} - - {{- if .Values.secret -}} - {{ include "common.secret" . | nindent 0 }} - {{- end -}} - - {{ include "common.configmap.portal" . | nindent 0 }} - - {{ include "common.networkpolicy" . | nindent 0 }} -{{- end -}} diff --git a/charts/common/templates/_rbac.tpl b/charts/common/templates/_rbac.tpl deleted file mode 100644 index 0899366c..00000000 --- a/charts/common/templates/_rbac.tpl +++ /dev/null @@ -1,52 +0,0 @@ -{{/* -This template serves as a blueprint for all PersistentVolumeClaim objects that are created -within the common library. -*/}} -{{- define "common.rbac" -}} -{{- if .Values.rbac.enabled }} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.rbac.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: - {{- with .Values.rbac.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -{{- with .Values.rbac.rules }} -rules: - {{- . | toYaml | nindent 4 }} -{{- end}} - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.rbac.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: - {{- with .Values.rbac.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: {{ include "common.names.fullname" . }} -subjects: - - kind: ServiceAccount - name: {{ include "common.names.serviceAccountName" . }} - namespace: {{ .Release.Namespace }} - {{- end }} - {{- with .Values.rbac.subjects }} - {{- toYaml . | nindent 2 }} - {{- end }} -{{- end -}} diff --git a/charts/common/templates/_secret.tpl b/charts/common/templates/_secret.tpl deleted file mode 100644 index 1a6df463..00000000 --- a/charts/common/templates/_secret.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{{/* -The Secret object to be created. -*/}} -{{- define "common.secret" }} ---- -apiVersion: v1 -kind: Secret -metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} -type: Opaque -{{- with .Values.secret }} -stringData: - {{- toYaml . | nindent 2 }} -{{- end }} -{{- end }} diff --git a/charts/common/templates/_service.tpl b/charts/common/templates/_service.tpl deleted file mode 100644 index 35811938..00000000 --- a/charts/common/templates/_service.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{{/* -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 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 -}} diff --git a/charts/common/templates/_serviceaccount.tpl b/charts/common/templates/_serviceaccount.tpl deleted file mode 100644 index dff16abf..00000000 --- a/charts/common/templates/_serviceaccount.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{{/* -The ServiceAccount object to be created. -*/}} -{{- define "common.serviceAccount" }} -{{- if .Values.serviceAccount.create }} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} -{{- end }} diff --git a/charts/common/templates/addons/code-server/_codeserver.tpl b/charts/common/templates/addons/code-server/_codeserver.tpl index ef1ca677..88058777 100644 --- a/charts/common/templates/addons/code-server/_codeserver.tpl +++ b/charts/common/templates/addons/code-server/_codeserver.tpl @@ -2,22 +2,22 @@ Template to render code-server addon It will include / inject the required templates based on the given values. */}} -{{- define "common.addon.codeserver" -}} +{{- define "tc.common.addon.codeserver" -}} {{- if .Values.addons.codeserver.enabled -}} {{/* Append the code-server container to the additionalContainers */}} - {{- $container := include "common.addon.codeserver.container" . | fromYaml -}} + {{- $container := include "tc.common.addon.codeserver.container" . | fromYaml -}} {{- if $container -}} {{- $_ := set .Values.additionalContainers "addon-codeserver" $container -}} {{- end -}} {{/* Include the deployKeySecret if not empty */}} - {{- $secret := include "common.addon.codeserver.deployKeySecret" . -}} + {{- $secret := include "tc.common.addon.codeserver.deployKeySecret" . -}} {{- if $secret -}} {{- $secret | nindent 0 -}} {{- end -}} {{/* Append the secret volume to the volumes */}} - {{- $volume := include "common.addon.codeserver.deployKeyVolumeSpec" . | fromYaml -}} + {{- $volume := include "tc.common.addon.codeserver.deployKeyVolumeSpec" . | fromYaml -}} {{- if $volume -}} {{- $_ := set .Values.persistence "deploykey" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $volume) -}} {{- end -}} @@ -27,7 +27,7 @@ It will include / inject the required templates based on the given values. {{- $serviceValues := .Values.addons.codeserver.service -}} {{- $_ := set $serviceValues "nameOverride" "codeserver" -}} {{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}} - {{- include "common.classes.service" $ -}} + {{- include "tc.common.class.service" $ -}} {{- $_ := unset $ "ObjectValues" -}} {{- end -}} @@ -37,13 +37,13 @@ It will include / inject the required templates based on the given values. {{- $_ := set $ingressValues "nameOverride" "codeserver" -}} {{/* Determine the target service name & port */}} - {{- $svcName := printf "%v-codeserver" (include "common.names.fullname" .) -}} + {{- $svcName := printf "%v-codeserver" (include "tc.common.names.fullname" .) -}} {{- $svcPort := .Values.addons.codeserver.service.ports.codeserver.port -}} {{- range $_, $host := $ingressValues.hosts -}} {{- $_ := set (index $host.paths 0) "service" (dict "name" $svcName "port" $svcPort) -}} {{- end -}} {{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}} - {{- include "common.classes.ingress" $ -}} + {{- include "tc.common.class.ingress" $ -}} {{- $_ := unset $ "ObjectValues" -}} {{- end -}} {{- end -}} diff --git a/charts/common/templates/addons/code-server/_container.tpl b/charts/common/templates/addons/code-server/_container.tpl index 473b7d23..19c4bd9a 100644 --- a/charts/common/templates/addons/code-server/_container.tpl +++ b/charts/common/templates/addons/code-server/_container.tpl @@ -1,7 +1,7 @@ {{/* The code-server sidecar container to be inserted. */}} -{{- define "common.addon.codeserver.container" -}} +{{- define "tc.common.addon.codeserver.container" -}} name: codeserver image: "{{ .Values.codeserverImage.repository }}:{{ .Values.codeserverImage.tag }}" imagePullPolicy: {{ .Values.codeserverImage.pullPolicy }} @@ -34,7 +34,7 @@ args: - "--port" - "{{ .Values.addons.codeserver.service.ports.codeserver.port }}" - {{ .Values.addons.codeserver.workingDir | default "/" }} -{{- with (include "common.controller.volumeMounts" . | trim) }} +{{- with (include "tc.common.controller.volumeMounts" . | trim) }} volumeMounts: {{ nindent 2 . }} {{- end }} diff --git a/charts/common/templates/addons/code-server/_secret.tpl b/charts/common/templates/addons/code-server/_secret.tpl index 14c62327..cfb53700 100644 --- a/charts/common/templates/addons/code-server/_secret.tpl +++ b/charts/common/templates/addons/code-server/_secret.tpl @@ -1,15 +1,15 @@ {{/* The OpenVPN credentials secrets to be included. */}} -{{- define "common.addon.codeserver.deployKeySecret" -}} +{{- define "tc.common.addon.codeserver.deployKeySecret" -}} {{- if or .Values.addons.codeserver.git.deployKey .Values.addons.codeserver.git.deployKeyBase64 }} --- apiVersion: v1 kind: Secret metadata: - name: {{ template "common.names.fullname" . }}-deploykey + name: {{ template "tc.common.names.fullname" . }}-deploykey labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} type: Opaque {{- if .Values.addons.codeserver.git.deployKey }} stringData: diff --git a/charts/common/templates/addons/code-server/_volume.tpl b/charts/common/templates/addons/code-server/_volume.tpl index 6e6d5947..42fbf155 100644 --- a/charts/common/templates/addons/code-server/_volume.tpl +++ b/charts/common/templates/addons/code-server/_volume.tpl @@ -1,13 +1,13 @@ {{/* The volume (referencing git deploykey) to be inserted into additionalVolumes. */}} -{{- define "common.addon.codeserver.deployKeyVolumeSpec" -}} +{{- define "tc.common.addon.codeserver.deployKeyVolumeSpec" -}} {{- if or .Values.addons.codeserver.git.deployKey .Values.addons.codeserver.git.deployKeyBase64 .Values.addons.codeserver.git.deployKeySecret }} secret: {{- if .Values.addons.codeserver.git.deployKeySecret }} secretName: {{ .Values.addons.codeserver.git.deployKeySecret }} {{- else }} - secretName: {{ include "common.names.fullname" . }}-deploykey + secretName: {{ include "tc.common.names.fullname" . }}-deploykey {{- end }} defaultMode: 256 items: diff --git a/charts/common/templates/addons/netshoot/_container.tpl b/charts/common/templates/addons/netshoot/_container.tpl index 33eae63f..a68604f1 100644 --- a/charts/common/templates/addons/netshoot/_container.tpl +++ b/charts/common/templates/addons/netshoot/_container.tpl @@ -1,7 +1,7 @@ {{/* The netshoot sidecar container to be inserted. */}} -{{- define "common.addon.netshoot.container" -}} +{{- define "tc.common.addon.netshoot.container" -}} name: netshoot image: "{{ .Values.netshootImage.repository }}:{{ .Values.netshootImage.tag }}" imagePullPolicy: {{ .Values.netshootImage.pullPolicy }} diff --git a/charts/common/templates/addons/netshoot/_netshoot.tpl b/charts/common/templates/addons/netshoot/_netshoot.tpl index 9a1e9fae..b6799b06 100644 --- a/charts/common/templates/addons/netshoot/_netshoot.tpl +++ b/charts/common/templates/addons/netshoot/_netshoot.tpl @@ -2,10 +2,10 @@ Template to render netshoot addon It will include / inject the required templates based on the given values. */}} -{{- define "common.addon.netshoot" -}} +{{- define "tc.common.addon.netshoot" -}} {{- if .Values.addons.netshoot.enabled -}} {{/* Append the netshoot container to the additionalContainers */}} - {{- $container := include "common.addon.netshoot.container" . | fromYaml -}} + {{- $container := include "tc.common.addon.netshoot.container" . | fromYaml -}} {{- if $container -}} {{- $_ := set .Values.additionalContainers "addon-netshoot" $container -}} {{- end -}} diff --git a/charts/common/templates/addons/promtail/_configmap.tpl b/charts/common/templates/addons/promtail/_configmap.tpl index 3b927576..638285bb 100644 --- a/charts/common/templates/addons/promtail/_configmap.tpl +++ b/charts/common/templates/addons/promtail/_configmap.tpl @@ -1,15 +1,15 @@ {{/* The promtail config to be included. */}} -{{- define "common.addon.promtail.configmap" -}} +{{- define "tc.common.addon.promtail.configmap" -}} {{- if .Values.addons.promtail.enabled }} --- apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "common.names.fullname" . }}-promtail + name: {{ include "tc.common.names.fullname" . }}-promtail labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} data: promtail.yaml: | server: diff --git a/charts/common/templates/addons/promtail/_container.tpl b/charts/common/templates/addons/promtail/_container.tpl index dda74a07..1909f070 100644 --- a/charts/common/templates/addons/promtail/_container.tpl +++ b/charts/common/templates/addons/promtail/_container.tpl @@ -1,7 +1,7 @@ {{/* The promtail sidecar container to be inserted. */}} -{{- define "common.addon.promtail.container" -}} +{{- define "tc.common.addon.promtail.container" -}} name: promtail image: "{{ .Values.promtailImage.repository }}:{{ .Values.promtailImage.tag }}" imagePullPolicy: {{ .Values.promtailImage.pullPolicy }} @@ -35,7 +35,7 @@ volumeMounts: mountPath: /etc/promtail/promtail.yaml subPath: promtail.yaml readOnly: true -{{- with (include "common.controller.volumeMounts" . | trim) }} +{{- with (include "tc.common.controller.volumeMounts" . | trim) }} {{ nindent 2 . }} {{- end }} {{- with .Values.addons.promtail.resources }} diff --git a/charts/common/templates/addons/promtail/_promtail.tpl b/charts/common/templates/addons/promtail/_promtail.tpl index c8ef10f9..c72cc163 100644 --- a/charts/common/templates/addons/promtail/_promtail.tpl +++ b/charts/common/templates/addons/promtail/_promtail.tpl @@ -2,22 +2,22 @@ Template to render promtail addon It will include / inject the required templates based on the given values. */}} -{{- define "common.addon.promtail" -}} +{{- define "tc.common.addon.promtail" -}} {{- if .Values.addons.promtail.enabled -}} {{/* Append the promtail container to the additionalContainers */}} - {{- $container := include "common.addon.promtail.container" . | fromYaml -}} + {{- $container := include "tc.common.addon.promtail.container" . | fromYaml -}} {{- if $container -}} {{- $_ := set .Values.additionalContainers "addon-promtail" $container -}} {{- end -}} {{/* Include the configmap if not empty */}} - {{- $configmap := include "common.addon.promtail.configmap" . -}} + {{- $configmap := include "tc.common.addon.promtail.configmap" . -}} {{- if $configmap -}} {{- $configmap | nindent 0 -}} {{- end -}} {{/* Append the promtail config volume to the volumes */}} - {{- $volume := include "common.addon.promtail.volumeSpec" . | fromYaml -}} + {{- $volume := include "tc.common.addon.promtail.volumeSpec" . | fromYaml -}} {{- if $volume -}} {{- $_ := set .Values.persistence "promtail-config" (dict "enabled" "true" "mountPath" "-" "type" "custom" "volumeSpec" $volume) -}} {{- end -}} diff --git a/charts/common/templates/addons/promtail/_volume.tpl b/charts/common/templates/addons/promtail/_volume.tpl index bce624b5..a278b599 100644 --- a/charts/common/templates/addons/promtail/_volume.tpl +++ b/charts/common/templates/addons/promtail/_volume.tpl @@ -1,7 +1,7 @@ {{/* The volume (referencing config) to be inserted into additionalVolumes. */}} -{{- define "common.addon.promtail.volumeSpec" -}} +{{- define "tc.common.addon.promtail.volumeSpec" -}} configMap: - name: {{ include "common.names.fullname" . }}-promtail + name: {{ include "tc.common.names.fullname" . }}-promtail {{- end -}} diff --git a/charts/common/templates/addons/vpn/_vpn.tpl b/charts/common/templates/addons/vpn/_vpn.tpl index 5b04611e..5f6d59da 100644 --- a/charts/common/templates/addons/vpn/_vpn.tpl +++ b/charts/common/templates/addons/vpn/_vpn.tpl @@ -2,14 +2,14 @@ Template to render VPN addon It will include / inject the required templates based on the given values. */}} -{{- define "common.addon.vpn" -}} +{{- define "tc.common.addon.vpn" -}} {{- if ne "disabled" .Values.addons.vpn.type -}} {{- if eq "openvpn" .Values.addons.vpn.type -}} - {{- include "common.addon.openvpn" . }} + {{- include "tc.common.addon.openvpn" . }} {{- end -}} {{- if eq "wireguard" .Values.addons.vpn.type -}} - {{- include "common.addon.wireguard" . }} + {{- include "tc.common.addon.wireguard" . }} {{- end -}} diff --git a/charts/common/templates/addons/vpn/openvpn/_addon.tpl b/charts/common/templates/addons/vpn/openvpn/_addon.tpl index 1cfcdd51..fea0dd1f 100644 --- a/charts/common/templates/addons/vpn/openvpn/_addon.tpl +++ b/charts/common/templates/addons/vpn/openvpn/_addon.tpl @@ -2,15 +2,15 @@ Template to render OpenVPN addon. It will add the container to the list of additionalContainers and add a credentials secret if speciffied. */}} -{{- define "common.addon.openvpn" -}} +{{- define "tc.common.addon.openvpn" -}} {{/* Append the openVPN container to the additionalContainers */}} - {{- $container := include "common.addon.openvpn.container" . | fromYaml -}} + {{- $container := include "tc.common.addon.openvpn.container" . | fromYaml -}} {{- if $container -}} {{- $_ := set .Values.additionalContainers "addon-openvpn" $container -}} {{- end -}} {{/* Include the secret if not empty */}} - {{- $secret := include "common.addon.openvpn.secret" . -}} + {{- $secret := include "tc.common.addon.openvpn.secret" . -}} {{- if $secret -}} {{- $secret | nindent 0 -}} {{- end -}} diff --git a/charts/common/templates/addons/vpn/openvpn/_container.tpl b/charts/common/templates/addons/vpn/openvpn/_container.tpl index eb1a5cf3..fa9507c0 100644 --- a/charts/common/templates/addons/vpn/openvpn/_container.tpl +++ b/charts/common/templates/addons/vpn/openvpn/_container.tpl @@ -1,7 +1,7 @@ {{/* The OpenVPN sidecar container to be inserted. */}} -{{- define "common.addon.openvpn.container" -}} +{{- define "tc.common.addon.openvpn.container" -}} name: openvpn image: "{{ .Values.openvpnImage.repository }}:{{ .Values.openvpnImage.tag }}" imagePullPolicy: {{ .Values.openvpnImage.pullPolicy }} @@ -52,7 +52,7 @@ env: {{- if or ( .Values.addons.vpn.openvpn.username ) ( .Values.addons.vpn.openvpn.password ) }} envFrom: - secretRef: - name: {{ include "common.names.fullname" . }}-openvpn + name: {{ include "tc.common.names.fullname" . }}-openvpn {{- end }} volumeMounts: - mountPath: {{ .Values.persistence.shared.mountPath }} diff --git a/charts/common/templates/addons/vpn/openvpn/_secret.tpl b/charts/common/templates/addons/vpn/openvpn/_secret.tpl index b479afb0..60fe27d8 100644 --- a/charts/common/templates/addons/vpn/openvpn/_secret.tpl +++ b/charts/common/templates/addons/vpn/openvpn/_secret.tpl @@ -1,14 +1,14 @@ {{/* The OpenVPN credentials secrets to be included. */}} -{{- define "common.addon.openvpn.secret" -}} +{{- define "tc.common.addon.openvpn.secret" -}} --- apiVersion: v1 kind: Secret metadata: - name: {{ include "common.names.fullname" $ }}-openvpn + name: {{ include "tc.common.names.fullname" $ }}-openvpn labels: - {{- include "common.labels" $ | nindent 4 }} + {{- include "tc.common.labels" $ | nindent 4 }} data: VPN_AUTH: {{ ( printf "%v;%v" .Values.addons.vpn.openvpn.username .Values.addons.vpn.openvpn.password ) | b64enc }} {{- end -}} diff --git a/charts/common/templates/addons/vpn/wireguard/_addon.tpl b/charts/common/templates/addons/vpn/wireguard/_addon.tpl index 6c7ea35c..2d593fc3 100644 --- a/charts/common/templates/addons/vpn/wireguard/_addon.tpl +++ b/charts/common/templates/addons/vpn/wireguard/_addon.tpl @@ -2,9 +2,9 @@ Template to render Wireguard addon. It will add the container to the list of additionalContainers. */}} */}} -{{- define "common.addon.wireguard" -}} +{{- define "tc.common.addon.wireguard" -}} {{/* Append the Wireguard container to the additionalContainers */}} - {{- $container := fromYaml (include "common.addon.wireguard.container" .) -}} + {{- $container := fromYaml (include "tc.common.addon.wireguard.container" .) -}} {{- if $container -}} {{- $_ := set .Values.additionalContainers "addon-wireguard" $container -}} {{- end -}} diff --git a/charts/common/templates/addons/vpn/wireguard/_container.tpl b/charts/common/templates/addons/vpn/wireguard/_container.tpl index 4eb13fda..18cfa192 100644 --- a/charts/common/templates/addons/vpn/wireguard/_container.tpl +++ b/charts/common/templates/addons/vpn/wireguard/_container.tpl @@ -1,7 +1,7 @@ {{/* The Wireguard sidecar container to be inserted. */}} -{{- define "common.addon.wireguard.container" -}} +{{- define "tc.common.addon.wireguard.container" -}} name: wireguard image: "{{ .Values.wireguardImage.repository }}:{{ .Values.wireguardImage.tag }}" imagePullPolicy: {{ .Values.wireguardImage.pullPolicy }} diff --git a/charts/common/templates/class/_HorizontalPodAutoscaler.tpl b/charts/common/templates/class/_HorizontalPodAutoscaler.tpl new file mode 100644 index 00000000..9958de11 --- /dev/null +++ b/charts/common/templates/class/_HorizontalPodAutoscaler.tpl @@ -0,0 +1,47 @@ +{{/* +This template serves as a blueprint for horizontal pod autoscaler objects that are created +using the common library. +*/}} +{{- define "tc.common.class.hpa" -}} + {{- $targetName := include "tc.common.names.fullname" . }} + {{- $fullName := include "tc.common.names.fullname" . -}} + {{- $hpaName := $fullName -}} + {{- $values := .Values.hpa -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.hpa -}} + {{- $values = . -}} + {{- end -}} + {{ end -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $hpaName = printf "%v-%v" $hpaName $values.nameOverride -}} + {{- end }} +--- +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ $hpaName }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ $values.targetKind | default ( include "tc.common.names.controllerType" . ) }} + name: {{ $values.target | default $targetName }} + minReplicas: {{ $values.minReplicas | default 1 }} + maxReplicas: {{ $values.maxReplicas | default 3 }} + metrics: + {{- if $values.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ $values.targetCPUUtilizationPercentage }} + {{- end }} + {{- if $values.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ $values.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/classes/_configmap.tpl b/charts/common/templates/class/_configmap.tpl similarity index 62% rename from charts/common/templates/classes/_configmap.tpl rename to charts/common/templates/class/_configmap.tpl index 31d841d6..3efdb1e1 100644 --- a/charts/common/templates/classes/_configmap.tpl +++ b/charts/common/templates/class/_configmap.tpl @@ -2,8 +2,8 @@ This template serves as a blueprint for all configMap objects that are created within the common library. */}} -{{- define "common.classes.configmap" -}} - {{- $fullName := include "common.names.fullname" . -}} +{{- define "tc.common.class.configmap" -}} + {{- $fullName := include "tc.common.names.fullname" . -}} {{- $configMapName := $fullName -}} {{- $values := .Values.configmap -}} @@ -21,14 +21,12 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ $configMapName }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with $values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with $values.annotations }} + {{- with (merge ($values.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} annotations: - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} data: {{- with $values.data }} diff --git a/charts/common/templates/classes/_ingress.tpl b/charts/common/templates/class/_ingress.tpl similarity index 83% rename from charts/common/templates/classes/_ingress.tpl rename to charts/common/templates/class/_ingress.tpl index ad02f96f..3cd05400 100644 --- a/charts/common/templates/classes/_ingress.tpl +++ b/charts/common/templates/class/_ingress.tpl @@ -2,8 +2,8 @@ This template serves as a blueprint for all Ingress objects that are created within the common library. */}} -{{- define "common.classes.ingress" -}} - {{- $fullName := include "common.names.fullname" . -}} +{{- define "tc.common.class.ingress" -}} + {{- $fullName := include "tc.common.names.fullname" . -}} {{- $ingressName := $fullName -}} {{- $values := .Values.ingress -}} @@ -17,13 +17,13 @@ within the common library. {{- $ingressName = printf "%v-%v" $ingressName $values.nameOverride -}} {{- end -}} - {{- $primaryService := get .Values.service (include "common.service.primary" .) -}} - {{- $autoLinkService := get .Values.service (include "common.service.primary" .) -}} + {{- $primaryService := get .Values.service (include "tc.common.lib.util.service.primary" .) -}} + {{- $autoLinkService := get .Values.service (include "tc.common.lib.util.service.primary" .) -}} {{- $defaultServiceName := $fullName -}} {{- if and (hasKey $primaryService "nameOverride") $primaryService.nameOverride -}} {{- $defaultServiceName = printf "%v-%v" $defaultServiceName $primaryService.nameOverride -}} {{- end -}} - {{- $defaultServicePort := get $primaryService.ports (include "common.classes.service.ports.primary" (dict "values" $primaryService)) -}} + {{- $defaultServicePort := get $primaryService.ports (include "tc.common.lib.util.service.ports.primary" (dict "values" $primaryService)) -}} {{- if and (hasKey $values "nameOverride") ( $values.nameOverride ) ( $values.autoLink ) -}} {{- $autoLinkService = get .Values.service $values.nameOverride -}} @@ -32,7 +32,7 @@ within the common library. {{- end -}} - {{- $isStable := include "common.capabilities.ingress.isStable" . }} + {{- $isStable := include "tc.common.capabilities.ingress.isStable" . }} {{- $mddwrNamespace := "default" }} {{- if $values.ingressClassName }} @@ -66,20 +66,18 @@ within the common library. {{ end }} --- -apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} +apiVersion: {{ include "tc.common.capabilities.ingress.apiVersion" . }} kind: Ingress metadata: name: {{ $ingressName }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with $values.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} + {{- with (merge ($values.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} annotations: "traefik.ingress.kubernetes.io/router.entrypoints": {{ $values.entrypoint | default "websecure" }} "traefik.ingress.kubernetes.io/router.middlewares": {{ $middlewares | quote }} - {{- with $values.annotations }} - {{- toYaml . | nindent 4 }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} spec: {{- if and $isStable $values.ingressClassName }} diff --git a/charts/common/templates/_networkPolicy.tpl b/charts/common/templates/class/_networkPolicy.tpl similarity index 74% rename from charts/common/templates/_networkPolicy.tpl rename to charts/common/templates/class/_networkPolicy.tpl index 44146985..82587ecb 100644 --- a/charts/common/templates/_networkPolicy.tpl +++ b/charts/common/templates/class/_networkPolicy.tpl @@ -1,40 +1,57 @@ {{/* Blueprint for the NetworkPolicy object that can be included in the addon. */}} -{{- define "common.networkpolicy" -}} -{{- if .Values.networkPolicy.enabled }} +{{- define "tc.common.class.networkpolicy" -}} + {{- $fullName := include "tc.common.names.fullname" . -}} + {{- $networkPolicyName := $fullName -}} + {{- $values := .Values.networkPolicy -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.networkPolicy -}} + {{- $values = . -}} + {{- end -}} + {{ end -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $networkPolicyName = printf "%v-%v" $networkPolicyName $values.nameOverride -}} + {{- end }} --- kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: - labels: - {{- include "common.labels" . | nindent 4 }} - name: {{ include "common.names.fullname" . }} + name: {{ $networkPolicyName }} + {{- with (merge ($values.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + annotations: + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} spec: podSelector: - {{- if .Values.networkPolicy.podSelector }} - {{- with .Values.networkPolicy.podSelector }} + {{- if $values.podSelector }} + {{- with $values.podSelector }} {{- . | toYaml | nindent 4 }} {{- end -}} {{- else }} matchLabels: - {{- include "common.labels.selectorLabels" . | nindent 6 }} + {{- include "tc.common.labels.selectorLabels" . | nindent 6 }} {{- end }} - {{- if .Values.networkPolicy.policyType }} - {{- if eq .Values.networkPolicy.policyType "ingress" }} + {{- if $values.policyType }} + {{- if eq $values.policyType "ingress" }} policyTypes: ["Ingress"] - {{- else if eq .Values.networkPolicy.policyType "egress" }} + {{- else if eq $values.policyType "egress" }} policyTypes: ["Egress"] - {{- else if eq .Values.networkPolicy.policyType "ingress-egress" }} + {{- else if eq $values.policyType "ingress-egress" }} policyTypes: ["Ingress", "Egress"] {{- end -}} {{- end -}} - {{- if .Values.networkPolicy.egress }} + {{- if $values.egress }} egress: - {{- range .Values.networkPolicy.egress }} + {{- range $values.egress }} - to: {{- range .to }} {{- $nss := false }} @@ -95,9 +112,9 @@ spec: {{- end -}} {{- end -}} - {{- if .Values.networkPolicy.ingress }} + {{- if $values.ingress }} ingress: - {{- range .Values.networkPolicy.ingress }} + {{- range $values.ingress }} - from: {{- range .from }} {{- $nss := false }} @@ -156,7 +173,4 @@ spec: {{- end -}} {{- end -}} {{- end -}} - - -{{- end -}} {{- end -}} diff --git a/charts/common/templates/classes/_pvc.tpl b/charts/common/templates/class/_pvc.tpl similarity index 69% rename from charts/common/templates/classes/_pvc.tpl rename to charts/common/templates/class/_pvc.tpl index f677a27c..1fe87269 100644 --- a/charts/common/templates/classes/_pvc.tpl +++ b/charts/common/templates/class/_pvc.tpl @@ -2,14 +2,14 @@ This template serves as a blueprint for all PersistentVolumeClaim objects that are created within the common library. */}} -{{- define "common.classes.pvc" -}} +{{- define "tc.common.class.pvc" -}} {{- $values := .Values.persistence -}} {{- if hasKey . "ObjectValues" -}} {{- with .ObjectValues.persistence -}} {{- $values = . -}} {{- end -}} {{ end -}} -{{- $pvcName := include "common.names.fullname" . -}} +{{- $pvcName := include "tc.common.names.fullname" . -}} {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} {{- if not (eq $values.nameOverride "-") -}} {{- $pvcName = printf "%v-%v" $pvcName $values.nameOverride -}} @@ -28,14 +28,14 @@ metadata: {{- if $values.retain }} "helm.sh/resource-policy": keep {{- end }} - {{- with $values.annotations }} - {{- toYaml . | nindent 4 }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- end }} labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} {{- with $values.labels }} - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} spec: accessModes: @@ -43,8 +43,12 @@ spec: resources: requests: storage: {{ $values.size | default "999Gi" | quote }} - {{ include "common.storage.class" ( dict "persistence" $values "global" $ ) }} + {{- with $values.spec }} + {{ tpl ( toYaml . ) $ | indent 2 }} + {{- end }} + {{ include "tc.common.storage.class" ( dict "persistence" $values "global" $ ) }} {{- if $values.volumeName }} volumeName: {{ $values.volumeName | quote }} {{- end }} + {{- end -}} diff --git a/charts/common/templates/class/_rbac.tpl b/charts/common/templates/class/_rbac.tpl new file mode 100644 index 00000000..41d370cc --- /dev/null +++ b/charts/common/templates/class/_rbac.tpl @@ -0,0 +1,64 @@ +{{/* +This template serves as a blueprint for rbac objects that are created +using the common library. +*/}} +{{- define "tc.common.class.rbac" -}} + {{- $targetName := include "tc.common.names.fullname" . }} + {{- $fullName := include "tc.common.names.fullname" . -}} + {{- $rbacName := $fullName -}} + {{- $values := .Values.rbac -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.rbac -}} + {{- $values = . -}} + {{- end -}} + {{ end -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $rbacName = printf "%v-%v" $rbacName $values.nameOverride -}} + {{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ $rbacName }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} + {{- with $values.labels }} + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + annotations: + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} +{{- with $values.rules }} +rules: + {{- tpl ( toYaml . ) $ | nindent 4 }} +{{- end}} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ $rbacName }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} + {{- with $values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $rbacName }} +subjects: + - kind: ServiceAccount + name: {{ default (include "tc.common.names.serviceAccountName" .) $values.serviceAccountName }} + namespace: {{ .Release.Namespace }} + {{- with $values.subjects }} + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/class/_secret.tpl b/charts/common/templates/class/_secret.tpl new file mode 100644 index 00000000..5ff87636 --- /dev/null +++ b/charts/common/templates/class/_secret.tpl @@ -0,0 +1,35 @@ +{{/* +This template serves as a blueprint for all secret objects that are created +within the common library. +*/}} +{{- define "tc.common.class.secret" -}} + {{- $fullName := include "tc.common.names.fullname" . -}} + {{- $secretName := $fullName -}} + {{- $values := .Values.secret -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.secret -}} + {{- $values = . -}} + {{- end -}} + {{ end -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $secretName = printf "%v-%v" $secretName $values.nameOverride -}} + {{- end }} +--- +apiVersion: v1 +kind: secret +metadata: + name: {{ $secretName }} + {{- with (merge ($values.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + annotations: + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} +stringData: +{{- with $values.data }} + {{- tpl (toYaml .) $ | nindent 2 }} +{{- end }} +{{- end }} diff --git a/charts/common/templates/classes/_service.tpl b/charts/common/templates/class/_service.tpl similarity index 82% rename from charts/common/templates/classes/_service.tpl rename to charts/common/templates/class/_service.tpl index f9fb561a..9e22a023 100644 --- a/charts/common/templates/classes/_service.tpl +++ b/charts/common/templates/class/_service.tpl @@ -2,7 +2,7 @@ This template serves as a blueprint for all Service objects that are created within the common library. */}} -{{- define "common.classes.service" -}} +{{- define "tc.common.class.service" -}} {{- $values := .Values.service -}} {{- if hasKey . "ObjectValues" -}} {{- with .ObjectValues.service -}} @@ -10,31 +10,29 @@ within the common library. {{- end -}} {{ end -}} -{{- $serviceName := include "common.names.fullname" . -}} +{{- $serviceName := include "tc.common.names.fullname" . -}} {{- 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)) }} +{{- $primaryPort := get $values.ports (include "tc.common.lib.util.service.ports.primary" (dict "values" $values)) }} --- apiVersion: v1 kind: Service metadata: name: {{ $serviceName }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- if $values.labels }} - {{ toYaml $values.labels | nindent 4 }} + {{- with (merge ($values.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} annotations: {{- if eq ( $primaryPort.protocol | default "" ) "HTTPS" }} traefik.ingress.kubernetes.io/service.serversscheme: https {{- end }} {{- if eq ( $svcType | default "" ) "LoadBalancer" }} - metallb.universe.tf/allow-shared-ip: {{ include "common.names.fullname" . }} + metallb.universe.tf/allow-shared-ip: {{ include "tc.common.names.fullname" . }} {{- end }} - {{- with $values.annotations }} - {{ toYaml . | nindent 4 }} + {{- with (merge ($values.annotations | default dict) (include "tc.common.annotations" $ | fromYaml)) }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} spec: {{- if (or (eq $svcType "ClusterIP") (empty $svcType)) }} @@ -51,9 +49,6 @@ spec: {{- if $values.loadBalancerIP }} loadBalancerIP: {{ $values.loadBalancerIP }} {{- end }} - {{- if $values.externalTrafficPolicy }} - externalTrafficPolicy: {{ $values.externalTrafficPolicy }} - {{- end }} {{- if $values.loadBalancerSourceRanges }} loadBalancerSourceRanges: {{ toYaml $values.loadBalancerSourceRanges | nindent 4 }} @@ -61,6 +56,9 @@ spec: {{- else }} type: {{ $svcType }} {{- end }} + {{- if $values.externalTrafficPolicy }} + externalTrafficPolicy: {{ $values.externalTrafficPolicy }} + {{- end }} {{- if $values.sessionAffinity }} sessionAffinity: {{ $values.sessionAffinity }} {{- if $values.sessionAffinityConfig }} @@ -109,7 +107,7 @@ spec: {{- tpl (toYaml .) $ | nindent 4 }} {{- end }} {{- else }} - {{- include "common.labels.selectorLabels" . | nindent 4 }} + {{- include "tc.common.labels.selectorLabels" . | nindent 4 }} {{- end }} {{- end }} {{- if eq $svcType "ExternalIP" }} @@ -119,7 +117,7 @@ kind: Endpoints metadata: name: {{ $serviceName }} labels: - {{- include "common.labels" $ | nindent 4 }} + {{- include "tc.common.labels" $ | nindent 4 }} subsets: - addresses: - ip: {{ $values.externalIP }} diff --git a/charts/common/templates/class/_serviceaccount.tpl b/charts/common/templates/class/_serviceaccount.tpl new file mode 100644 index 00000000..cb5d089a --- /dev/null +++ b/charts/common/templates/class/_serviceaccount.tpl @@ -0,0 +1,31 @@ +{{/* +This template serves as a blueprint for ServiceAccount objects that are created +using the common library. +*/}} +{{- define "tc.common.class.serviceaccount" -}} + {{- $targetName := include "tc.common.names.fullname" . }} + {{- $fullName := include "tc.common.names.fullname" . -}} + {{- $saName := $fullName -}} + {{- $values := .Values.serviceAccount -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.serviceAccount -}} + {{- $values = . -}} + {{- end -}} + {{ end -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $saName = printf "%v-%v" $saName $values.nameOverride -}} + {{- end }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $saName }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} + {{- with $values.serviceAccount.annotations }} + annotations: + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/lib/chart/_annotations.tpl b/charts/common/templates/lib/chart/_annotations.tpl index 12a0a543..538ac0e2 100644 --- a/charts/common/templates/lib/chart/_annotations.tpl +++ b/charts/common/templates/lib/chart/_annotations.tpl @@ -1,11 +1,21 @@ {{/* Common annotations shared across objects */}} -{{- define "common.annotations.workload.spec" -}} -rollme: {{ randAlphaNum 5 | quote }} +{{- define "tc.common.annotations" -}} + {{- with .Values.global.annotations }} + {{- range $k, $v := . }} + {{- $name := $k }} + {{- $value := tpl $v $ }} +{{ $name }}: {{ quote $value }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* Annotations on all workload spec objects */}} +{{- define "tc.common.annotations.workload.spec" -}} {{- if .Values.ixExternalInterfacesConfigurationNames }} k8s.v1.cni.cncf.io/networks: {{ join ", " .Values.ixExternalInterfacesConfigurationNames }} {{- end }} {{- end -}} -{{- define "common.annotations.workload" -}} -rollme: {{ randAlphaNum 5 | quote }} +{{/* Annotations on all workload objects */}} +{{- define "tc.common.annotations.workload" -}} {{- end -}} diff --git a/charts/common/templates/lib/chart/_capabilities.tpl b/charts/common/templates/lib/chart/_capabilities.tpl index 96de3c10..075f288b 100644 --- a/charts/common/templates/lib/chart/_capabilities.tpl +++ b/charts/common/templates/lib/chart/_capabilities.tpl @@ -1,19 +1,19 @@ {{/* Allow KubeVersion to be overridden. */}} -{{- define "common.capabilities.ingress.kubeVersion" -}} +{{- define "tc.common.capabilities.ingress.kubeVersion" -}} {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride -}} {{- end -}} {{/* Return the appropriate apiVersion for Ingress objects */}} -{{- define "common.capabilities.ingress.apiVersion" -}} +{{- define "tc.common.capabilities.ingress.apiVersion" -}} {{- print "networking.k8s.io/v1" -}} - {{- if semverCompare "<1.19" (include "common.capabilities.ingress.kubeVersion" .) -}} + {{- if semverCompare "<1.19" (include "tc.common.capabilities.ingress.kubeVersion" .) -}} {{- print "beta1" -}} {{- end -}} {{- end -}} {{/* Check Ingress stability */}} -{{- define "common.capabilities.ingress.isStable" -}} - {{- if eq (include "common.capabilities.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- define "tc.common.capabilities.ingress.isStable" -}} + {{- if eq (include "tc.common.capabilities.ingress.apiVersion" .) "networking.k8s.io/v1" -}} {{- true -}} {{- end -}} {{- end -}} diff --git a/charts/common/templates/lib/chart/_labels.tpl b/charts/common/templates/lib/chart/_labels.tpl index 8a1e11aa..81db6850 100644 --- a/charts/common/templates/lib/chart/_labels.tpl +++ b/charts/common/templates/lib/chart/_labels.tpl @@ -1,15 +1,23 @@ {{/* Common labels shared across objects */}} -{{- define "common.labels" -}} -helm.sh/chart: {{ include "common.names.chart" . }} -{{ include "common.labels.selectorLabels" . }} - {{- if .Chart.AppVersion }} +{{- define "tc.common.labels" -}} +helm.sh/chart: {{ include "tc.common.names.chart" . }} +{{ include "tc.common.labels.selectorLabels" . }} +{{- if .Chart.AppVersion }} +helm-revision: "{{ .Release.Revision }}" app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} - {{- end }} +{{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.global.labels }} + {{- range $k, $v := . }} + {{- $name := $k }} + {{- $value := tpl $v $ }} +{{ $name }}: {{ quote $value }} + {{- end }} +{{- end }} {{- end -}} {{/* Selector labels shared across objects */}} -{{- define "common.labels.selectorLabels" -}} -app.kubernetes.io/name: {{ include "common.names.name" . }} +{{- define "tc.common.labels.selectorLabels" -}} +app.kubernetes.io/name: {{ include "tc.common.names.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end -}} diff --git a/charts/common/templates/lib/chart/_names.tpl b/charts/common/templates/lib/chart/_names.tpl index 86d573f3..39baaa0a 100644 --- a/charts/common/templates/lib/chart/_names.tpl +++ b/charts/common/templates/lib/chart/_names.tpl @@ -1,5 +1,5 @@ {{/* Expand the name of the chart */}} -{{- define "common.names.name" -}} +{{- define "tc.common.names.name" -}} {{- $globalNameOverride := "" -}} {{- if hasKey .Values "global" -}} {{- $globalNameOverride = (default $globalNameOverride .Values.global.nameOverride) -}} @@ -12,8 +12,8 @@ Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} -{{- define "common.names.fullname" -}} - {{- $name := include "common.names.name" . -}} +{{- define "tc.common.names.fullname" -}} + {{- $name := include "tc.common.names.name" . -}} {{- $globalFullNameOverride := "" -}} {{- if hasKey .Values "global" -}} {{- $globalFullNameOverride = (default $globalFullNameOverride .Values.global.fullnameOverride) -}} @@ -31,21 +31,21 @@ If release name contains chart name it will be used as a full name. {{- end -}} {{/* Create chart name and version as used by the chart label */}} -{{- define "common.names.chart" -}} +{{- define "tc.common.names.chart" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} {{/* Create the name of the ServiceAccount to use */}} -{{- define "common.names.serviceAccountName" -}} +{{- define "tc.common.names.serviceAccountName" -}} {{- if .Values.serviceAccount.create -}} - {{- default (include "common.names.fullname" .) .Values.serviceAccount.name -}} + {{- default (include "tc.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" -}} +{{- define "tc.common.names.controllerType" -}} {{- if eq .Values.controller.type "deployment" -}} {{- print "Deployment" -}} {{- else if eq .Values.controller.type "daemonset" -}} @@ -60,6 +60,6 @@ If release name contains chart name it will be used as a full name. {{/* Create the "name" + "." + "namespace" fqdn */}} -{{- define "common.names.fqdn" -}} -{{- printf "%s.%s" (include "common.names.fullname" .) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- define "tc.common.names.fqdn" -}} +{{- printf "%s.%s" (include "tc.common.names.fullname" .) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- end -}} diff --git a/charts/common/templates/lib/chart/_setup.tpl b/charts/common/templates/lib/chart/_setup.tpl deleted file mode 100644 index dcdb4523..00000000 --- a/charts/common/templates/lib/chart/_setup.tpl +++ /dev/null @@ -1,17 +0,0 @@ -{{- define "common.setup" -}} - -{{- /* Merge the local chart values and the common chart defaults */ -}} -{{- include "common.values" . }} - -{{- /* Autogenerate postgresql passwords if needed */ -}} -{{- include "common.dependencies.postgresql.injector" . }} - -{{- /* Autogenerate redis passwords if needed */ -}} -{{- include "common.dependencies.redis.injector" . }} - -{{- /* Autogenerate mariadb passwords if needed */ -}} -{{- include "common.dependencies.mariadb.injector" . }} - -{{- /* Autogenerate mongodb passwords if needed */ -}} -{{- include "common.dependencies.mongodb.injector" . }} -{{- end -}} diff --git a/charts/common/templates/lib/chart/_values.tpl b/charts/common/templates/lib/chart/_values.tpl deleted file mode 100644 index 7b8371d7..00000000 --- a/charts/common/templates/lib/chart/_values.tpl +++ /dev/null @@ -1,283 +0,0 @@ -{{/* Merge the local chart values and the common chart defaults */}} -{{- define "common.values" -}} - {{- if .Values.common -}} - {{- $defaultValues := deepCopy .Values.common -}} - {{- $userValues := deepCopy (omit .Values "common") -}} - {{- $mergedValues := mustMergeOverwrite $defaultValues $userValues -}} - {{- $_ := set . "Values" (deepCopy $mergedValues) -}} - {{- end -}} - - {{/* merge podAnnotationsList with podAnnotations */}} - {{- $podAnnotationsDict := dict }} - {{- range .Values.podAnnotationsList }} - {{- $_ := set $podAnnotationsDict .name .value }} - {{- end }} - {{- $podanno := merge .Values.podAnnotations $podAnnotationsDict }} - {{- $_ := set .Values "podAnnotations" (deepCopy $podanno) -}} - - {{/* merge podLabelsList with podLabels */}} - {{- $podLabelsDict := dict }} - {{- range .Values.controller.labelsList }} - {{- $_ := set $podLabelsDict .name .value }} - {{- end }} - {{- $podlab := merge .Values.controller.labels $podLabelsDict }} - {{- $_ := set .Values.controller "labels" (deepCopy $podlab) -}} - - {{/* merge controllerAnnotationsList with controllerAnnotations */}} - {{- $controllerAnnotationsDict := dict }} - {{- range .Values.controller.annotationsList }} - {{- $_ := set $controllerAnnotationsDict .name .value }} - {{- end }} - {{- $controlleranno := merge .Values.controller.annotations $controllerAnnotationsDict }} - {{- $_ := set .Values.controller "annotations" (deepCopy $controlleranno) -}} - - {{/* merge controllerLabelsList with controllerLabels */}} - {{- $controllerLabelsDict := dict }} - {{- range .Values.controller.labelsList }} - {{- $_ := set $controllerLabelsDict .name .value }} - {{- end }} - {{- $controllerlab := merge .Values.controller.labels $controllerLabelsDict }} - {{- $_ := set .Values "labels" (deepCopy $controllerlab) -}} - - - - {{/* merge persistenceList with Persitence */}} - {{- $perDict := dict }} - {{- range $index, $item := .Values.persistenceList -}} - {{- $name := ( printf "list-%s" ( $index | toString ) ) }} - {{- if $item.name }} - {{- $name = $item.name }} - {{- end }} - {{- $_ := set $perDict $name $item }} - {{- end }} - - {{/* merge deviceList with Persitence */}} - {{- range $index, $item := .Values.deviceList -}} - {{- $name := ( printf "device-%s" ( $index | toString ) ) }} - {{- if $item.name }} - {{- $name = $item.name }} - {{- end }} - {{- $_ := set $perDict $name $item }} - {{- end }} - {{- $per := merge .Values.persistence $perDict }} - {{- $_ := set .Values "persistence" (deepCopy $per) -}} - - - {{/* merge persistenceAnnotationsList with persistenceAnnotations */}} - {{- range $index, $item := .Values.persistence }} - {{- if $item.enabled }} - {{- $persistenceAnnotationsDict := dict }} - {{- range $item.annotationsList }} - {{- $_ := set $persistenceAnnotationsDict .name .value }} - {{- end }} - {{- $tmp := $item.annotations }} - {{- $persistenceanno := merge $tmp $persistenceAnnotationsDict }} - {{- $_ := set $item "annotations" (deepCopy $persistenceanno) -}} - {{- end }} - {{- end }} - - - {{/* merge persistenceLabelsList with persistenceLabels */}} - {{- range $index, $item := .Values.persistence }} - {{- if $item.enabled }} - {{- $persistenceLabelsDict := dict }} - {{- range $item.labelsList }} - {{- $_ := set $persistenceLabelsDict .name .value }} - {{- end }} - {{- $tmp := $item.labels }} - {{- $persistencelab := merge $tmp $persistenceLabelsDict }} - {{- $_ := set $item "labels" (deepCopy $persistencelab) -}} - {{- end }} - {{- end }} - - {{/* merge ingressList with ingress */}} - {{- $ingDict := dict }} - {{- range $index, $item := .Values.ingressList -}} - {{- $name := ( printf "list-%s" ( $index | toString ) ) }} - {{- if $item.name }} - {{- $name = $item.name }} - {{- end }} - {{- $_ := set $ingDict $name $item }} - {{- end }} - {{- $ing := merge .Values.ingress $ingDict }} - {{- $_ := set .Values "ingress" (deepCopy $ing) -}} - - - {{/* merge ingressAnnotationsList with ingressAnnotations */}} - {{- range $index, $item := .Values.ingress }} - {{- if $item.enabled }} - {{- $ingressAnnotationsDict := dict }} - {{- range $item.annotationsList }} - {{- $_ := set $ingressAnnotationsDict .name .value }} - {{- end }} - {{- $tmp := $item.annotations }} - {{- $ingressanno := merge $tmp $ingressAnnotationsDict }} - {{- $_ := set $item "annotations" (deepCopy $ingressanno) -}} - {{- end }} - {{- end }} - - - {{/* merge ingressLabelsList with ingressLabels */}} - {{- range $index, $item := .Values.ingress }} - {{- if $item.enabled }} - {{- $ingressLabelsDict := dict }} - {{- range $item.labelsList }} - {{- $_ := set $ingressLabelsDict .name .value }} - {{- end }} - {{- $tmp := $item.labels }} - {{- $ingresslab := merge $tmp $ingressLabelsDict }} - {{- $_ := set $item "labels" (deepCopy $ingresslab) -}} - {{- end }} - {{- end }} - - {{/* Enable privileged securitycontext when deviceList is used */}} - {{- if .Values.securityContext.privileged }} - {{- else if .Values.deviceList }} - {{- $_ := set .Values.securityContext "privileged" true -}} - {{- $_ := set .Values.securityContext "allowPrivilegeEscalation" true -}} - {{- end }} - - - {{/* save supplementalGroups to placeholder variables */}} - {{- $fixedGroups := list 568 }} - {{- $valuegroups := list }} - {{- $devGroups := list }} - {{- $gpuGroups := list }} - - {{/* put user-entered supplementalgroups in placeholder variable */}} - {{- if .Values.podSecurityContext.supplementalGroups }} - {{- $valuegroups = .Values.podSecurityContext.supplementalGroups }} - {{- end }} - - {{/* Append requered groups to supplementalGroups when deviceList is used */}} - {{- if .Values.deviceList}} - {{- $devGroups = list 5 10 20 24 }} - {{- end }} - - {{/* Append requered groups to supplementalGroups when scaleGPU is used */}} - {{- if .Values.scaleGPU }} - {{- $gpuGroups = list 44 107 }} - {{- end }} - - {{/* combine and write all supplementalGroups to .Values */}} - {{- $supGroups := concat $fixedGroups $valuegroups $devGroups $gpuGroups }} - {{- $_ := set .Values.podSecurityContext "supplementalGroups" $supGroups -}} - - {{/* merge serviceList with service */}} - {{- $portsDict := dict }} - {{- range $index, $item := .Values.serviceList -}} - {{- if $item.enabled }} - {{- $name := ( printf "list-%s" ( $index | toString ) ) }} - {{- if $item.name }} - {{- $name = $item.name }} - {{- end }} - {{- $_ := set $portsDict $name $item }} - {{- end }} - {{- end }} - {{- $srv := merge .Values.service $portsDict }} - {{- $_ := set .Values "service" (deepCopy $srv) -}} - - {{/* merge portsList with ports */}} - {{- range $index, $item := .Values.service -}} - {{- if $item.enabled }} - {{- $portsDict := dict }} - {{- range $index2, $item2 := $item.portsList -}} - {{- if $item2.enabled }} - {{- $name := ( printf "list-%s" ( $index2 | toString ) ) }} - {{- if $item2.name }} - {{- $name = $item2.name }} - {{- end }} - {{- $_ := set $portsDict $name $item2 }} - {{- end }} - {{- $tmp := $item.ports }} - {{- $ports := merge $tmp $portsDict }} - {{- $_ := set $item "ports" (deepCopy $ports) -}} - {{- end }} - {{- end }} - {{- end }} - - - {{/* automatically set CAP_NET_BIND_SERVICE */}} - {{- $fixedCapAdd := list }} - {{- $customCapAdd := list }} - {{- $valueCapAdd := list }} - {{- $dynamicCapAdd := list }} - {{- $fixedCapDrop := list }} - {{- $customCapDrop := list }} - {{- $valueCapDrop := list }} - {{- $dynamicCapDrop := list }} - {{- if .Values.securityContext.capabilities.add }} - {{- $valueCapAdd = .Values.securityContext.capabilities.add }} - {{- end }} - {{- if .Values.securityContext.capabilities.drop }} - {{- $valueCapDrop = .Values.securityContext.capabilities.drop }} - {{- end }} - {{- if .Values.customCapabilities.add }} - {{- $customCapAdd = .Values.customCapabilities.add }} - {{- end }} - {{- if .Values.customCapabilities.drop }} - {{- $customCapDrop = .Values.customCapabilities.drop }} - {{- end }} - - {{- $privPort := false }} - {{- range .Values.service }} - {{- range $name, $values := .ports }} - {{- if and ( $values.targetPort ) ( kindIs "int" $values.targetPort ) }} - {{- if ( semverCompare "<= 1024" ( toString $values.targetPort ) ) }} - {{- $privPort = true }} - {{- end }} - {{- else if and ( $values.port ) ( kindIs "int" $values.port ) }} - {{- if ( semverCompare "<= 1024" ( toString $values.port ) ) }} - {{- $privPort = true }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - - {{- if or ( $privPort ) ( .Values.hostNetwork ) }} - {{- $dynamicCapAdd = list "NET_BIND_SERVICE" }} - {{- end }} - - {{/* combine and write all capabilities to .Values */}} - {{- $CapAdd := concat $fixedCapAdd $valueCapAdd $dynamicCapAdd }} - {{- $CapDrop := concat $fixedCapDrop $valueCapDrop $dynamicCapDrop }} - {{- if $CapDrop }} - {{- $_ := set .Values.securityContext.capabilities "drop" $CapDrop -}} - {{- end }} - {{- if $CapAdd }} - {{- $_ := set .Values.securityContext.capabilities "add" $CapAdd -}} - {{- end }} - - {{- range .Values.persistence }} - {{- if .type }} - {{- if eq .type "simplePVC" }} - {{- $_ := set . "type" "pvc" }} - {{- end }} - {{- if eq .type "simpleHP" }} - {{- $_ := set . "type" "hostPath" }} - {{- if .setPermissionsSimple }} - {{- $_ := set . "setPermissions" .setPermissionsSimple }} - {{- end }} - {{- if .hostPathSimple }} - {{- $_ := set . "hostPath" .hostPathSimple }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - - {{- range .Values.volumeClaimTemplates }} - {{- if .type }} - {{- if eq .type "simplePVC" }} - {{- $_ := set . "type" "pvc" }} - {{- end }} - {{- end }} - {{- end }} - - {{- range .Values.service }} - {{- if .type }} - {{- if eq .type "Simple" }} - {{- $_ := set . "type" "LoadBalancer" }} - {{- end }} - {{- end }} - {{- end }} -{{- end -}} diff --git a/charts/common/templates/lib/controller/_autopermissions.tpl b/charts/common/templates/lib/controller/_autopermissions.tpl deleted file mode 100644 index a40199af..00000000 --- a/charts/common/templates/lib/controller/_autopermissions.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{{/* -This template serves as the blueprint for the mountPermissions job that is run -before chart installation. -*/}} -{{- define "common.controller.autopermissions" -}} -{{- $group := .Values.podSecurityContext.fsGroup -}} -{{- $hostPathMounts := dict -}} -{{- range $name, $mount := .Values.persistence -}} - {{- if and $mount.enabled $mount.setPermissions -}} - {{- $name = default ( $name| toString ) $mount.name -}} - {{- $_ := set $hostPathMounts $name $mount -}} - {{- end -}} -{{- end }} -- name: autopermissions - image: {{ .Values.alpineImage.repository }}:{{ .Values.alpineImage.tag }} - securityContext: - runAsUser: 0 - privileged: false - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - resources: - {{- with .Values.resources }} - {{- toYaml . | nindent 4 }} - {{- end }} - command: - - "/bin/sh" - - "-c" - - "echo 'Automatically correcting permissions...';{{ if and ( .Values.addons.vpn.configFile.enabled ) ( not ( eq .Values.addons.vpn.type "disabled" )) }}chown -R 568:568 /vpn/vpn.conf; chmod -R g+w /vpn/vpn.conf || echo 'chmod failed for vpn config, are you running NFSv4 ACLs?';{{ end }}{{ range $_, $hpm := $hostPathMounts }}chown -R :{{ $group }} {{ $hpm.mountPath | squote }}; chmod -R g+w || echo 'chmod failed for {{ $hpm.mountPath }}, are you running NFSv4 ACLs?' {{ $hpm.mountPath | squote }};{{ end }}" - volumeMounts: - {{- if and ( .Values.addons.vpn.configFile.enabled ) ( not ( eq .Values.addons.vpn.type "disabled" )) }} - - name: vpnconfig - mountPath: /vpn/vpn.conf - {{- end }} - {{- range $name, $hpm := $hostPathMounts }} - - name: {{ $name }} - mountPath: {{ $hpm.mountPath }} - {{- if $hpm.subPath }} - subPath: {{ $hpm.subPath }} - {{- end }} - {{- end }} -{{- end -}} diff --git a/charts/common/templates/lib/controller/_container.tpl b/charts/common/templates/lib/controller/_container.tpl index abdb30b2..facef2a5 100644 --- a/charts/common/templates/lib/controller/_container.tpl +++ b/charts/common/templates/lib/controller/_container.tpl @@ -1,12 +1,12 @@ {{- /* The main container included in the controller */ -}} -{{- define "common.controller.mainContainer" -}} -- name: {{ include "common.names.fullname" . }} - image: {{ include "common.images.selector" . }} +{{- define "tc.common.controller.mainContainer" -}} +- name: {{ include "tc.common.names.fullname" . }} + image: {{ include "tc.common.images.selector" . }} imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.command }} command: {{- if kindIs "string" . }} - - {{ . }} + - {{ tpl . $ }} {{- else }} {{ toYaml . | nindent 4 }} {{- end }} @@ -15,53 +15,57 @@ args: {{- with .Values.args }} {{- if kindIs "string" . }} - - {{ . }} + - {{ tpl . $ }} {{- else }} - {{ toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- end }} {{- with .Values.extraArgs }} {{- if kindIs "string" . }} - - {{ . }} + - {{ tpl . $ }} {{- else }} - {{ toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- end }} {{- end }} - tty: {{ .Values.tty }} - stdin: {{ .Values.stdin }} + {{- with .Values.tty }} + tty: {{ tpl . $ }} + {{- end }} + {{- with .Values.stdin }} + stdin: {{ tpl . $ }} + {{- end }} {{- with .Values.securityContext }} securityContext: - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- with .Values.lifecycle }} lifecycle: - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- with .Values.termination.messagePath }} - terminationMessagePath: {{ . }} + terminationMessagePath: {{ tpl . $ }} {{- end }} {{- with .Values.termination.messagePolicy }} - terminationMessagePolicy: {{ . }} + terminationMessagePolicy: {{ tpl . $ }} {{- end }} env: - name: PUID - value: {{ .Values.security.PUID | quote }} + value: {{ tpl ( toYaml .Values.security.PUID ) $ | quote }} - name: USER_ID - value: {{ .Values.security.PUID | quote }} + value: {{ tpl ( toYaml .Values.security.PUID ) $ | quote }} - name: UID - value: {{ .Values.security.PUID | quote }} + value: {{ tpl ( toYaml .Values.security.PUID ) $ | quote }} - name: UMASK - value: {{ .Values.security.UMASK | quote }} + value: {{ tpl ( toYaml .Values.security.UMASK ) $ | quote }} - name: UMASK_SET - value: {{ .Values.security.UMASK | quote }} + value: {{ tpl ( toYaml .Values.security.UMASK ) $ | quote }} - name: PGID - value: {{ .Values.podSecurityContext.fsGroup | quote }} + value: {{ tpl ( toYaml .Values.podSecurityContext.fsGroup ) $ | quote }} - name: GROUP_ID - value: {{ .Values.podSecurityContext.fsGroup | quote }} + value: {{ tpl ( toYaml .Values.podSecurityContext.fsGroup ) $ | quote }} - name: GID - value: {{ .Values.podSecurityContext.fsGroup | quote }} + value: {{ tpl ( toYaml .Values.podSecurityContext.fsGroup ) $ | quote }} {{- if or ( .Values.securityContext.readOnlyRootFilesystem ) ( .Values.securityContext.runAsNonRoot ) }} - name: S6_READ_ONLY_ROOT value: "1" @@ -74,7 +78,7 @@ value: "all" {{- end }} - name: TZ - value: {{ .Values.TZ | quote }} + value: {{ tpl ( toYaml .Values.TZ ) $ | quote }} {{- with .Values.env }} {{- range $k, $v := . }} {{- $name := $k }} @@ -87,7 +91,7 @@ {{- if hasKey $value "value" }} {{- $value = $value.value -}} {{- else if hasKey $value "valueFrom" }} - {{- toYaml $value | nindent 6 }} + {{- dict "valueFrom" $value.valueFrom | toYaml | nindent 6 }} {{- else }} {{- dict "valueFrom" $value | toYaml | nindent 6 }} {{- end }} @@ -100,10 +104,6 @@ {{- end }} {{- end }} {{- end }} - {{- range $key, $value := .Values.envTpl }} - - name: {{ $key }} - value: {{ tpl $value $ | quote }} - {{- end }} {{- range $key, $value := .Values.envValueFrom }} - name: {{ $key }} valueFrom: @@ -128,7 +128,7 @@ {{- end }} {{- end}} envFrom: - {{- range .Values.envFrom -}} + {{- range .Values.envFrom }} {{- if .secretRef }} - secretRef: name: {{ tpl .secretRef.name $ | quote }} @@ -137,18 +137,18 @@ name: {{ tpl .configMapRef.name $ | quote }} {{- else }} {{- end }} - {{- end -}} - {{- if .Values.secret }} - - secretRef: - name: {{ include "common.names.fullname" . }} + {{- end }} + {{- if .Values.secretEnv }} + - secretRef: + name: {{ include "tc.common.names.fullname" . }} {{- end }} ports: - {{- include "common.controller.ports" . | trim | nindent 4 }} - {{- with (include "common.controller.volumeMounts" . | trim) }} + {{- include "tc.common.controller.ports" . | trim | nindent 4 }} + {{- with (include "tc.common.controller.volumeMounts" . | trim) }} volumeMounts: {{ nindent 4 . }} {{- end }} - {{- include "common.controller.probes" . | trim | nindent 2 }} + {{- include "tc.common.controller.probes" . | trim | nindent 2 }} {{/* Merges the TrueNAS SCALE generated GPU info with the .Values.resources dict */}} diff --git a/charts/common/templates/lib/controller/_hostpatch.tpl b/charts/common/templates/lib/controller/_hostpatch.tpl deleted file mode 100644 index 2ab164c5..00000000 --- a/charts/common/templates/lib/controller/_hostpatch.tpl +++ /dev/null @@ -1,21 +0,0 @@ -{{/* -This template serves as the blueprint for the mountPermissions job that is run -before chart installation. -TODO: delete docker compose deletion once iX has disabled it -*/}} -{{- define "common.controller.hostpatch" -}} -- name: hostpatch - image: {{ .Values.alpineImage.repository }}:{{ .Values.alpineImage.tag }} - securityContext: - runAsUser: 0 - privileged: true - command: - - "/bin/sh" - - "-c" - - ( sysctl -w fs.inotify.max_user_watches=524288 || echo "error setting inotify") && ( sysctl -w fs.inotify.max_user_instances=512 || echo "error setting inotify") && ( chmod -x /host/usr/bin/docker-compose || echo "error locking docker-compose") && ( chmod -x /host/bin/docker-compose || echo "error locking docker-compose") - volumeMounts: - - mountPath: /host/usr/bin - name: host-usr-bin - - mountPath: /host/bin - name: host-bin -{{- end -}} diff --git a/charts/common/templates/lib/controller/_pod.tpl b/charts/common/templates/lib/controller/_pod.tpl index 183acdee..e1f63e8d 100644 --- a/charts/common/templates/lib/controller/_pod.tpl +++ b/charts/common/templates/lib/controller/_pod.tpl @@ -1,27 +1,27 @@ {{- /* The pod definition included in the controller. */ -}} -{{- define "common.controller.pod" -}} +{{- define "tc.common.controller.pod" -}} {{- with .Values.imagePullSecrets }} imagePullSecrets: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} -serviceAccountName: {{ include "common.names.serviceAccountName" . }} +serviceAccountName: {{ include "tc.common.names.serviceAccountName" . }} {{- with .Values.podSecurityContext }} securityContext: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- with .Values.priorityClassName }} -priorityClassName: {{ . }} +priorityClassName: {{ tpl . $ }} {{- end }} {{- with .Values.schedulerName }} -schedulerName: {{ . }} +schedulerName: {{ tpl . $ }} {{- end }} {{- with .Values.hostNetwork }} hostNetwork: {{ . }} {{- end }} {{- with .Values.hostname }} -hostname: {{ . }} +hostname: {{ tpl . $ }} {{- end }} {{- if .Values.dnsPolicy }} dnsPolicy: {{ .Values.dnsPolicy }} @@ -34,15 +34,15 @@ dnsPolicy: ClusterFirst dnsConfig: {{- with .Values.dnsConfig.options }} options: - {{- toYaml . | nindent 4 }} + {{ tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- with .Values.dnsConfig.nameservers }} nameservers: [] - {{- toYaml . | nindent 4 }} + {{ tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- with .Values.dnsConfig.searches }} searches: [] - {{- toYaml . | nindent 4 }} + {{ tpl ( toYaml . ) $ | nindent 4 }} {{- end }} {{- end }} enableServiceLinks: {{ .Values.enableServiceLinks }} @@ -50,13 +50,11 @@ enableServiceLinks: {{ .Values.enableServiceLinks }} terminationGracePeriodSeconds: {{ . }} {{- end }} initContainers: - {{- include "common.controller.autopermissions" . | nindent 2 }} - {{- include "common.controller.hostpatch" . | nindent 2 }} - {{- include "common.dependencies.postgresql.init" . | nindent 2 }} - {{- include "common.dependencies.mariadb.init" . | nindent 2 }} - {{- include "common.dependencies.mongodb.init" . | nindent 2 }} - {{- if .Release.IsInstall }} - {{- if .Values.installContainers }} + {{- include "tc.common.controller.prepare" . | nindent 2 }} + {{- include "tc.common.dependencies.postgresql.init" . | nindent 2 }} + {{- include "tc.common.dependencies.mariadb.init" . | nindent 2 }} + {{- include "tc.common.dependencies.mongodb.init" . | nindent 2 }} + {{- if and ( or ( .Release.IsInstall ) ( .Values.test.install ) ) ( .Values.installContainers )}} {{- $installContainers := list }} {{- range $index, $key := (keys .Values.installContainers | uniq | sortAlpha) }} {{- $container := get $.Values.installContainers $key }} @@ -67,9 +65,7 @@ initContainers: {{- end }} {{- tpl (toYaml $installContainers) $ | nindent 2 }} {{- end }} - {{- end }} - {{- if .Release.IsUpgrade }} - {{- if .Values.upgradeContainers }} + {{- if and ( or ( .Release.IsUpgrade ) ( .Values.test.upgrade ) ) ( .Values.upgradeContainers )}} {{- $upgradeContainers := list }} {{- range $index, $key := (keys .Values.upgradeContainers | uniq | sortAlpha) }} {{- $container := get $.Values.upgradeContainers $key }} @@ -80,7 +76,6 @@ initContainers: {{- end }} {{- tpl (toYaml $upgradeContainers) $ | nindent 2 }} {{- end }} - {{- end }} {{- if .Values.initContainers }} {{- $initContainers := list }} {{- range $index, $key := (keys .Values.initContainers | uniq | sortAlpha) }} @@ -93,7 +88,7 @@ initContainers: {{- tpl (toYaml $initContainers) $ | nindent 2 }} {{- end }} containers: - {{- include "common.controller.mainContainer" . | nindent 2 }} + {{- include "tc.common.controller.mainContainer" . | nindent 2 }} {{- with .Values.additionalContainers }} {{- $additionalContainers := list }} {{- range $name, $container := . }} @@ -104,28 +99,28 @@ containers: {{- end }} {{- tpl (toYaml $additionalContainers) $ | nindent 2 }} {{- end }} - {{- with (include "common.controller.volumes" . | trim) }} + {{- with (include "tc.common.controller.volumes" . | trim) }} volumes: {{- nindent 2 . }} {{- end }} {{- with .Values.hostAliases }} hostAliases: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- with .Values.nodeSelector }} nodeSelector: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- with .Values.affinity }} affinity: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- with .Values.topologySpreadConstraints }} topologySpreadConstraints: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- with .Values.tolerations }} tolerations: - {{- toYaml . | nindent 2 }} + {{ tpl ( toYaml . ) $ | nindent 2 }} {{- end }} {{- end -}} diff --git a/charts/common/templates/lib/controller/_ports.tpl b/charts/common/templates/lib/controller/_ports.tpl index 5394690c..9181d0d6 100644 --- a/charts/common/templates/lib/controller/_ports.tpl +++ b/charts/common/templates/lib/controller/_ports.tpl @@ -1,7 +1,7 @@ {{/* Ports included by the controller. */}} -{{- define "common.controller.ports" -}} +{{- define "tc.common.controller.ports" -}} {{- $ports := list -}} {{- range .Values.service -}} {{- if .enabled -}} @@ -16,7 +16,7 @@ Ports included by the controller. {{- if $ports -}} {{- range $_ := $ports }} {{- if .enabled }} -- name: {{ .name }} +- name: {{ tpl .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 }} @@ -25,7 +25,7 @@ Ports included by the controller. {{- if or ( eq .protocol "HTTP" ) ( eq .protocol "HTTPS" ) ( eq .protocol "TCP" ) }} protocol: TCP {{- else }} - protocol: {{ .protocol }} + protocol: {{ tpl .protocol $ }} {{- end }} {{- else }} protocol: TCP diff --git a/charts/common/templates/lib/controller/_prepare.tpl b/charts/common/templates/lib/controller/_prepare.tpl new file mode 100644 index 00000000..f2f34171 --- /dev/null +++ b/charts/common/templates/lib/controller/_prepare.tpl @@ -0,0 +1,70 @@ +{{/* +This template serves as the blueprint for the mountPermissions job that is run +before chart installation. +*/}} +{{- define "tc.common.controller.prepare" -}} +{{- $group := .Values.podSecurityContext.fsGroup -}} +{{- $hostPathMounts := dict -}} +{{- range $name, $mount := .Values.persistence -}} + {{- if and $mount.enabled $mount.setPermissions -}} + {{- $name = default ( $name| toString ) $mount.name -}} + {{- $_ := set $hostPathMounts $name $mount -}} + {{- end -}} +{{- end }} +- name: autopermissions + image: {{ .Values.alpineImage.repository }}:{{ .Values.alpineImage.tag }} + securityContext: + runAsUser: 0 + privileged: true + resources: + {{- with .Values.resources }} + {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + command: + - "/bin/sh" + - "-c" + - | + /bin/bash <<'EOF' + echo "Automatically correcting permissions..." + {{- if and ( .Values.addons.vpn.configFile.enabled ) ( not ( eq .Values.addons.vpn.type "disabled" )) }} + echo "Automatically correcting permissions for vpn config file..." + if nfs4xdr_getfacl && nfs4xdr_getfacl | grep -qv "Failed to get NFSv4 ACL"; then + echo "NFSv4 ACLs detected, using nfs4_setfacl to set permissions..." + nfs4_setfacl -a A::568:RWX /vpn/vpn.conf + nfs4_setfacl -a A:g:568:RWX /vpn/vpn.conf + else + echo "No NFSv4 ACLs detected, trying chown/chmod..." + chown -R 568:568 /vpn/vpn.conf + chmod -R g+w /vpn/vpn.conf + fi + {{- end }} + {{- range $_, $hpm := $hostPathMounts }} + echo "Automatically correcting permissions for {{ $hpm.mountPath }}..." + if nfs4xdr_getfacl && nfs4xdr_getfacl | grep -qv "Failed to get NFSv4 ACL"; then + echo "NFSv4 ACLs detected, using nfs4_setfacl to set permissions..." + nfs4_setfacl -R -a A:g:{{ $group }}:RWX {{ tpl $hpm.mountPath $ | squote }} + else + echo "No NFSv4 ACLs detected, trying chown/chmod..." + chown -R :{{ $group }} {{ tpl $hpm.mountPath $ | squote }} + chmod -R g+rwx {{ tpl $hpm.mountPath $ | squote }} + fi + {{- end }} + {{- if .Values.patchInotify }} + echo "increasing inotify limits..." + ( sysctl -w fs.inotify.max_user_watches=524288 || echo "error setting inotify") && ( sysctl -w fs.inotify.max_user_instances=512 || echo "error setting inotify") + {{- end }} + EOF + + volumeMounts: + {{- range $name, $hpm := $hostPathMounts }} + - name: {{ $name }} + mountPath: {{ $hpm.mountPath }} + {{- if $hpm.subPath }} + subPath: {{ $hpm.subPath }} + {{- end }} + {{- end }} + {{- if and ( .Values.addons.vpn.configFile.enabled ) ( not ( eq .Values.addons.vpn.type "disabled" )) }} + - name: vpnconfig + mountPath: /vpn/vpn.conf + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/controller/_probes.tpl b/charts/common/templates/lib/controller/_probes.tpl index 59583e8d..7f764c96 100644 --- a/charts/common/templates/lib/controller/_probes.tpl +++ b/charts/common/templates/lib/controller/_probes.tpl @@ -1,11 +1,11 @@ {{/* Probes selection logic. */}} -{{- define "common.controller.probes" -}} -{{- $primaryService := get .Values.service (include "common.service.primary" .) -}} +{{- define "tc.common.controller.probes" -}} +{{- $primaryService := get .Values.service (include "tc.common.lib.util.service.primary" .) -}} {{- $primaryPort := "" -}} {{- if $primaryService -}} - {{- $primaryPort = get $primaryService.ports (include "common.classes.service.ports.primary" (dict "serviceName" (include "common.service.primary" .) "values" $primaryService)) -}} + {{- $primaryPort = get $primaryService.ports (include "tc.common.lib.util.service.ports.primary" (dict "serviceName" (include "tc.common.lib.util.service.primary" .) "values" $primaryService)) -}} {{- end -}} {{- $probeType := "TCP" -}} diff --git a/charts/common/templates/lib/controller/_volumeMounts.tpl b/charts/common/templates/lib/controller/_volumeMounts.tpl index 7778f48d..52c02fd6 100644 --- a/charts/common/templates/lib/controller/_volumeMounts.tpl +++ b/charts/common/templates/lib/controller/_volumeMounts.tpl @@ -1,5 +1,5 @@ {{/* Volumes included by the controller */}} -{{- define "common.controller.volumeMounts" -}} +{{- define "tc.common.controller.volumeMounts" -}} {{- range $index, $item := .Values.persistence }} {{- if not $item.noMount }} {{- $mountPath := (printf "/%v" $index) -}} @@ -10,16 +10,16 @@ {{- $mountPath = . -}} {{- end }} {{- if and $item.enabled (ne $mountPath "-") }} -- mountPath: {{ $mountPath }} - name: {{ $index }} +- mountPath: {{ tpl $mountPath $ }} + name: {{ tpl $index $ }} {{- with $item.subPath }} - subPath: {{ . }} + subPath: {{ tpl . $ }} {{- end }} {{- with $item.readOnly }} readOnly: {{ . }} {{- end }} {{- with $item.mountPropagation }} - mountPropagation: {{ . }} + mountPropagation: {{ tpl . $ }} {{- end }} {{- end }} {{- end }} @@ -27,19 +27,11 @@ {{- if eq .Values.controller.type "statefulset" }} {{- range $index, $vct := .Values.volumeClaimTemplates }} - {{- $vctname := $index }} - {{- if $vct.name }} - {{- $vctname := $vct.name }} - {{- end }} - {{- if not $vct.noMount }} - mountPath: {{ $vct.mountPath }} - name: {{ $vctname }} + name: {{ $vct.name }} {{- if $vct.subPath }} subPath: {{ $vct.subPath }} {{- end }} {{- end }} - {{- end }} {{- end }} - - {{- end -}} diff --git a/charts/common/templates/lib/controller/_volumes.tpl b/charts/common/templates/lib/controller/_volumes.tpl index 742a8c7e..21a705b4 100644 --- a/charts/common/templates/lib/controller/_volumes.tpl +++ b/charts/common/templates/lib/controller/_volumes.tpl @@ -1,12 +1,12 @@ {{/* Volumes included by the controller. */}} -{{- define "common.controller.volumes" -}} +{{- define "tc.common.controller.volumes" -}} {{- range $index, $persistence := .Values.persistence }} {{- if $persistence.enabled }} -- name: {{ $index }} +- name: {{ tpl $index $ }} {{- if eq (default "pvc" $persistence.type) "pvc" }} - {{- $pvcName := (include "common.names.fullname" $) -}} + {{- $pvcName := (include "tc.common.names.fullname" $) -}} {{- if $persistence.existingClaim }} {{- /* Always prefer an existingClaim if that is set */}} {{- $pvcName = $persistence.existingClaim -}} @@ -14,17 +14,17 @@ Volumes included by the controller. {{- /* Otherwise refer to the PVC name */}} {{- if $persistence.nameOverride -}} {{- if not (eq $persistence.nameOverride "-") -}} - {{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $persistence.nameOverride) -}} + {{- $pvcName = (printf "%s-%s" (include "tc.common.names.fullname" $) $persistence.nameOverride) -}} {{- end -}} {{- else -}} - {{- $pvcName = (printf "%s-%s" (include "common.names.fullname" $) $index) -}} + {{- $pvcName = (printf "%s-%s" (include "tc.common.names.fullname" $) $index) -}} {{- end -}} {{- if $persistence.forceName -}} {{- $pvcName = $persistence.forceName -}} {{- end -}} {{- end }} persistentVolumeClaim: - claimName: {{ $pvcName }} + claimName: {{ tpl $pvcName $ }} {{- else if eq $persistence.type "emptyDir" }} {{- $emptyDir := dict -}} {{- with $persistence.medium -}} @@ -33,7 +33,7 @@ Volumes included by the controller. {{- with $persistence.sizeLimit -}} {{- $_ := set $emptyDir "sizeLimit" . -}} {{- end }} - emptyDir: {{- $emptyDir | toYaml | nindent 4 }} + emptyDir: {{- tpl ( toYaml $emptyDir ) $ | nindent 4 }} {{- else if or (eq $persistence.type "configMap") (eq $persistence.type "secret") }} {{- $objectName := (required (printf "objectName not set for persistence item %s" $index) $persistence.objectName) }} {{- $objectName = tpl $objectName $ }} @@ -45,20 +45,24 @@ Volumes included by the controller. secretName: {{ $objectName }} {{- end }} {{- with $persistence.defaultMode }} - defaultMode: {{ . }} + defaultMode: {{ tpl . $ }} {{- end }} {{- with $persistence.items }} items: - {{- toYaml . | nindent 6 }} + {{- tpl ( toYaml . ) $ | nindent 6 }} {{- end }} {{- else if eq $persistence.type "hostPath" }} hostPath: path: {{ required "hostPath not set" $persistence.hostPath }} {{- with $persistence.hostPathType }} - type: {{ . }} + type: {{ tpl . $ }} {{- end }} + {{- else if eq $persistence.type "nfs" }} + nfs: + server: {{ required "server not set" $persistence.server }} + path: {{ required "path not set" $persistence.path }} {{- else if eq $persistence.type "custom" }} - {{- toYaml $persistence.volumeSpec | nindent 2 }} + {{- tpl ( toYaml $persistence.volumeSpec ) $ | nindent 2 }} {{- else }} {{- fail (printf "Not a valid persistence.type (%s)" $persistence.type) }} {{- end }} diff --git a/charts/common/templates/lib/dependencies/_mariadbInit.tpl b/charts/common/templates/lib/dependencies/_mariadbInit.tpl index 225b6a9a..3c3fe266 100644 --- a/charts/common/templates/lib/dependencies/_mariadbInit.tpl +++ b/charts/common/templates/lib/dependencies/_mariadbInit.tpl @@ -1,7 +1,7 @@ {{/* This template ensures pods with mariadb dependency have a delayed start */}} -{{- define "common.dependencies.mariadb.init" -}} +{{- define "tc.common.dependencies.mariadb.init" -}} {{- if .Values.mariadb.enabled }} - name: mariadb-init image: "{{ .Values.mariadbImage.repository}}:{{ .Values.mariadbImage.tag }}" @@ -22,7 +22,7 @@ This template ensures pods with mariadb dependency have a delayed start - ALL resources: {{- with .Values.resources }} - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} command: ["bash", "-ec"] args: diff --git a/charts/common/templates/lib/dependencies/_mariadbInjector.tpl b/charts/common/templates/lib/dependencies/_mariadbInjector.tpl index a67874ca..f4e5cc4d 100644 --- a/charts/common/templates/lib/dependencies/_mariadbInjector.tpl +++ b/charts/common/templates/lib/dependencies/_mariadbInjector.tpl @@ -1,7 +1,7 @@ {{/* This template generates a random password and ensures it persists across updates/edits to the chart */}} -{{- define "common.dependencies.mariadb.injector" -}} +{{- define "tc.common.dependencies.mariadb.injector" -}} {{- $pghost := printf "%v-%v" .Release.Name "mariadb" }} {{- if .Values.mariadb.enabled }} @@ -10,7 +10,7 @@ apiVersion: v1 kind: Secret metadata: labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} name: mariadbcreds {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace "mariadbcreds" }} {{- $dbPass := "" }} diff --git a/charts/common/templates/lib/dependencies/_mongodbInit.tpl b/charts/common/templates/lib/dependencies/_mongodbInit.tpl index f415d7cb..a3a78a47 100644 --- a/charts/common/templates/lib/dependencies/_mongodbInit.tpl +++ b/charts/common/templates/lib/dependencies/_mongodbInit.tpl @@ -1,7 +1,7 @@ {{/* This template ensures pods with mongodb dependency have a delayed start */}} -{{- define "common.dependencies.mongodb.init" -}} +{{- define "tc.common.dependencies.mongodb.init" -}} {{- if .Values.mongodb.enabled }} - name: mongodb-init image: "{{ .Values.mongodbImage.repository}}:{{ .Values.mongodbImage.tag }}" @@ -19,7 +19,7 @@ This template ensures pods with mongodb dependency have a delayed start - ALL resources: {{- with .Values.resources }} - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} command: ["bash", "-ec"] args: diff --git a/charts/common/templates/lib/dependencies/_mongodbInjector.tpl b/charts/common/templates/lib/dependencies/_mongodbInjector.tpl index 94b9245a..f43e43da 100644 --- a/charts/common/templates/lib/dependencies/_mongodbInjector.tpl +++ b/charts/common/templates/lib/dependencies/_mongodbInjector.tpl @@ -1,7 +1,7 @@ {{/* This template generates a random password and ensures it persists across updates/edits to the chart */}} -{{- define "common.dependencies.mongodb.injector" -}} +{{- define "tc.common.dependencies.mongodb.injector" -}} {{- $pghost := printf "%v-%v" .Release.Name "mongodb" }} {{- if .Values.mongodb.enabled }} @@ -10,7 +10,7 @@ apiVersion: v1 kind: Secret metadata: labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} name: mongodbcreds {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace "mongodbcreds" }} {{- $dbPass := "" }} diff --git a/charts/common/templates/lib/dependencies/_postgresInit.tpl b/charts/common/templates/lib/dependencies/_postgresInit.tpl index 52acf71e..90983a33 100644 --- a/charts/common/templates/lib/dependencies/_postgresInit.tpl +++ b/charts/common/templates/lib/dependencies/_postgresInit.tpl @@ -1,7 +1,7 @@ {{/* This template ensures pods with postgresql dependency have a delayed start */}} -{{- define "common.dependencies.postgresql.init" -}} +{{- define "tc.common.dependencies.postgresql.init" -}} {{- $pghost := printf "%v-%v" .Release.Name "postgresql" }} {{- if .Values.postgresql.enabled }} - name: postgresql-init @@ -12,7 +12,7 @@ This template ensures pods with postgresql dependency have a delayed start - ALL resources: {{- with .Values.resources }} - {{- toYaml . | nindent 4 }} + {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} command: - "sh" diff --git a/charts/common/templates/lib/dependencies/_postgresInjector.tpl b/charts/common/templates/lib/dependencies/_postgresInjector.tpl index c4394259..ff37bbae 100644 --- a/charts/common/templates/lib/dependencies/_postgresInjector.tpl +++ b/charts/common/templates/lib/dependencies/_postgresInjector.tpl @@ -1,7 +1,7 @@ {{/* This template generates a random password and ensures it persists across updates/edits to the chart */}} -{{- define "common.dependencies.postgresql.injector" -}} +{{- define "tc.common.dependencies.postgresql.injector" -}} {{- $pghost := printf "%v-%v" .Release.Name "postgresql" }} {{- if .Values.postgresql.enabled }} @@ -10,7 +10,7 @@ apiVersion: v1 kind: Secret metadata: labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} name: dbcreds {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace "dbcreds" }} {{- $dbPass := "" }} diff --git a/charts/common/templates/lib/dependencies/_redisInjector.tpl b/charts/common/templates/lib/dependencies/_redisInjector.tpl index 37479251..e01e3dcd 100644 --- a/charts/common/templates/lib/dependencies/_redisInjector.tpl +++ b/charts/common/templates/lib/dependencies/_redisInjector.tpl @@ -1,7 +1,7 @@ {{/* This template generates a random password and ensures it persists across updates/edits to the chart */}} -{{- define "common.dependencies.redis.injector" -}} +{{- define "tc.common.dependencies.redis.injector" -}} {{- $pghost := printf "%v-%v" .Release.Name "redis" }} {{- if .Values.redis.enabled }} @@ -10,7 +10,7 @@ apiVersion: v1 kind: Secret metadata: labels: - {{- include "common.labels" . | nindent 4 }} + {{- include "tc.common.labels" . | nindent 4 }} name: rediscreds {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace "rediscreds" }} {{- $dbPass := "" }} diff --git a/charts/common/templates/lib/utils/_affinities.tpl b/charts/common/templates/lib/util/_affinities.tpl similarity index 61% rename from charts/common/templates/lib/utils/_affinities.tpl rename to charts/common/templates/lib/util/_affinities.tpl index e85b8792..8ac0a6e3 100644 --- a/charts/common/templates/lib/utils/_affinities.tpl +++ b/charts/common/templates/lib/util/_affinities.tpl @@ -2,9 +2,9 @@ {{/* Return a soft nodeAffinity definition -{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +{{ include "tc.common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} */}} -{{- define "common.affinities.nodes.soft" -}} +{{- define "tc.common.affinities.nodes.soft" -}} preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: @@ -19,9 +19,9 @@ preferredDuringSchedulingIgnoredDuringExecution: {{/* Return a hard nodeAffinity definition -{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +{{ include "tc.common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} */}} -{{- define "common.affinities.nodes.hard" -}} +{{- define "tc.common.affinities.nodes.hard" -}} requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: @@ -35,27 +35,27 @@ requiredDuringSchedulingIgnoredDuringExecution: {{/* Return a nodeAffinity definition -{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +{{ include "tc.common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} */}} -{{- define "common.affinities.nodes" -}} +{{- define "tc.common.affinities.nodes" -}} {{- if eq .type "soft" }} - {{- include "common.affinities.nodes.soft" . -}} + {{- include "tc.common.affinities.nodes.soft" . -}} {{- else if eq .type "hard" }} - {{- include "common.affinities.nodes.hard" . -}} + {{- include "tc.common.affinities.nodes.hard" . -}} {{- end -}} {{- end -}} {{/* Return a soft podAffinity/podAntiAffinity definition -{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +{{ include "tc.common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} */}} -{{- define "common.affinities.pods.soft" -}} +{{- define "tc.common.affinities.pods.soft" -}} {{- $component := default "" .component -}} {{- $extraMatchLabels := default (dict) .extraMatchLabels -}} preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: - matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + matchLabels: {{- (include "tc.common.labels.matchLabels" .context) | nindent 10 }} {{- if not (empty $component) }} {{ printf "app.kubernetes.io/component: %s" $component }} {{- end }} @@ -70,14 +70,14 @@ preferredDuringSchedulingIgnoredDuringExecution: {{/* Return a hard podAffinity/podAntiAffinity definition -{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +{{ include "tc.common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} */}} -{{- define "common.affinities.pods.hard" -}} +{{- define "tc.common.affinities.pods.hard" -}} {{- $component := default "" .component -}} {{- $extraMatchLabels := default (dict) .extraMatchLabels -}} requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: - matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + matchLabels: {{- (include "tc.common.labels.matchLabels" .context) | nindent 8 }} {{- if not (empty $component) }} {{ printf "app.kubernetes.io/component: %s" $component }} {{- end }} @@ -91,12 +91,12 @@ requiredDuringSchedulingIgnoredDuringExecution: {{/* Return a podAffinity/podAntiAffinity definition -{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +{{ include "tc.common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} */}} -{{- define "common.affinities.pods" -}} +{{- define "tc.common.affinities.pods" -}} {{- if eq .type "soft" }} - {{- include "common.affinities.pods.soft" . -}} + {{- include "tc.common.affinities.pods.soft" . -}} {{- else if eq .type "hard" }} - {{- include "common.affinities.pods.hard" . -}} + {{- include "tc.common.affinities.pods.hard" . -}} {{- end -}} {{- end -}} diff --git a/charts/common/templates/lib/utils/_images.tpl b/charts/common/templates/lib/util/_images.tpl similarity index 54% rename from charts/common/templates/lib/utils/_images.tpl rename to charts/common/templates/lib/util/_images.tpl index a7f656ab..45e35621 100644 --- a/charts/common/templates/lib/utils/_images.tpl +++ b/charts/common/templates/lib/util/_images.tpl @@ -1,9 +1,9 @@ {{/* vim: set filetype=mustache: */}} {{/* Return the proper image name -{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} +{{ include "tc.common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} */}} -{{- define "common.images.image" -}} +{{- define "tc.common.images.image" -}} {{- $repositoryName := .imageRoot.repository -}} {{- $tag := .imageRoot.tag | toString -}} {{- printf "%s:%s" $repositoryName $tag -}} @@ -11,9 +11,9 @@ Return the proper image name {{/* Return the image name using the selector -{{ include "common.images.selector" . }} +{{ include "tc.common.images.selector" . }} */}} -{{- define "common.images.selector" -}} +{{- define "tc.common.images.selector" -}} {{- $imageDict := get .Values "image" }} {{- $selected := .Values.imageSelector }} {{- if hasKey .Values $selected }} @@ -25,15 +25,15 @@ Return the image name using the selector {{- end -}} {{/* -Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) -{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +Return the proper Docker Image Registry Secret Names (deprecated: use tc.common.images.renderPullSecrets instead) +{{ include "tc.common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} */}} -{{- define "common.images.pullSecrets" -}} +{{- define "tc.common.images.pullSecrets" -}} {{- end -}} {{/* Return the proper Docker Image Registry Secret Names evaluating values as templates -{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +{{ include "tc.common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} */}} -{{- define "common.images.renderPullSecrets" -}} +{{- define "tc.common.images.renderPullSecrets" -}} {{- end -}} diff --git a/charts/common/templates/lib/utils/_labels.tpl b/charts/common/templates/lib/util/_labels.tpl similarity index 50% rename from charts/common/templates/lib/utils/_labels.tpl rename to charts/common/templates/lib/util/_labels.tpl index eab03905..4e44bed9 100644 --- a/charts/common/templates/lib/utils/_labels.tpl +++ b/charts/common/templates/lib/util/_labels.tpl @@ -2,13 +2,13 @@ {{/* Kubernetes standard labels */}} -{{- define "common.labels.standard" -}} -{{- include "common.labels" . }} +{{- define "tc.common.labels.standard" -}} +{{- include "tc.common.labels" . }} {{- end -}} {{/* Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector */}} -{{- define "common.labels.matchLabels" -}} -{{- include "common.labels.selectorLabels" . }} +{{- define "tc.common.labels.matchLabels" -}} +{{- include "tc.common.labels.selectorLabels" . }} {{- end -}} diff --git a/charts/common/templates/lib/util/_primary-ingress.tpl b/charts/common/templates/lib/util/_primary-ingress.tpl new file mode 100644 index 00000000..b3470cfb --- /dev/null +++ b/charts/common/templates/lib/util/_primary-ingress.tpl @@ -0,0 +1,21 @@ +{{/* Return the name of the primary ingress object */}} +{{- define "tc.common.lib.util.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 -}} diff --git a/charts/common/templates/lib/util/_primary-rbac.tpl b/charts/common/templates/lib/util/_primary-rbac.tpl new file mode 100644 index 00000000..7d1708cc --- /dev/null +++ b/charts/common/templates/lib/util/_primary-rbac.tpl @@ -0,0 +1,23 @@ +{{/* +Return the primary rbac object +*/}} +{{- define "tc.common.lib.util.rbac.primary" -}} + {{- $enabledrbacs := dict -}} + {{- range $name, $rbac := .Values.rbac -}} + {{- if $rbac.enabled -}} + {{- $_ := set $enabledrbacs $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $rbac := $enabledrbacs -}} + {{- if and (hasKey $rbac "primary") $rbac.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $enabledrbacs | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/charts/common/templates/lib/util/_primary-service.tpl b/charts/common/templates/lib/util/_primary-service.tpl new file mode 100644 index 00000000..d2a26d6a --- /dev/null +++ b/charts/common/templates/lib/util/_primary-service.tpl @@ -0,0 +1,23 @@ +{{/* +Return the primary service object +*/}} +{{- define "tc.common.lib.util.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 -}} diff --git a/charts/common/templates/lib/util/_primary-serviceAccount.tpl b/charts/common/templates/lib/util/_primary-serviceAccount.tpl new file mode 100644 index 00000000..e09fc4a7 --- /dev/null +++ b/charts/common/templates/lib/util/_primary-serviceAccount.tpl @@ -0,0 +1,23 @@ +{{/* +Return the primary serviceAccount object +*/}} +{{- define "tc.common.lib.util.serviceaccount.primary" -}} + {{- $enabledServiceaccounts := dict -}} + {{- range $name, $serviceAccount := .Values.serviceAccount -}} + {{- if $serviceAccount.enabled -}} + {{- $_ := set $enabledServiceaccounts $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $serviceAccount := $enabledServiceaccounts -}} + {{- if and (hasKey $serviceAccount "primary") $serviceAccount.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $enabledServiceaccounts | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/charts/common/templates/classes/_service_ports.tpl b/charts/common/templates/lib/util/_service_ports.tpl similarity index 92% rename from charts/common/templates/classes/_service_ports.tpl rename to charts/common/templates/lib/util/_service_ports.tpl index 32cae4c8..2c602963 100644 --- a/charts/common/templates/classes/_service_ports.tpl +++ b/charts/common/templates/lib/util/_service_ports.tpl @@ -1,7 +1,7 @@ {{/* Return the primary port for a given Service object. */}} -{{- define "common.classes.service.ports.primary" -}} +{{- define "tc.common.lib.util.service.ports.primary" -}} {{- $enabledPorts := dict -}} {{- range $name, $port := .values.ports -}} {{- if $port.enabled -}} diff --git a/charts/common/templates/lib/util/_storage.tpl b/charts/common/templates/lib/util/_storage.tpl new file mode 100644 index 00000000..5ad14669 --- /dev/null +++ b/charts/common/templates/lib/util/_storage.tpl @@ -0,0 +1,20 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "tc.common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $ ) }} +*/}} +{{- define "tc.common.storage.class" -}} + +{{- if .persistence.storageClass -}} + {{- if (eq "-" .persistence.storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else if and (eq "SCALE-ZFS" .persistence.storageClass ) -}} + {{- printf "storageClassName: %s" .global.Values.global.ixChartContext.storageClassName -}} + {{- else -}} + {{- printf "storageClassName: %s" .persistence.storageClass -}} + {{- end -}} +{{- else if .global.Values.global.ixChartContext -}} + {{- printf "storageClassName: %s" .global.Values.global.ixChartContext.storageClassName -}} +{{- end -}} + +{{- end -}} diff --git a/charts/common/templates/lib/utils/_tplvalues.tpl b/charts/common/templates/lib/util/_tplvalues.tpl similarity index 64% rename from charts/common/templates/lib/utils/_tplvalues.tpl rename to charts/common/templates/lib/util/_tplvalues.tpl index 2db16685..fab7f604 100644 --- a/charts/common/templates/lib/utils/_tplvalues.tpl +++ b/charts/common/templates/lib/util/_tplvalues.tpl @@ -2,9 +2,9 @@ {{/* Renders a value that contains template. Usage: -{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +{{ include "tc.common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} */}} -{{- define "common.tplvalues.render" -}} +{{- define "tc.common.tplvalues.render" -}} {{- if typeIs "string" .value }} {{- tpl .value .context }} {{- else }} diff --git a/charts/common/templates/lib/utils/_warnings.tpl b/charts/common/templates/lib/util/_warnings.tpl similarity index 77% rename from charts/common/templates/lib/utils/_warnings.tpl rename to charts/common/templates/lib/util/_warnings.tpl index 464afa4c..d2290ebe 100644 --- a/charts/common/templates/lib/utils/_warnings.tpl +++ b/charts/common/templates/lib/util/_warnings.tpl @@ -2,9 +2,9 @@ {{/* Warning about using rolling tag. Usage: -{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +{{ include "tc.common.warnings.rollingTag" .Values.path.to.the.imageRoot }} */}} -{{- define "common.warnings.rollingTag" -}} +{{- define "tc.common.warnings.rollingTag" -}} {{- if not (.tag | toString | regexFind "-r\\d+$|sha256:") }} WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. diff --git a/charts/common/templates/lib/utils/_storage.tpl b/charts/common/templates/lib/utils/_storage.tpl deleted file mode 100644 index eaa816ce..00000000 --- a/charts/common/templates/lib/utils/_storage.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Return the proper Storage Class -{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $ ) }} -*/}} -{{- define "common.storage.class" -}} - -{{- $storageClass := .persistence.storageClass -}} -{{- $output := "" -}} - -{{- if ( hasKey .persistence "storageClass" ) -}} - {{- if $storageClass -}} - {{- if (eq "-" $storageClass) -}} - {{- $output = "\"\"" -}} - {{- else if (eq "SCALE-ZFS" $storageClass ) }} - {{- $output = ( printf "ix-storage-class-%s" .global.Release.Name ) -}} - {{- else }} - {{- $output = $storageClass -}} - {{- end -}} - {{- printf "storageClassName: %s" $output -}} - {{- else -}} - {{- printf "%s" "storageClassName: " -}} - {{- end -}} -{{- else if .global }} - {{- if .global.Values.storageClass -}} - {{- $output = .global.Values.storageClass -}} - {{- else if .global.Values.ixChartContext }} - {{- $output = ( printf "ix-storage-class-%s" .global.Release.Name ) -}} - {{- else if .global.Values.global -}} - {{- if .global.Values.global.storageClass -}} - {{- $output = .global.Values.global.storageClass -}} - {{- end -}} - {{- if or ( .global.Values.global.ixChartContext ) ( .global.Values.global.isSCALE ) -}} - {{- $output = ( printf "ix-storage-class-%s" .global.Release.Name ) -}} - {{- end }} - {{- end -}} - {{- if $output -}} - {{- printf "storageClassName: %s" $output -}} - {{- end -}} -{{- end -}} -{{- end -}} diff --git a/charts/common/templates/lib/values/_capabilities.tpl b/charts/common/templates/lib/values/_capabilities.tpl new file mode 100644 index 00000000..1ebec48a --- /dev/null +++ b/charts/common/templates/lib/values/_capabilities.tpl @@ -0,0 +1,52 @@ +{{/* automatically set CAP_NET_BIND_SERVICE */}} +{{- define "tc.common.lib.values.capabilities" -}} + {{- $fixedCapAdd := list }} + {{- $customCapAdd := list }} + {{- $valueCapAdd := list }} + {{- $dynamicCapAdd := list }} + {{- $fixedCapDrop := list }} + {{- $customCapDrop := list }} + {{- $valueCapDrop := list }} + {{- $dynamicCapDrop := list }} + {{- if .Values.securityContext.capabilities.add }} + {{- $valueCapAdd = .Values.securityContext.capabilities.add }} + {{- end }} + {{- if .Values.securityContext.capabilities.drop }} + {{- $valueCapDrop = .Values.securityContext.capabilities.drop }} + {{- end }} + {{- if .Values.customCapabilities.add }} + {{- $customCapAdd = .Values.customCapabilities.add }} + {{- end }} + {{- if .Values.customCapabilities.drop }} + {{- $customCapDrop = .Values.customCapabilities.drop }} + {{- end }} + + {{- $privPort := false }} + {{- range .Values.service }} + {{- range $name, $values := .ports }} + {{- if and ( $values.targetPort ) ( kindIs "int" $values.targetPort ) }} + {{- if ( semverCompare "<= 1024" ( toString $values.targetPort ) ) }} + {{- $privPort = true }} + {{- end }} + {{- else if and ( $values.port ) ( kindIs "int" $values.port ) }} + {{- if ( semverCompare "<= 1024" ( toString $values.port ) ) }} + {{- $privPort = true }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + + {{- if $privPort }} + {{- $dynamicCapAdd = list "NET_BIND_SERVICE" }} + {{- end }} + + {{/* combine and write all capabilities to .Values */}} + {{- $CapAdd := concat $fixedCapAdd $valueCapAdd $dynamicCapAdd }} + {{- $CapDrop := concat $fixedCapDrop $valueCapDrop $dynamicCapDrop }} + {{- if $CapDrop }} + {{- $_ := set .Values.securityContext.capabilities "drop" $CapDrop -}} + {{- end }} + {{- if $CapAdd }} + {{- $_ := set .Values.securityContext.capabilities "add" $CapAdd -}} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/_persistenceSimple.tpl b/charts/common/templates/lib/values/_persistenceSimple.tpl new file mode 100644 index 00000000..d2fbe386 --- /dev/null +++ b/charts/common/templates/lib/values/_persistenceSimple.tpl @@ -0,0 +1,19 @@ +{{/* Allow some extra "fake" persistence options for SCALE GUI simplification */}} +{{- define "tc.common.lib.values.persistence.simple" -}} + {{- range .Values.persistence }} + {{- if .type }} + {{- if eq .type "simplePVC" }} + {{- $_ := set . "type" "pvc" }} + {{- end }} + {{- if eq .type "simpleHP" }} + {{- $_ := set . "type" "hostPath" }} + {{- if .setPermissionsSimple }} + {{- $_ := set . "setPermissions" .setPermissionsSimple }} + {{- end }} + {{- if .hostPathSimple }} + {{- $_ := set . "hostPath" .hostPathSimple }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/_privileged.tpl b/charts/common/templates/lib/values/_privileged.tpl new file mode 100644 index 00000000..8fce3571 --- /dev/null +++ b/charts/common/templates/lib/values/_privileged.tpl @@ -0,0 +1,8 @@ +{{/* Enable privileged securitycontext when deviceList is used */}} +{{- define "tc.common.lib.values.securityContext.privileged" -}} + {{- if .Values.securityContext.privileged }} + {{- else if .Values.deviceList }} + {{- $_ := set .Values.securityContext "privileged" true -}} + {{- $_ := set .Values.securityContext "allowPrivilegeEscalation" true -}} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/_serviceSimple.tpl b/charts/common/templates/lib/values/_serviceSimple.tpl new file mode 100644 index 00000000..451eb47c --- /dev/null +++ b/charts/common/templates/lib/values/_serviceSimple.tpl @@ -0,0 +1,10 @@ +{{/* Allow some extra "fake" service options for SCALE GUI simplification */}} +{{- define "tc.common.lib.values.service.simple" -}} + {{- range .Values.service }} + {{- if .type }} + {{- if eq .type "Simple" }} + {{- $_ := set . "type" "LoadBalancer" }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/_supplementalGroups.tpl b/charts/common/templates/lib/values/_supplementalGroups.tpl new file mode 100644 index 00000000..f86a5863 --- /dev/null +++ b/charts/common/templates/lib/values/_supplementalGroups.tpl @@ -0,0 +1,28 @@ +{{/* Append default supplementalGroups to user defined groups */}} +{{- define "tc.common.lib.values.supplementalGroups" -}} + + {{/* save supplementalGroups to placeholder variables */}} + {{- $fixedGroups := list 568 }} + {{- $valuegroups := list }} + {{- $devGroups := list }} + {{- $gpuGroups := list }} + + {{/* put user-entered supplementalgroups in placeholder variable */}} + {{- if .Values.podSecurityContext.supplementalGroups }} + {{- $valuegroups = .Values.podSecurityContext.supplementalGroups }} + {{- end }} + + {{/* Append requered groups to supplementalGroups when deviceList is used */}} + {{- if and ( .Values.deviceList ) ( .Values.global.ixChartContext ) }} + {{- $devGroups = list 5 10 20 24 }} + {{- end }} + + {{/* Append requered groups to supplementalGroups when scaleGPU is used */}} + {{- if and ( .Values.scaleGPU ) ( .Values.global.ixChartContext ) }} + {{- $gpuGroups = list 44 107 }} + {{- end }} + + {{/* combine and write all supplementalGroups to .Values */}} + {{- $supGroups := concat $fixedGroups $valuegroups $devGroups $gpuGroups }} + {{- $_ := set .Values.podSecurityContext "supplementalGroups" $supGroups -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/_values.tpl b/charts/common/templates/lib/values/_values.tpl new file mode 100644 index 00000000..8626c04e --- /dev/null +++ b/charts/common/templates/lib/values/_values.tpl @@ -0,0 +1,9 @@ +{{/* Merge the local chart values and the common chart defaults */}} +{{- define "tc.common.values.init" -}} + {{- if .Values.common -}} + {{- $defaultValues := deepCopy .Values.common -}} + {{- $userValues := deepCopy (omit .Values "common") -}} + {{- $mergedValues := mustMergeOverwrite $defaultValues $userValues -}} + {{- $_ := set . "Values" (deepCopy $mergedValues) -}} + {{- end -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/_vctSimple.tpl b/charts/common/templates/lib/values/_vctSimple.tpl new file mode 100644 index 00000000..f70076f4 --- /dev/null +++ b/charts/common/templates/lib/values/_vctSimple.tpl @@ -0,0 +1,10 @@ +{{/* Allow some extra "fake" VolumeClaimTemplate options for SCALE GUI simplification */}} +{{- define "tc.common.lib.values.volumeClaimTemplates.simple" -}} + {{- range .Values.volumeClaimTemplates }} + {{- if .type }} + {{- if eq .type "simplePVC" }} + {{- $_ := set . "type" "pvc" }} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_controllerAnnotationsList.tpl b/charts/common/templates/lib/values/lists/_controllerAnnotationsList.tpl new file mode 100644 index 00000000..cfb648f3 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_controllerAnnotationsList.tpl @@ -0,0 +1,9 @@ +{{/* merge controllerAnnotationsList with controllerAnnotations */}} +{{- define "tc.common.lib.values.controller.annotations.list" -}} + {{- $controllerAnnotationsDict := dict }} + {{- range .Values.controller.annotationsList }} + {{- $_ := set $controllerAnnotationsDict .name .value }} + {{- end }} + {{- $controlleranno := merge .Values.controller.annotations $controllerAnnotationsDict }} + {{- $_ := set .Values.controller "annotations" (deepCopy $controlleranno) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_controllerLabelsList.tpl b/charts/common/templates/lib/values/lists/_controllerLabelsList.tpl new file mode 100644 index 00000000..747f0338 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_controllerLabelsList.tpl @@ -0,0 +1,9 @@ +{{/* merge controllerLabelsList with controllerLabels */}} +{{- define "tc.common.lib.values.controller.label.list" -}} + {{- $controllerLabelsDict := dict }} + {{- range .Values.controller.labelsList }} + {{- $_ := set $controllerLabelsDict .name .value }} + {{- end }} + {{- $controllerlab := merge .Values.controller.labels $controllerLabelsDict }} + {{- $_ := set .Values "labels" (deepCopy $controllerlab) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_ingressAnnotationsList.tpl b/charts/common/templates/lib/values/lists/_ingressAnnotationsList.tpl new file mode 100644 index 00000000..dd80543c --- /dev/null +++ b/charts/common/templates/lib/values/lists/_ingressAnnotationsList.tpl @@ -0,0 +1,14 @@ +{{/* merge ingressAnnotationsList with ingressAnnotations */}} +{{- define "tc.common.lib.values.ingress.annotations.list" -}} + {{- range $index, $item := .Values.ingress }} + {{- if $item.enabled }} + {{- $ingressAnnotationsDict := dict }} + {{- range $item.annotationsList }} + {{- $_ := set $ingressAnnotationsDict .name .value }} + {{- end }} + {{- $tmp := $item.annotations }} + {{- $ingressanno := merge $tmp $ingressAnnotationsDict }} + {{- $_ := set $item "annotations" (deepCopy $ingressanno) -}} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_ingressLabelsList.tpl b/charts/common/templates/lib/values/lists/_ingressLabelsList.tpl new file mode 100644 index 00000000..702eaf27 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_ingressLabelsList.tpl @@ -0,0 +1,14 @@ +{{/* merge ingressLabelsList with ingressLabels */}} +{{- define "tc.common.lib.values.ingress.label.list" -}} + {{- range $index, $item := .Values.ingress }} + {{- if $item.enabled }} + {{- $ingressLabelsDict := dict }} + {{- range $item.labelsList }} + {{- $_ := set $ingressLabelsDict .name .value }} + {{- end }} + {{- $tmp := $item.labels }} + {{- $ingresslab := merge $tmp $ingressLabelsDict }} + {{- $_ := set $item "labels" (deepCopy $ingresslab) -}} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_ingressList.tpl b/charts/common/templates/lib/values/lists/_ingressList.tpl new file mode 100644 index 00000000..2c24fd7f --- /dev/null +++ b/charts/common/templates/lib/values/lists/_ingressList.tpl @@ -0,0 +1,13 @@ +{{/* merge ingressList with ingress */}} +{{- define "tc.common.lib.values.ingress.list" -}} + {{- $ingDict := dict }} + {{- range $index, $item := .Values.ingressList -}} + {{- $name := ( printf "list-%s" ( $index | toString ) ) }} + {{- if $item.name }} + {{- $name = $item.name }} + {{- end }} + {{- $_ := set $ingDict $name $item }} + {{- end }} + {{- $ing := merge .Values.ingress $ingDict }} + {{- $_ := set .Values "ingress" (deepCopy $ing) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_persistenceAnnotationsList.tpl b/charts/common/templates/lib/values/lists/_persistenceAnnotationsList.tpl new file mode 100644 index 00000000..f73ef812 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_persistenceAnnotationsList.tpl @@ -0,0 +1,14 @@ +{{/* merge persistenceAnnotationsList with persistenceAnnotations */}} +{{- define "tc.common.lib.values.persistence.annotations.list" -}} + {{- range $index, $item := .Values.persistence }} + {{- if $item.enabled }} + {{- $persistenceAnnotationsDict := dict }} + {{- range $item.annotationsList }} + {{- $_ := set $persistenceAnnotationsDict .name .value }} + {{- end }} + {{- $tmp := $item.annotations }} + {{- $persistenceanno := merge $tmp $persistenceAnnotationsDict }} + {{- $_ := set $item "annotations" (deepCopy $persistenceanno) -}} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_persistenceLabelsList.tpl b/charts/common/templates/lib/values/lists/_persistenceLabelsList.tpl new file mode 100644 index 00000000..051a853b --- /dev/null +++ b/charts/common/templates/lib/values/lists/_persistenceLabelsList.tpl @@ -0,0 +1,14 @@ +{{/* merge persistenceLabelsList with persistenceLabels */}} +{{- define "tc.common.lib.values.persistence.label.list" -}} + {{- range $index, $item := .Values.persistence }} + {{- if $item.enabled }} + {{- $persistenceLabelsDict := dict }} + {{- range $item.labelsList }} + {{- $_ := set $persistenceLabelsDict .name .value }} + {{- end }} + {{- $tmp := $item.labels }} + {{- $persistencelab := merge $tmp $persistenceLabelsDict }} + {{- $_ := set $item "labels" (deepCopy $persistencelab) -}} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_persistenceList.tpl b/charts/common/templates/lib/values/lists/_persistenceList.tpl new file mode 100644 index 00000000..4907aa05 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_persistenceList.tpl @@ -0,0 +1,21 @@ +{{/* merge persistenceList with Persitence */}} +{{- define "tc.common.lib.values.persistence.list" -}} + {{- $perDict := dict }} + {{- range $index, $item := .Values.persistenceList -}} + {{- $name := ( printf "list-%s" ( $index | toString ) ) }} + {{- if $item.name }} + {{- $name = $item.name }} + {{- end }} + {{- $_ := set $perDict $name $item }} + {{- end }} + + {{- range $index, $item := .Values.deviceList -}} + {{- $name := ( printf "device-%s" ( $index | toString ) ) }} + {{- if $item.name }} + {{- $name = $item.name }} + {{- end }} + {{- $_ := set $perDict $name $item }} + {{- end }} + {{- $per := merge .Values.persistence $perDict }} + {{- $_ := set .Values "persistence" (deepCopy $per) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_podAnnotationsList.tpl b/charts/common/templates/lib/values/lists/_podAnnotationsList.tpl new file mode 100644 index 00000000..38f8f7c7 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_podAnnotationsList.tpl @@ -0,0 +1,9 @@ +{{/* merge podAnnotationsList with podAnnotations */}} +{{- define "tc.common.lib.values.pod.annotations.list" -}} + {{- $podAnnotationsDict := dict }} + {{- range .Values.podAnnotationsList }} + {{- $_ := set $podAnnotationsDict .name .value }} + {{- end }} + {{- $podanno := merge .Values.podAnnotations $podAnnotationsDict }} + {{- $_ := set .Values "podAnnotations" (deepCopy $podanno) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_podLabelsList.tpl b/charts/common/templates/lib/values/lists/_podLabelsList.tpl new file mode 100644 index 00000000..585106d8 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_podLabelsList.tpl @@ -0,0 +1,9 @@ +{{/* merge podLabelsList with podLabels */}} +{{- define "tc.common.lib.values.pod.label.list" -}} + {{- $podLabelsDict := dict }} + {{- range .Values.controller.labelsList }} + {{- $_ := set $podLabelsDict .name .value }} + {{- end }} + {{- $podlab := merge .Values.controller.labels $podLabelsDict }} + {{- $_ := set .Values.controller "labels" (deepCopy $podlab) -}} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_portsList.tpl b/charts/common/templates/lib/values/lists/_portsList.tpl new file mode 100644 index 00000000..4182a9d5 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_portsList.tpl @@ -0,0 +1,20 @@ +{{/* merge portsList with ports */}} +{{- define "tc.common.lib.values.ports.list" -}} + {{- range $index, $item := .Values.service -}} + {{- if $item.enabled }} + {{- $portsDict := dict }} + {{- range $index2, $item2 := $item.portsList -}} + {{- if $item2.enabled }} + {{- $name := ( printf "list-%s" ( $index2 | toString ) ) }} + {{- if $item2.name }} + {{- $name = $item2.name }} + {{- end }} + {{- $_ := set $portsDict $name $item2 }} + {{- end }} + {{- $tmp := $item.ports }} + {{- $ports := merge $tmp $portsDict }} + {{- $_ := set $item "ports" (deepCopy $ports) -}} + {{- end }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/charts/common/templates/lib/values/lists/_serviceList.tpl b/charts/common/templates/lib/values/lists/_serviceList.tpl new file mode 100644 index 00000000..07b689b5 --- /dev/null +++ b/charts/common/templates/lib/values/lists/_serviceList.tpl @@ -0,0 +1,15 @@ +{{/* merge serviceList with service */}} +{{- define "tc.common.lib.values.service.list" -}} + {{- $portsDict := dict }} + {{- range $index, $item := .Values.serviceList -}} + {{- if $item.enabled }} + {{- $name := ( printf "list-%s" ( $index | toString ) ) }} + {{- if $item.name }} + {{- $name = $item.name }} + {{- end }} + {{- $_ := set $portsDict $name $item }} + {{- end }} + {{- end }} + {{- $srv := merge .Values.service $portsDict }} + {{- $_ := set .Values "service" (deepCopy $srv) -}} +{{- end -}} diff --git a/charts/common/templates/_all.tpl b/charts/common/templates/loader/_all.tpl similarity index 65% rename from charts/common/templates/_all.tpl rename to charts/common/templates/loader/_all.tpl index 52cb4116..cb6a6349 100644 --- a/charts/common/templates/_all.tpl +++ b/charts/common/templates/loader/_all.tpl @@ -1,11 +1,11 @@ {{/* Main entrypoint for the common library chart. It will render all underlying templates based on the provided values. */}} -{{- define "common.all" -}} +{{- define "tc.common.loader.all" -}} {{- /* Generate chart and dependency values */ -}} - {{- include "common.setup" . }} + {{- include "tc.common.loader.init" . }} {{- /* Generate remaining objects */ -}} - {{- include "common.postSetup" . }} + {{- include "tc.common.loader.apply" . }} {{- end -}} diff --git a/charts/common/templates/loader/_apply.tpl b/charts/common/templates/loader/_apply.tpl new file mode 100644 index 00000000..e8634da9 --- /dev/null +++ b/charts/common/templates/loader/_apply.tpl @@ -0,0 +1,62 @@ +{{/* +Secondary entrypoint and primary loader for the common chart +*/}} +{{- define "tc.common.loader.apply" -}} + {{- /* Render the externalInterfaces */ -}} + {{ include "tc.common.scale.externalInterfaces" . | nindent 0 }} + + {{- /* Enable code-server add-on if required */ -}} + {{- if .Values.addons.codeserver.enabled }} + {{- include "tc.common.addon.codeserver" . }} + {{- end -}} + + {{- /* Enable VPN add-on if required */ -}} + {{- if ne "disabled" .Values.addons.vpn.type -}} + {{- include "tc.common.addon.vpn" . }} + {{- end -}} + + {{- /* Enable promtail add-on if required */ -}} + {{- if .Values.addons.promtail.enabled }} + {{- include "tc.common.addon.promtail" . }} + {{- end -}} + + {{- /* Enable netshoot add-on if required */ -}} + {{- if .Values.addons.netshoot.enabled }} + {{- include "tc.common.addon.netshoot" . }} + {{- end -}} + + {{- /* Build the configmaps */ -}} + {{ include "tc.common.spawner.configmap" . | nindent 0 }} + + {{- /* Build the secrets */ -}} + {{ include "tc.common.spawner.secret" . | nindent 0 }} + + {{- /* Build the templates */ -}} + {{- include "tc.common.spawner.pvc" . }} + + {{ include "tc.common.spawner.serviceaccount" . | nindent 0 }} + + {{- if .Values.controller.enabled }} + {{- if eq .Values.controller.type "deployment" }} + {{- include "tc.common.deployment" . | nindent 0 }} + {{ else if eq .Values.controller.type "daemonset" }} + {{- include "tc.common.daemonset" . | nindent 0 }} + {{ else if eq .Values.controller.type "statefulset" }} + {{- include "tc.common.statefulset" . | nindent 0 }} + {{ else }} + {{- fail (printf "Not a valid controller.type (%s)" .Values.controller.type) }} + {{- end -}} + {{- end -}} + + {{ include "tc.common.spawner.rbac" . | nindent 0 }} + + {{ include "tc.common.spawner.hpa" . | nindent 0 }} + + {{ include "tc.common.spawner.service" . | nindent 0 }} + + {{ include "tc.common.spawner.ingress" . | nindent 0 }} + + {{ include "tc.common.scale.portal" . | nindent 0 }} + + {{ include "tc.common.spawner.networkpolicy" . | nindent 0 }} +{{- end -}} diff --git a/charts/common/templates/loader/_init.tpl b/charts/common/templates/loader/_init.tpl new file mode 100644 index 00000000..676d94a6 --- /dev/null +++ b/charts/common/templates/loader/_init.tpl @@ -0,0 +1,30 @@ +{{- define "tc.common.loader.init" -}} + {{- /* Merge the local chart values and the common chart defaults */ -}} + {{- include "tc.common.values.init" . }} + + {{- include "tc.common.loader.lists" . }} + + {{- include "tc.common.lib.values.persistence.simple" . }} + + {{- include "tc.common.lib.values.volumeClaimTemplates.simple" . }} + + {{- include "tc.common.lib.values.service.simple" . }} + + {{- include "tc.common.lib.values.capabilities" . }} + + {{- include "tc.common.lib.values.supplementalGroups" . }} + + {{- include "tc.common.lib.values.securityContext.privileged" . }} + + {{- /* Autogenerate postgresql passwords if needed */ -}} + {{- include "tc.common.dependencies.postgresql.injector" . }} + + {{- /* Autogenerate redis passwords if needed */ -}} + {{- include "tc.common.dependencies.redis.injector" . }} + + {{- /* Autogenerate mariadb passwords if needed */ -}} + {{- include "tc.common.dependencies.mariadb.injector" . }} + + {{- /* Autogenerate mongodb passwords if needed */ -}} + {{- include "tc.common.dependencies.mongodb.injector" . }} +{{- end -}} diff --git a/charts/common/templates/loader/_lists.tpl b/charts/common/templates/loader/_lists.tpl new file mode 100644 index 00000000..077630a1 --- /dev/null +++ b/charts/common/templates/loader/_lists.tpl @@ -0,0 +1,23 @@ +{{/* load all list to dict injectors */}} +{{- define "tc.common.loader.lists" -}} + + + {{ include "tc.common.lib.values.controller.label.list" . }} + {{ include "tc.common.lib.values.controller.annotations.list" . }} + + {{ include "tc.common.lib.values.pod.label.list" . }} + {{ include "tc.common.lib.values.pod.annotations.list" . }} + + {{ include "tc.common.lib.values.persistence.list" . }} + {{ include "tc.common.lib.values.persistence.label.list" . }} + {{ include "tc.common.lib.values.persistence.annotations.list" . }} + + {{ include "tc.common.lib.values.service.list" . }} + + {{ include "tc.common.lib.values.ingress.list" . }} + {{ include "tc.common.lib.values.ingress.label.list" . }} + {{ include "tc.common.lib.values.ingress.annotations.list" . }} + + + +{{- end -}} diff --git a/charts/common/templates/pods/_daemonset.tpl b/charts/common/templates/pods/_daemonset.tpl new file mode 100644 index 00000000..211af94b --- /dev/null +++ b/charts/common/templates/pods/_daemonset.tpl @@ -0,0 +1,36 @@ +{{/* +This template serves as the blueprint for the DaemonSet objects that are created +within the common library. +*/}} +{{- define "tc.common.daemonset" }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "tc.common.names.fullname" . }} + {{- with (merge (.Values.controller.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + {{- with (merge (.Values.controller.annotations | default dict) (include "tc.common.annotations" $ | fromYaml) (include "tc.common.annotations.workload" $ | fromYaml)) }} + annotations: {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} +spec: + revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "tc.common.labels.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- include "tc.common.annotations.workload.spec" . | nindent 8 }} + {{- with .Values.podAnnotations }} + {{- tpl ( toYaml . ) $ | nindent 8 }} + {{- end }} + labels: + {{- include "tc.common.labels.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- tpl ( toYaml . ) $ | nindent 8 }} + {{- end }} + spec: + {{- include "tc.common.controller.pod" . | nindent 6 }} +{{- end }} diff --git a/charts/common/templates/_deployment.tpl b/charts/common/templates/pods/_deployment.tpl similarity index 57% rename from charts/common/templates/_deployment.tpl rename to charts/common/templates/pods/_deployment.tpl index eb905d3b..ac587afb 100644 --- a/charts/common/templates/_deployment.tpl +++ b/charts/common/templates/pods/_deployment.tpl @@ -2,21 +2,17 @@ This template serves as the blueprint for the Deployment objects that are created within the common library. */}} -{{- define "common.deployment" }} +{{- define "tc.common.deployment" }} --- apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.controller.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - annotations: - {{- include "common.annotations.workload" . | nindent 4 }} - {{- with .Values.controller.annotations }} - {{- toYaml . | nindent 4 }} + name: {{ include "tc.common.names.fullname" . }} + {{- with (merge (.Values.controller.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + {{- with (merge (.Values.controller.annotations | default dict) (include "tc.common.annotations" $ | fromYaml) (include "tc.common.annotations.workload" $ | fromYaml)) }} + annotations: {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} spec: revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} @@ -40,19 +36,19 @@ spec: {{- end }} selector: matchLabels: - {{- include "common.labels.selectorLabels" . | nindent 6 }} + {{- include "tc.common.labels.selectorLabels" . | nindent 6 }} template: metadata: annotations: - {{- include "common.annotations.workload.spec" . | nindent 8 }} + {{- include "tc.common.annotations.workload.spec" . | nindent 8 }} {{- with .Values.podAnnotations }} - {{- toYaml . | nindent 8 }} + {{- tpl ( toYaml . ) $ | nindent 8 }} {{- end }} labels: - {{- include "common.labels.selectorLabels" . | nindent 8 }} + {{- include "tc.common.labels.selectorLabels" . | nindent 8 }} {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} + {{- tpl ( toYaml . ) $ | nindent 8 }} {{- end }} spec: - {{- include "common.controller.pod" . | nindent 6 }} + {{- include "tc.common.controller.pod" . | nindent 6 }} {{- end }} diff --git a/charts/common/templates/_statefulset.tpl b/charts/common/templates/pods/_statefulset.tpl similarity index 53% rename from charts/common/templates/_statefulset.tpl rename to charts/common/templates/pods/_statefulset.tpl index 9f4318ec..0d39c1e8 100644 --- a/charts/common/templates/_statefulset.tpl +++ b/charts/common/templates/pods/_statefulset.tpl @@ -2,22 +2,19 @@ This template serves as the blueprint for the StatefulSet objects that are created within the common library. */}} -{{- define "common.statefulset" }} +{{- define "tc.common.statefulset" }} {{- $values := .Values }} {{- $releaseName := .Release.Name }} --- apiVersion: apps/v1 kind: StatefulSet metadata: - name: {{ include "common.names.fullname" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.controller.labels }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.controller.annotations }} - annotations: - {{- toYaml . | nindent 4 }} + name: {{ include "tc.common.names.fullname" . }} + {{- with (merge (.Values.controller.labels | default dict) (include "tc.common.labels" $ | fromYaml)) }} + labels: {{- tpl ( toYaml . ) $ | nindent 4 }} + {{- end }} + {{- with (merge (.Values.controller.annotations | default dict) (include "tc.common.annotations" $ | fromYaml) (include "tc.common.annotations.workload" $ | fromYaml)) }} + annotations: {{- tpl ( toYaml . ) $ | nindent 4 }} {{- end }} spec: revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit }} @@ -34,35 +31,31 @@ spec: {{- end }} selector: matchLabels: - {{- include "common.labels.selectorLabels" . | nindent 6 }} - serviceName: {{ include "common.names.fullname" . }} + {{- include "tc.common.labels.selectorLabels" . | nindent 6 }} + serviceName: {{ include "tc.common.names.fullname" . }} template: metadata: {{- with .Values.podAnnotations }} annotations: - {{- toYaml . | nindent 8 }} + {{- tpl ( toYaml . ) $ | nindent 8 }} {{- end }} labels: - {{- include "common.labels.selectorLabels" . | nindent 8 }} + {{- include "tc.common.labels.selectorLabels" . | nindent 8 }} {{- with .Values.podLabels }} - {{- toYaml . | nindent 8 }} + {{- tpl ( toYaml . ) $ | nindent 8 }} {{- end }} spec: - {{- include "common.controller.pod" . | nindent 6 }} + {{- include "tc.common.controller.pod" . | nindent 6 }} volumeClaimTemplates: {{- range $index, $vct := .Values.volumeClaimTemplates }} - {{- $vctname := $index }} - {{- if $vct.name }} - {{- $vctname := $vct.name }} - {{- end }} - metadata: - name: {{ $vctname }} + name: {{ $vct.name }} spec: accessModes: - - {{ ( $vct.accessMode | default "ReadWriteOnce" ) | quote }} + - {{ tpl ( $vct.accessMode | default "ReadWriteOnce" ) $ | quote }} resources: requests: - storage: {{ $vct.size | default "999Gi" | quote }} - {{ include "common.storage.class" ( dict "persistence" $vct "global" $) }} + storage: {{ tpl ( $vct.size | default "999Gi" ) $ | quote }} + {{ include "tc.common.storage.class" ( dict "persistence" $vct "global" $) }} {{- end }} {{- end }} diff --git a/charts/common/templates/_configmap.tpl b/charts/common/templates/spawner/_configmap.tpl similarity index 85% rename from charts/common/templates/_configmap.tpl rename to charts/common/templates/spawner/_configmap.tpl index 73ad958e..e69d6cab 100644 --- a/charts/common/templates/_configmap.tpl +++ b/charts/common/templates/spawner/_configmap.tpl @@ -1,7 +1,7 @@ {{/* Renders the configMap objects required by the chart. */}} -{{- define "common.configmap" -}} +{{- define "tc.common.spawner.configmap" -}} {{- /* Generate named configMaps as required */ -}} {{- range $name, $configmap := .Values.configmap }} {{- if $configmap.enabled -}} @@ -13,7 +13,7 @@ Renders the configMap objects required by the chart. {{ end -}} {{- $_ := set $ "ObjectValues" (dict "configmap" $configmapValues) -}} - {{- include "common.classes.configmap" $ }} + {{- include "tc.common.class.configmap" $ }} {{- end }} {{- end }} {{- end }} diff --git a/charts/common/templates/spawner/_hpa.tpl b/charts/common/templates/spawner/_hpa.tpl new file mode 100644 index 00000000..52068fcd --- /dev/null +++ b/charts/common/templates/spawner/_hpa.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the configMap objects required by the chart. +*/}} +{{- define "tc.common.spawner.hpa" -}} + {{- /* Generate named configMaps as required */ -}} + {{- range $name, $hpa := .Values.horizontalPodAutoscaler }} + {{- if $hpa.enabled -}} + {{- $hpaValues := $hpa -}} + + {{/* set the default nameOverride to the hpa name */}} + {{- if not $hpaValues.nameOverride -}} + {{- $_ := set $hpaValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "hpa" $hpaValues) -}} + {{- include "tc.common.class.hpa" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/_ingress.tpl b/charts/common/templates/spawner/_ingress.tpl similarity index 55% rename from charts/common/templates/_ingress.tpl rename to charts/common/templates/spawner/_ingress.tpl index 843c370a..f28463c0 100644 --- a/charts/common/templates/_ingress.tpl +++ b/charts/common/templates/spawner/_ingress.tpl @@ -1,51 +1,29 @@ {{/* Renders the Ingress objects required by the chart */}} -{{- define "common.ingress" -}} +{{- define "tc.common.spawner.ingress" -}} {{- /* Generate named ingresses as required */ -}} {{- range $name, $ingress := .Values.ingress }} {{- if $ingress.enabled -}} {{- $ingressValues := $ingress -}} {{/* set defaults */}} - {{- if and (not $ingressValues.nameOverride) (ne $name (include "common.ingress.primary" $)) -}} + {{- if and (not $ingressValues.nameOverride) (ne $name (include "tc.common.lib.util.ingress.primary" $)) -}} {{- $_ := set $ingressValues "nameOverride" $name -}} {{- end -}} {{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}} - {{- include "common.classes.ingress" $ }} + {{- include "tc.common.class.ingress" $ }} {{- range $index, $tlsValues := $ingressValues.tls }} - {{- if .scaleCert }} + {{- if and ( .scaleCert ) ( $.Values.global.ixChartContext ) }} {{- $nameOverride := ( printf "%v-%v" "tls" $index ) -}} {{- if $ingressValues.nameOverride -}} {{- $nameOverride = ( printf "%v-%v-%v" $ingressValues.nameOverride "tls" $index ) -}} {{- end }} {{- $_ := set $tlsValues "nameOverride" $nameOverride -}} {{- $_ := set $ "ObjectValues" (dict "certHolder" $tlsValues) -}} - {{- include "common.cert.secret" $ }} + {{- include "tc.common.scale.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 -}} diff --git a/charts/common/templates/spawner/_networkPolicy.tpl b/charts/common/templates/spawner/_networkPolicy.tpl new file mode 100644 index 00000000..25e0118e --- /dev/null +++ b/charts/common/templates/spawner/_networkPolicy.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the networkPolicy objects required by the chart. +*/}} +{{- define "tc.common.spawner.networkpolicy" -}} + {{- /* Generate named networkpolicy as required */ -}} + {{- range $name, $networkPolicy := .Values.networkPolicy }} + {{- if $networkPolicy.enabled -}} + {{- $networkPolicyValues := $networkPolicy -}} + + {{/* set the default nameOverride to the networkpolicy name */}} + {{- if not $networkPolicyValues.nameOverride -}} + {{- $_ := set $networkPolicyValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "networkPolicy" $networkPolicyValues) -}} + {{- include "tc.common.class.networkpolicy" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/_pvc.tpl b/charts/common/templates/spawner/_pvc.tpl similarity index 85% rename from charts/common/templates/_pvc.tpl rename to charts/common/templates/spawner/_pvc.tpl index 608b4de6..77e171c3 100644 --- a/charts/common/templates/_pvc.tpl +++ b/charts/common/templates/spawner/_pvc.tpl @@ -1,7 +1,7 @@ {{/* Renders the Persistent Volume Claim objects required by the chart. */}} -{{- define "common.pvc" -}} +{{- define "tc.common.spawner.pvc" -}} {{- /* Generate pvc as required */ -}} {{- range $index, $PVC := .Values.persistence }} {{- if and $PVC.enabled (eq (default "pvc" $PVC.type) "pvc") (not $PVC.existingClaim) -}} @@ -10,7 +10,7 @@ Renders the Persistent Volume Claim objects required by the chart. {{- $_ := set $persistenceValues "nameOverride" $index -}} {{- end -}} {{- $_ := set $ "ObjectValues" (dict "persistence" $persistenceValues) -}} - {{- include "common.classes.pvc" $ | nindent 0 -}} + {{- include "tc.common.class.pvc" $ | nindent 0 -}} {{- end }} {{- end }} {{- end }} diff --git a/charts/common/templates/spawner/_rbac.tpl b/charts/common/templates/spawner/_rbac.tpl new file mode 100644 index 00000000..84b50100 --- /dev/null +++ b/charts/common/templates/spawner/_rbac.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the configMap objects required by the chart. +*/}} +{{- define "tc.common.spawner.rbac" -}} + {{- /* Generate named rbac as required */ -}} + {{- range $name, $rbac := .Values.rbac }} + {{- if $rbac.enabled -}} + {{- $rbacValues := $rbac -}} + + {{/* set the default nameOverride to the rbac name */}} + {{- if and (not $rbacValues.nameOverride) (ne $name (include "tc.common.lib.util.rbac.primary" $)) -}} + {{- $_ := set $rbacValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "rbac" $rbacValues) -}} + {{- include "tc.common.class.rbac" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/spawner/_secret.tpl b/charts/common/templates/spawner/_secret.tpl new file mode 100644 index 00000000..2604e1f4 --- /dev/null +++ b/charts/common/templates/spawner/_secret.tpl @@ -0,0 +1,26 @@ +{{/* +Renders the Secret objects required by the chart. +*/}} +{{- define "tc.common.spawner.secret" -}} + {{- if .Values.secretEnv }} + {{- $secretValues := .Values.secretEnv -}} + + {{- $_ := set $ "ObjectValues" (dict "secret" $secretValues) -}} + {{- include "tc.common.class.secret" $ }} + {{- end }} + + {{- /* Generate named secrets as required */ -}} + {{- range $name, $secret := .Values.secret }} + {{- if $secret.enabled -}} + {{- $secretValues := $secret -}} + + {{/* set the default nameOverride to the Secret name */}} + {{- if not $secretValues.nameOverride -}} + {{- $_ := set $secretValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "secret" $secretValues) -}} + {{- include "tc.common.class.secret" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/spawner/_service.tpl b/charts/common/templates/spawner/_service.tpl new file mode 100644 index 00000000..5156dbc5 --- /dev/null +++ b/charts/common/templates/spawner/_service.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the Service objects required by the chart. +*/}} +{{- define "tc.common.spawner.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 "tc.common.lib.util.service.primary" $)) -}} + {{- $_ := set $serviceValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "service" $serviceValues) -}} + {{- include "tc.common.class.service" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/templates/spawner/_serviceaccount.tpl b/charts/common/templates/spawner/_serviceaccount.tpl new file mode 100644 index 00000000..87288ccc --- /dev/null +++ b/charts/common/templates/spawner/_serviceaccount.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the serviceAccount objects required by the chart. +*/}} +{{- define "tc.common.spawner.serviceaccount" -}} + {{- /* Generate named serviceAccount as required */ -}} + {{- range $name, $serviceAccount := .Values.serviceAccount }} + {{- if $serviceAccount.enabled -}} + {{- $saValues := $serviceAccount -}} + + {{/* set the default nameOverride to the serviceAccount name */}} + {{- if and (not $saValues.nameOverride) (ne $name (include "tc.common.lib.util.service.primary" $)) -}} + {{- $_ := set $saValues "nameOverride" $name -}} + {{ end -}} + + {{- $_ := set $ "ObjectValues" (dict "serviceAccount" $saValues) -}} + {{- include "tc.common.class.serviceAccount" $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/common/values.yaml b/charts/common/values.yaml index c2c5bd6c..a1c42adb 100644 --- a/charts/common/values.yaml +++ b/charts/common/values.yaml @@ -93,7 +93,10 @@ global: nameOverride: # -- Set the entire name definition fullnameOverride: - isSCALE: false + # -- Set additional global labels. Helm templates can be used. + labels: {} + # -- Set additional global annotations. Helm templates can be used. + annotations: {} controller: # -- enable the controller. @@ -155,6 +158,8 @@ extraArgs: [] # -- Set Container Timezone TZ: UTC +patchInotify: true + # -- Set the primary portal for TrueNAS SCALE portal: # -- enable generation of the portal configmap @@ -191,70 +196,96 @@ stdin: false # -- Add a Horizontal Pod Autoscaler # @default -- -autoscaling: - enabled: false - target: # deploymentname - minReplicas: # 1 - maxReplicas: # 100 - targetCPUUtilizationPercentage: # 80 - targetMemoryUtilizationPercentage: # 80 +horizontalPodAutoscaler: + main: + enabled: false + # -- deployment kind of target + # @default -- main pod + targetKind: + # -- name of the targeted deployment + # @default -- main pod + target: + # -- minimum amount of replica's to spawn + # @default -- 1 + minReplicas: + # -- minimum amount of replica's to spawn + # @default -- 100 + maxReplicas: + # -- minimum amount of replica's to spawn + # @default -- 80 + targetCPUUtilizationPercentage: + # -- minimum amount of replica's to spawn + # @default -- 80 + targetMemoryUtilizationPercentage: # -- Create serviceaccount # @default -- See below serviceAccount: - # -- Specifies whether a service account should be created - create: false + main: + # -- Make this the primary serviceAccount (used in probes, notes, etc...). + # If there is more than 1 serviceAccount, make sure that only 1 serviceAccount is marked as primary. + primary: true - # -- Annotations to add to the service account - annotations: {} + # -- Specifies whether a service account should be created + enabled: false - # -- The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - name: "" + # -- Annotations to add to the service account + annotations: {} + + # -- The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" # -- Create a ClusterRole and ClusterRoleBinding # @default -- See below rbac: - # -- Enables or disables the ClusterRole and ClusterRoleBinding - enabled: false + main: + # -- Make this the primary rbac (used in probes, notes, etc...). + # If there is more than 1 rbac, make sure that only 1 rbac is marked as primary. + primary: true - # -- Set Annotations on the ClusterRole - clusterRoleLabels: {} + # -- Enables or disables the ClusterRole and ClusterRoleBinding + enabled: false - # -- Set labels on the ClusterRole - clusterRoleAnnotations: {} + # -- Set Annotations on the ClusterRole + clusterRoleLabels: {} - # -- Set Annotations on the ClusterRoleBinding + # -- Set labels on the ClusterRole + clusterRoleAnnotations: {} - clusterRoleBindingLabels: {} + # -- Set Annotations on the ClusterRoleBinding - # -- Set labels on the ClusterRoleBinding - clusterRoleBindingAnnotations: {} + clusterRoleBindingLabels: {} - # -- Set Rules on the ClusterRole - rules: {} + # -- Set labels on the ClusterRoleBinding + clusterRoleBindingAnnotations: {} - # -- Add subjects to the ClusterRoleBinding. - # includes the above created serviceaccount - subjects: {} + # -- Set Rules on the ClusterRole + rules: {} + + # -- Defines default subject serviceAccount Name. + # serviceAccountName: "" + + # -- Add subjects to the ClusterRoleBinding. + # includes the above created serviceaccount + subjects: {} # -- Configure networkPolicy for the chart here. # @default -- See below networkPolicy: - # -- Enables or disables the networkPolicy - enabled: false + main: + # -- Enables or disables the networkPolicy + enabled: false - # customizes the podSelector (defaults to the helm-chart selector-labels - # podSelector: + # customizes the podSelector (defaults to the helm-chart selector-labels + # podSelector: - # -- add or remove Policy types. Options: ingress, egress, ingress-egress - policyType: "" - - # -- add or remove egress policies - egress: [] - - # -- add or remove egress policies - ingress: [] + # -- add or remove Policy types. Options: ingress, egress, ingress-egress + policyType: "" + # -- add or remove egress policies + egress: [] + # -- add or remove egress policies + ingress: [] # -- Use this directly attach a pod to a SCALE interface. # Please be aware: This bypasses k8s services @@ -275,7 +306,7 @@ externalInterfaces: [] # -- 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: {} +secretEnv: {} # PASSWORD: my-password # -- Main environment variables. Template enabled. @@ -283,27 +314,37 @@ secret: {} # A) TZ: UTC # B) PASSWD: '{{ .Release.Name }}' # C) PASSWD: -# envFrom: -# ... +# configMapKeyRef: +# name: config-map-name +# key: key-name +# D) PASSWD: +# valueFrom: +# secretKeyRef: +# name: secret-name +# key: key-name +# ... +# E) - name: TZ +# value: UTC +# F) - name: TZ +# value: '{{ .Release.Name }}' env: {} -## Variables with values set from templates, example -## With a release name of: demo, the example env value will be: demo-admin -envTpl: {} - # TEMPLATE_VALUE: "{{ .Release.Name }}-admin" - -## Variables with values from (for example) the Downward API -## See https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/ -envValueFrom: {} - # NODE_NAME: - # fieldRef: - # fieldPath: spec.nodeName - envFrom: [] # - configMapRef: # name: config-map-name # - secretRef: # name: secret-name + +# -- Create secret objects directly from dict. +secret: + # -- Secret Name + example-secret: + # -- Enable or Disable the secret from being created + enabled: false + # -- The actual data to be loaded into the secret as stringData + # Can contain tpl templating + data: {} + # -- Custom priority class for different treatment by the scheduler priorityClassName: # system-node-critical @@ -311,6 +352,7 @@ priorityClassName: # system-node-critical schedulerName: # awkward-dangerous-scheduler # -- Allows specifying explicit hostname setting +# please be aware this breaks some guides that assume default k8s hostnames... hostname: # -- When using hostNetwork make sure you set dnsPolicy to `ClusterFirstWithHostNet` @@ -320,6 +362,7 @@ hostNetwork: false dnsPolicy: # ClusterFirst # -- Optional DNS settings, configuring the ndots option may resolve nslookup issues on some Kubernetes setups. +# By default we already specify " ndots=1 ", due to some reoccuring issues on SCALE. dnsConfig: options: - name: ndots @@ -503,11 +546,15 @@ service: # @default -- See below portsList: [] + # -- Specify the externalTrafficPolicy for the service. Options: Cluster, Local + # -- [[ref](https://kubernetes.io/docs/tutorials/services/source-ip/)] + externalTrafficPolicy: + # -- Specify the ip policy. Options: SingleStack, PreferDualStack, RequireDualStack ipFamilyPolicy: SingleStack # -- The ip families that should be used. Options: IPv4, IPv6 - ipFamilies: [ ] + ipFamilies: [] # -- Configure the Service port information here. # Additional ports can be added by adding a dictionary key similar to the 'http' service. @@ -706,9 +753,14 @@ persistence: # -- The amount of storage that is requested for the persistent volume. size: 999Gi - # - Set to true to retain the PVC upon `helm uninstall` + # -- Set to true to retain the PVC upon `helm uninstall` retain: false + # -- Add additional custom spec parameters + # Used, for example, by openEBS to set dataset parameters + # Be sure not to add duplicates of the above variables + spec: {} + # -- Create an emptyDir volume to share between all containers # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) # @default -- See below @@ -768,35 +820,6 @@ persistence: # specify a size for memory backed volumes. sizeLimit: # 1Gi - - # -- Hostpath mountpoint to allow mounting the /usr/bin folder to disable docker-compose - # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) - # @default -- See below - # TODO Delete this once iX has blocked docker-compose - host-usr-bin: - enabled: true - noMount: true - type: hostPath - # -- Which path on the host should be mounted. - hostPath: /usr/bin - # -- Where to mount the path in the main container. - # Defaults to the value of `hostPath` - mountPath: "/host/usr/bin" - - # -- Hostpath mountpoint to allow mounting the /bin folder to disable docker-compose - # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) - # @default -- See below - # TODO Delete this once iX has blocked docker-compose - host-bin: - enabled: true - noMount: true - type: hostPath - # -- Which path on the host should be mounted. - hostPath: /bin - # -- Where to mount the path in the main container. - # Defaults to the value of `hostPath` - mountPath: "/host/bin" - # -- Example of a hostPath mount # [[ref]]https://kubernetes.io/docs/concepts/storage/volumes/#hostpath) # @default -- See below @@ -809,7 +832,7 @@ persistence: setPermissions: false # -- Where to mount the path in the main container. # Defaults to the value of `hostPath` - mountPath: "" # /myDev + mountPath: # /myDev # -- Specifying a hostPathType adds a check before trying to mount the path. # See Kubernetes documentation for options. hostPathType: "" @@ -828,7 +851,7 @@ persistence: setPermissionsSimple: false # -- Where to mount the path in the main container. # Defaults to the value of `hostPath` - mountPath: "" # /myDev + mountPath: # /myDev # -- Specifying a hostPathType adds a check before trying to mount the path. # See Kubernetes documentation for options. hostPathType: "" @@ -863,7 +886,7 @@ persistence: # -- Where to mount the volume in the main container. # Defaults to `/`, # setting to '-' creates the volume but disables the volumeMount. - mountPath: # /custom-mount + mountPath: # /custom-mount # -- Specify if the volume should be mounted read-only. readOnly: false @@ -877,7 +900,7 @@ persistence: # -- Where to mount the volume in the main container. # Defaults to `/`, # setting to '-' creates the volume but disables the volumeMount. - mountPath: # /custom-mount + mountPath: # /custom-mount # -- Specify if the volume should be mounted read-only. readOnly: false # -- define the default mount mode for the secret @@ -887,6 +910,22 @@ persistence: - key: username path: my-group/my-username + # -- Example of a nfs mount + # @default -- See below + nfs-example: + enabled: false + type: nfs + # -- Specify the name of the secret object to be mounted + server: 192.168.10.10 + # -- define the default mount path on the nfs server + path: "/somepath" + # -- Where to mount the volume in the main container. + # Defaults to `/`, + # setting to '-' creates the volume but disables the volumeMount. + mountPath: # /custom-mount + # -- Specify if the volume should be mounted read-only. + readOnly: false + # -- Used in conjunction with `controller.type: statefulset` to create individual disks for each instance. volumeClaimTemplates: [] # data: @@ -943,6 +982,16 @@ resources: cpu: 10m memory: 50Mi +# -- used to add SCALE GPU configuration +scaleGPU: + +# -- used to fake certain states for tests +test: + # -- fake install for install initContainers + install: false + # -- fake upgrade for upgrade initContainers + upgrade: false + # -- The common chart supports several add-ons. These can be configured under this key. # @default -- See below addons: @@ -977,7 +1026,7 @@ addons: # -- All variables specified here will be added to the vpn sidecar container # See the documentation of the VPN image for all config values envList: [] - #- name: someenv + # - name: someenv # value: somevalue # -- Provide a customized vpn configuration file to be used by the VPN. @@ -1005,7 +1054,7 @@ addons: # -- All variables specified here will be added to the codeserver sidecar container # See the documentation of the codeserver image for all config values envList: [] - #- name: someenv + # - name: someenv # value: somevalue # -- Set codeserver command line arguments. # Consider setting --user-data-dir to a persistent location to preserve code-server setting changes @@ -1071,7 +1120,7 @@ addons: # -- All variables specified here will be added to the promtail sidecar container # See the documentation of the promtail image for all config values envList: [] - #- name: someenv + # - name: someenv # value: somevalue # -- Set promtail command line arguments args: [] @@ -1096,7 +1145,7 @@ addons: # -- All variables specified here will be added to the netshoot sidecar container # See the documentation of the netshoot image for all config values envList: [] - #- name: someenv + # - name: someenv # value: somevalue ## diff --git a/helper-charts/common-test/Chart.yaml b/helper-charts/common-test/Chart.yaml index 3580bece..9434217d 100644 --- a/helper-charts/common-test/Chart.yaml +++ b/helper-charts/common-test/Chart.yaml @@ -1,9 +1,9 @@ apiVersion: v2 -appVersion: "1.8.0" +appVersion: "" dependencies: - name: common repository: file://../../charts/common - version: '>=0.0.1' + version: n/a deprecated: false description: Helper chart to test different use cases of the common library home: https://github.com/truecharts/apps/tree/master/charts/library/common-test @@ -22,4 +22,4 @@ name: common-test sources: - https://github.com/truecharts/apps/tree/master/charts/library/common-test type: application -version: 3.3.9 +version: 4.0.0 diff --git a/helper-charts/common-test/charts/common-9.1.0.tgz b/helper-charts/common-test/charts/common-9.1.0.tgz deleted file mode 100644 index 0018a2d42b741e4264e08284a511970149759ad0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42886 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 G4g>(UvBSgw diff --git a/helper-charts/common-test/ci/configmap-values.yaml b/helper-charts/common-test/ci/configmap-values.yaml index 65cfd82d..3ba33a86 100644 --- a/helper-charts/common-test/ci/configmap-values.yaml +++ b/helper-charts/common-test/ci/configmap-values.yaml @@ -36,7 +36,7 @@ persistence: configmap: enabled: true type: configMap - objectName: '{{ include "common.names.fullname" . -}}-configmap-example' + objectName: '{{ include "tc.common.names.fullname" . -}}-configmap-example' mountPath: /configmapmount diff --git a/helper-charts/common-test/ci/networkpolicy-values.yaml b/helper-charts/common-test/ci/networkpolicy-values.yaml index 72e6a7fc..fe42c9a8 100644 --- a/helper-charts/common-test/ci/networkpolicy-values.yaml +++ b/helper-charts/common-test/ci/networkpolicy-values.yaml @@ -81,47 +81,48 @@ probes: "until": "Thu Dec 29 15:05:38 2022" networkPolicy: - enabled: true + main: + enabled: true - ingress: - - from: - - ipBlock: - cidr: 172.17.0.0/16 - except: - - 172.17.1.0/24 - - namespaceSelector: - matchLabels: - project: myproject - - podSelector: - matchLabels: - role: frontend - - namespaceSelector: - matchLabels: - project: myproject2 - podSelector: - matchLabels: - role: frontend2 - ports: - - protocol: TCP - port: 6379 - egress: - - to: - - ipBlock: - cidr: 172.17.2.0/16 - except: - - 172.17.2.0/24 - - namespaceSelector: - matchLabels: - project: myproject3 - - podSelector: - matchLabels: - role: frontend3 - - namespaceSelector: - matchLabels: - project: myproject4 - podSelector: - matchLabels: - role: frontend4 - ports: - - protocol: TCP - port: 5978 + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: myproject + - podSelector: + matchLabels: + role: frontend + - namespaceSelector: + matchLabels: + project: myproject2 + podSelector: + matchLabels: + role: frontend2 + ports: + - protocol: TCP + port: 6379 + egress: + - to: + - ipBlock: + cidr: 172.17.2.0/16 + except: + - 172.17.2.0/24 + - namespaceSelector: + matchLabels: + project: myproject3 + - podSelector: + matchLabels: + role: frontend3 + - namespaceSelector: + matchLabels: + project: myproject4 + podSelector: + matchLabels: + role: frontend4 + ports: + - protocol: TCP + port: 5978 diff --git a/helper-charts/common-test/ci/persistence-values.yaml b/helper-charts/common-test/ci/persistence-values.yaml index a194c3ee..aa5796b4 100644 --- a/helper-charts/common-test/ci/persistence-values.yaml +++ b/helper-charts/common-test/ci/persistence-values.yaml @@ -166,6 +166,25 @@ persistence: hostPathType: "" readOnly: false + pvc-auto: + enabled: true + setPermissions: true + annotationsList: [] + annotations: {} + labelsList: [] + labels: {} + type: pvc + forceName: "" + mountPath: /autotest + readOnly: false + nameOverride: + storageClass: + existingClaim: + subPath: + accessMode: ReadWriteOnce + size: 1Gi + retain: false + "ixCertificateAuthorities": {} "ixCertificates": diff --git a/helper-charts/common-test/ci/rbac-values.yaml b/helper-charts/common-test/ci/rbac-values.yaml index 95e40c59..000998f9 100644 --- a/helper-charts/common-test/ci/rbac-values.yaml +++ b/helper-charts/common-test/ci/rbac-values.yaml @@ -14,51 +14,53 @@ args: - '8080' rbac: - enabled: true - rules: - - apiGroups: - - "" - resources: - - services - - endpoints - - secrets - verbs: - - get - - list - - watch - - apiGroups: - - extensions - - networking.k8s.io - resources: - - ingresses - - ingressclasses - verbs: - - get - - list - - watch - - apiGroups: - - extensions - - networking.k8s.io - resources: - - ingresses/status - verbs: - - update - - apiGroups: - - traefik.containo.us - resources: - - ingressroutes - - ingressroutetcps - - ingressrouteudps - - middlewares - - middlewaretcps - - tlsoptions - - tlsstores - - traefikservices - - serverstransports - verbs: - - get - - list - - watch + main: + enabled: true + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - traefik.containo.us + resources: + - ingressroutes + - ingressroutetcps + - ingressrouteudps + - middlewares + - middlewaretcps + - tlsoptions + - tlsstores + - traefikservices + - serverstransports + verbs: + - get + - list + - watch serviceAccount: - create: true + main: + create: true diff --git a/helper-charts/common-test/templates/common.yaml b/helper-charts/common-test/templates/common.yaml index a6613c2c..c1a366e1 100644 --- a/helper-charts/common-test/templates/common.yaml +++ b/helper-charts/common-test/templates/common.yaml @@ -1 +1 @@ -{{ include "common.all" . }} +{{ include "tc.common.loader.all" . }} diff --git a/helper-charts/common-test/tests/addons/codeserver_test.yaml b/helper-charts/common-test/tests/addons/codeserver_test.yaml new file mode 100644 index 00000000..d75a66a4 --- /dev/null +++ b/helper-charts/common-test/tests/addons/codeserver_test.yaml @@ -0,0 +1,167 @@ +suite: addon codeserver +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + not: true + equal: + path: spec.template.spec.containers[0].name + value: codeserver + + - it: addon enabled should pass + set: + addons: + codeserver: + enabled: true + volumeMounts: + - name: "config" + mountPath: "/data/config" + asserts: + - hasDocuments: + count: 3 + - documentIndex: 0 + isKind: + of: Service + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: &AddonServiceDocument 2 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: codeserver + - documentIndex: *AddonServiceDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: addon enabled with deployKey should pass + set: + addons: + codeserver: + enabled: true + git: + deployKey: test + volumeMounts: + - name: "config" + mountPath: "/data/config" + asserts: + - hasDocuments: + count: 4 + - documentIndex: &AddonDeployKeySecretDocument 0 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 2 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /root/.ssh/id_rsa + name: deploykey + subPath: id_rsa + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: deploykey + secret: + defaultMode: 256 + items: + - key: id_rsa + path: id_rsa + secretName: RELEASE-NAME-common-test-deploykey + - documentIndex: *AddonDeployKeySecretDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-deploykey + + - it: addon enabled with InlineBase64 deployKey should pass + set: + addons: + codeserver: + enabled: true + git: + deployKeyBase64: dGVzdEtleQ== + volumeMounts: + - name: "config" + mountPath: "/data/config" + asserts: + - hasDocuments: + count: 4 + - documentIndex: &AddonDeployKeySecretDocument 0 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 2 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /root/.ssh/id_rsa + name: deploykey + subPath: id_rsa + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: deploykey + secret: + defaultMode: 256 + items: + - key: id_rsa + path: id_rsa + secretName: RELEASE-NAME-common-test-deploykey + - documentIndex: *AddonDeployKeySecretDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-deploykey + + - it: addon enabled with existingSecret deployKey should pass + set: + addons: + codeserver: + enabled: true + git: + deployKeySecret: test-secret + volumeMounts: + - name: "config" + mountPath: "/data/config" + asserts: + - hasDocuments: + count: 3 + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /root/.ssh/id_rsa + name: deploykey + subPath: id_rsa + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: deploykey + secret: + defaultMode: 256 + items: + - key: id_rsa + path: id_rsa + secretName: test-secret diff --git a/helper-charts/common-test/tests/addons/netshoot_test.yaml b/helper-charts/common-test/tests/addons/netshoot_test.yaml new file mode 100644 index 00000000..45b2967e --- /dev/null +++ b/helper-charts/common-test/tests/addons/netshoot_test.yaml @@ -0,0 +1,38 @@ +suite: addon netshoot +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + not: true + equal: + path: spec.template.spec.containers[0].name + value: netshoot + + - it: addon enabled should pass + set: + addons: + netshoot: + enabled: true + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + equal: + path: spec.template.spec.containers[1].name + value: netshoot diff --git a/helper-charts/common-test/tests/addons/vpn_test.yaml b/helper-charts/common-test/tests/addons/vpn_test.yaml new file mode 100644 index 00000000..8db67590 --- /dev/null +++ b/helper-charts/common-test/tests/addons/vpn_test.yaml @@ -0,0 +1,80 @@ +suite: addon vpn +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &DeploymentDocument 0 + isKind: + of: Deployment + - documentIndex: 1 + isKind: + of: Service + - documentIndex: *DeploymentDocument + not: true + equal: + path: spec.template.spec.containers[0].name + value: vpn + + - it: addon enabled with configFile should pass + set: + addons: + vpn: + type: openvpn + configFile: + enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: &AddonVPNConfigSecretDocument 0 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /vpn/vpn.conf + name: vpnconfig + - documentIndex: *DeploymentDocument + contains: + path: spec.template.spec.volumes + content: + name: vpnconfig + hostPath: + path: /vpn/vpn.conf + type: File + - documentIndex: *AddonVPNConfigSecretDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-openvpn + + - it: addon enabled with managed secret should pass + set: + addons: + vpn: + type: openvpn + openvpn: + username: something + password: something + asserts: + - hasDocuments: + count: 3 + - documentIndex: &SecretDocument 0 + isKind: + of: Secret + - documentIndex: &DeploymentDocument 1 + isKind: + of: Deployment + - documentIndex: 2 + isKind: + of: Service + - documentIndex: *DeploymentDocument + not: true + equal: + path: spec.template.spec.containers[0].name + value: vpn diff --git a/helper-charts/common-test/tests/configmap/metadata_test.yaml b/helper-charts/common-test/tests/configmap/metadata_test.yaml new file mode 100644 index 00000000..27b9271b --- /dev/null +++ b/helper-charts/common-test/tests/configmap/metadata_test.yaml @@ -0,0 +1,87 @@ +suite: configmap metadata +templates: + - common.yaml +tests: + - it: default metadata should pass + set: + configmap: + config: + enabled: true + asserts: + - documentIndex: &ConfigmapDocument 0 + isKind: + of: ConfigMap + - documentIndex: *ConfigmapDocument + isNull: + path: metadata.annotations + - documentIndex: *ConfigmapDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + configmap: + config: + enabled: true + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ConfigmapDocument 0 + isKind: + of: ConfigMap + - documentIndex: *ConfigmapDocument + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *ConfigmapDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + configmap: + config: + enabled: true + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ConfigmapDocument 0 + isKind: + of: ConfigMap + - documentIndex: *ConfigmapDocument + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + - documentIndex: *ConfigmapDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/configmap/names_test.yaml b/helper-charts/common-test/tests/configmap/names_test.yaml new file mode 100644 index 00000000..764e75fa --- /dev/null +++ b/helper-charts/common-test/tests/configmap/names_test.yaml @@ -0,0 +1,91 @@ +suite: configMap names +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + not: true + isKind: + of: ConfigMap + - documentIndex: 1 + not: true + isKind: + of: ConfigMap + + - it: with disabled configMap should pass + set: + configmap: + config: + enabled: false + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + not: true + isKind: + of: ConfigMap + - documentIndex: 1 + not: true + isKind: + of: ConfigMap + + - it: with multiple configMap should pass + set: + configmap: + config: + enabled: true + data: + foo: bar + secondary: + enabled: true + asserts: + - hasDocuments: + count: 4 + - documentIndex: 0 + isKind: + of: ConfigMap + - documentIndex: 0 + isNotNull: + path: metadata.name + - documentIndex: 1 + isKind: + of: ConfigMap + - documentIndex: 1 + isNotNull: + path: metadata.name + + - it: default name should pass + set: + configmap: + config: + enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 0 + isKind: + of: ConfigMap + - documentIndex: 0 + equal: + path: metadata.name + value: RELEASE-NAME-common-test-config + + - it: with nameOverride should pass + set: + configmap: + config: + enabled: true + nameOverride: http + asserts: + - hasDocuments: + count: 3 + - documentIndex: 0 + isKind: + of: ConfigMap + - documentIndex: 0 + equal: + path: metadata.name + value: RELEASE-NAME-common-test-http diff --git a/helper-charts/common-test/tests/container/args_test.yaml b/helper-charts/common-test/tests/container/args_test.yaml new file mode 100644 index 00000000..b17ddedb --- /dev/null +++ b/helper-charts/common-test/tests/container/args_test.yaml @@ -0,0 +1,41 @@ +suite: container args override +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + isNull: + path: spec.template.spec.containers[0].args + + - it: single string should pass + set: + args: sleep infinity + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].args + value: + - sleep infinity + + - it: list of strings should pass + set: + args: + - sleep + - infinity + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].args + value: + - sleep + - infinity diff --git a/helper-charts/common-test/tests/container/command_test.yaml b/helper-charts/common-test/tests/container/command_test.yaml new file mode 100644 index 00000000..78c272b7 --- /dev/null +++ b/helper-charts/common-test/tests/container/command_test.yaml @@ -0,0 +1,41 @@ +suite: container command override +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + isNull: + path: spec.template.spec.containers[0].command + + - it: single string should pass + set: + command: /bin/sh + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].command + value: + - /bin/sh + + - it: list of strings should pass + set: + command: + - /bin/sh + - -c + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].command + value: + - /bin/sh + - -c diff --git a/helper-charts/common-test/tests/container/env_test.yaml b/helper-charts/common-test/tests/container/env_test.yaml new file mode 100644 index 00000000..1b8f9ff3 --- /dev/null +++ b/helper-charts/common-test/tests/container/env_test.yaml @@ -0,0 +1,192 @@ +suite: container env values +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env + value: + - name: PUID + value: "568" + - name: USER_ID + value: "568" + - name: UID + value: "568" + - name: UMASK + value: "2" + - name: UMASK_SET + value: "2" + - name: PGID + value: "568" + - name: GROUP_ID + value: "568" + - name: GID + value: "568" + - name: S6_READ_ONLY_ROOT + value: "1" + - name: NVIDIA_VISIBLE_DEVICES + value: void + - name: TZ + value: UTC + + - it: KeyValue string should pass + set: + env: + string: value_of_env + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: string + value: value_of_env + + - it: KeyValue float should pass + set: + env: + string: 4.2 + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: string + value: "4.2" + + - it: KeyValue int should pass + set: + env: + string: 1 + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: string + value: "1" + + - it: KeyValue float should pass + set: + env: + string: 4.2 + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: string + value: "4.2" + + - it: List should pass + set: + env: + - name: STATIC_ENV_FROM_LIST + value: STATIC_ENV_VALUE_FROM_LIST + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: STATIC_ENV_FROM_LIST + value: STATIC_ENV_VALUE_FROM_LIST + + - it: Explicit ValueFrom in list should pass + set: + env: + - name: DYNAMIC_ENV_FROM_LIST + valueFrom: + fieldRef: + fieldPath: spec.nodeName + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: DYNAMIC_ENV_FROM_LIST + valueFrom: + fieldRef: + fieldPath: spec.nodeName + + - it: Implicit ValueFrom should pass + set: + env: + DYNAMIC_ENV: + fieldRef: + fieldPath: spec.nodeName + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: DYNAMIC_ENV + valueFrom: + fieldRef: + fieldPath: spec.nodeName + + - it: Templated value should pass + set: + env: + DYNAMIC_ENV: "{{ .Release.Name }}-admin" + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: DYNAMIC_ENV + value: RELEASE-NAME-admin + + - it: Combined KeyValue with Explicit ValueFrom should pass + set: + env: + STATIC_ENV: static + DYNAMIC_ENV: + valueFrom: + fieldRef: + fieldPath: spec.nodeName + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[11] + value: + name: DYNAMIC_ENV + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].env[12] + value: + name: STATIC_ENV + value: static diff --git a/helper-charts/common-test/tests/container/envfrom_test.yaml b/helper-charts/common-test/tests/container/envfrom_test.yaml new file mode 100644 index 00000000..12620b94 --- /dev/null +++ b/helper-charts/common-test/tests/container/envfrom_test.yaml @@ -0,0 +1,43 @@ +suite: container envFrom values +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + isNull: + path: spec.template.spec.containers[0].envFrom + + - it: explicit envFrom should pass + set: + envFrom: + - secretRef: + name: myCustomSecret + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].envFrom[0] + value: + secretRef: + name: myCustomSecret + + - it: from secretEnv should pass + set: + secretEnv: + STATIC_SECRET: value_of_secret + asserts: + - documentIndex: &DeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].envFrom[0] + value: + secretRef: + name: RELEASE-NAME-common-test diff --git a/helper-charts/common-test/tests/container/ports_test.yaml b/helper-charts/common-test/tests/container/ports_test.yaml new file mode 100644 index 00000000..78520f04 --- /dev/null +++ b/helper-charts/common-test/tests/container/ports_test.yaml @@ -0,0 +1,95 @@ +suite: container ports +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].ports[0] + value: + containerPort: 8080 + name: main + protocol: TCP + + - it: custom port should pass + set: + service: + main: + ports: + main: + enabled: false + server: + enabled: true + port: 8081 + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].ports[0] + value: + containerPort: 8081 + name: server + protocol: TCP + + - it: HTTP protocol should pass + set: + service: + main: + ports: + main: + protocol: HTTP + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].ports[0] + value: + containerPort: 8080 + name: main + protocol: TCP + + - it: HTTPS protocol should pass + set: + service: + main: + ports: + main: + protocol: HTTPS + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].ports[0] + value: + containerPort: 8080 + name: main + protocol: TCP + + - it: UDP protocol should pass + set: + service: + main: + ports: + main: + protocol: UDP + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].ports[0] + value: + containerPort: 8080 + name: main + protocol: UDP diff --git a/helper-charts/common-test/tests/container/volumemounts_test.yaml b/helper-charts/common-test/tests/container/volumemounts_test.yaml new file mode 100644 index 00000000..1dcc78fb --- /dev/null +++ b/helper-charts/common-test/tests/container/volumemounts_test.yaml @@ -0,0 +1,129 @@ +suite: container volumeMounts +templates: + - common.yaml +tests: + - it: no persistence should pass + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - mountPath: /shared + name: shared + - mountPath: /tmp + name: temp + - mountPath: /var/logs + name: varlogs + + - it: default should pass + set: + persistence: + config: + enabled: true + asserts: + - documentIndex: &DeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: config + mountPath: /config + + - it: emptyDir should pass + set: + persistence: + cache: + enabled: true + type: emptyDir + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: cache + mountPath: /cache + + - it: custom mountPath should pass + set: + persistence: + config: + enabled: true + mountPath: /custom + accessMode: ReadWriteMany + size: 1G + asserts: + - documentIndex: &DeploymentDoc 1 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: config + mountPath: /custom + + - it: mount with subPath should pass + set: + persistence: + config: + enabled: true + existingClaim: myClaim + subPath: "mySubPath" + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: config + mountPath: /config + subPath: mySubPath + + - it: hostPath with custom mountPath should pass + set: + persistence: + config: + enabled: true + type: hostPath + mountPath: /data + hostPath: /tmp + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: config + mountPath: /data + + - it: hostPath mount with subPath should pass + set: + persistence: + config: + enabled: true + type: hostPath + hostPath: /dev + subPath: mySubPath + asserts: + - documentIndex: &DeploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *DeploymentDoc + equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: config + mountPath: /dev + subPath: mySubPath diff --git a/helper-charts/common-test/tests/controller/metadata_daemonset_test.yaml b/helper-charts/common-test/tests/controller/metadata_daemonset_test.yaml new file mode 100644 index 00000000..ad0686d1 --- /dev/null +++ b/helper-charts/common-test/tests/controller/metadata_daemonset_test.yaml @@ -0,0 +1,83 @@ +suite: controller metadata daemonset +templates: + - common.yaml +tests: + - it: default metadata should pass + set: + controller.type: daemonset + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: DaemonSet + - documentIndex: *ControllerDoc + isNull: + path: metadata.annotations + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + controller: + type: daemonset + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: DaemonSet + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + controller: + type: daemonset + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: DaemonSet + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/controller/metadata_deployment_test.yaml b/helper-charts/common-test/tests/controller/metadata_deployment_test.yaml new file mode 100644 index 00000000..5e6cefc7 --- /dev/null +++ b/helper-charts/common-test/tests/controller/metadata_deployment_test.yaml @@ -0,0 +1,83 @@ +suite: controller metadata deployment +templates: + - common.yaml +tests: + - it: default metadata should pass + set: + controller.type: deployment + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: Deployment + - documentIndex: *ControllerDoc + isNull: + path: metadata.annotations + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + controller: + type: deployment + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: Deployment + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + controller: + type: deployment + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: Deployment + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/controller/metadata_statefulset_test.yaml b/helper-charts/common-test/tests/controller/metadata_statefulset_test.yaml new file mode 100644 index 00000000..16261e17 --- /dev/null +++ b/helper-charts/common-test/tests/controller/metadata_statefulset_test.yaml @@ -0,0 +1,83 @@ +suite: controller metadata statefulset +templates: + - common.yaml +tests: + - it: default metadata should pass + set: + controller.type: statefulset + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: StatefulSet + - documentIndex: *ControllerDoc + isNull: + path: metadata.annotations + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + controller: + type: statefulset + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: StatefulSet + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + controller: + type: statefulset + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: StatefulSet + - documentIndex: *ControllerDoc + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + - documentIndex: *ControllerDoc + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/controller/type_test.yaml b/helper-charts/common-test/tests/controller/type_test.yaml new file mode 100644 index 00000000..59bb9fe8 --- /dev/null +++ b/helper-charts/common-test/tests/controller/type_test.yaml @@ -0,0 +1,56 @@ +suite: controller types +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: Deployment + - documentIndex: *ControllerDoc + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: daemonset should pass + set: + controller.type: daemonset + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: DaemonSet + - documentIndex: *ControllerDoc + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: statefulset should pass + set: + controller.type: statefulset + asserts: + - documentIndex: &ControllerDoc 0 + isKind: + of: StatefulSet + - documentIndex: *ControllerDoc + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: disabled should pass + set: + controller.enabled: false + asserts: + - hasDocuments: + count: 1 + - documentIndex: &ControllerDoc 0 + not: true + isKind: + of: StatefulSet + - documentIndex: *ControllerDoc + not: true + isKind: + of: DaemonSet + - documentIndex: *ControllerDoc + not: true + isKind: + of: Controller diff --git a/helper-charts/common-test/tests/ingress/metadata_test.yaml b/helper-charts/common-test/tests/ingress/metadata_test.yaml new file mode 100644 index 00000000..f3df841d --- /dev/null +++ b/helper-charts/common-test/tests/ingress/metadata_test.yaml @@ -0,0 +1,91 @@ +suite: ingress metadata +templates: + - common.yaml +tests: + - it: default metadata should pass + set: + ingress.main.enabled: true + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: metadata.annotations + value: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: default-chain-basic@kubernetescrd + + - documentIndex: *IngressDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + ingress.main: + enabled: true + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: metadata.annotations + value: + test_annotation: test + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: default-chain-basic@kubernetescrd + - documentIndex: *IngressDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + ingress.main: + enabled: true + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.middlewares: default-chain-basic@kubernetescrd + - documentIndex: *IngressDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/ingress/presence_test.yaml b/helper-charts/common-test/tests/ingress/presence_test.yaml new file mode 100644 index 00000000..ace5582e --- /dev/null +++ b/helper-charts/common-test/tests/ingress/presence_test.yaml @@ -0,0 +1,71 @@ +suite: ingress presence +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + not: true + isKind: + of: Ingress + - documentIndex: 1 + not: true + isKind: + of: Ingress + + - it: explicitly disabled should pass + set: + ingress.main.enabled: false + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + not: true + isKind: + of: Ingress + - documentIndex: 1 + not: true + isKind: + of: Ingress + + - it: explicitly enabled should pass + set: + ingress.main.enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 0 + not: true + isKind: + of: Ingress + - documentIndex: 1 + not: true + isKind: + of: Ingress + - documentIndex: 2 + isKind: + of: Ingress + + - it: multiple enabled should pass + set: + ingress.main.enabled: true + ingress.test.enabled: true + asserts: + - hasDocuments: + count: 4 + - documentIndex: 0 + not: true + isKind: + of: Ingress + - documentIndex: 1 + not: true + isKind: + of: Ingress + - documentIndex: 2 + isKind: + of: Ingress + - documentIndex: 3 + isKind: + of: Ingress diff --git a/helper-charts/common-test/tests/ingress/service_reference_test.yaml b/helper-charts/common-test/tests/ingress/service_reference_test.yaml new file mode 100644 index 00000000..ffa626ea --- /dev/null +++ b/helper-charts/common-test/tests/ingress/service_reference_test.yaml @@ -0,0 +1,39 @@ +suite: ingress service reference +templates: + - common.yaml +tests: + - it: default should pass + set: + ingress.main.enabled: true + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend + value: + serviceName: RELEASE-NAME-common-test + servicePort: 8080 + + - it: custom service reference should pass + set: + ingress.main: + enabled: true + hosts: + - host: chart-test.local + paths: + - path: / + service: + name: pathService + port: 1234 + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].backend + value: + serviceName: pathService + servicePort: 1234 diff --git a/helper-charts/common-test/tests/ingress/tls_test.yaml b/helper-charts/common-test/tests/ingress/tls_test.yaml new file mode 100644 index 00000000..e66a002f --- /dev/null +++ b/helper-charts/common-test/tests/ingress/tls_test.yaml @@ -0,0 +1,72 @@ +suite: ingress tls +templates: + - common.yaml +tests: + - it: default should pass + set: + ingress.main.enabled: true + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + isNull: + path: spec.tls + + - it: tls enabled should pass + set: + ingress.main: + enabled: true + tls: + - secretName: test + hosts: + - hostname + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.tls[0] + value: + secretName: test + hosts: + - hostname + + - it: tls enabled without secret should pass + set: + ingress.main: + enabled: true + tls: + - hosts: + - hostname + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.tls[0] + value: + hosts: + - hostname + + - it: tls enabled with secret template should pass + set: + ingress.main: + enabled: true + tls: + - secretName: "{{ .Release.Name }}-secret" + hosts: + - hostname + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.tls[0] + value: + secretName: RELEASE-NAME-secret + hosts: + - hostname diff --git a/helper-charts/common-test/tests/ingress/values_test.yaml b/helper-charts/common-test/tests/ingress/values_test.yaml new file mode 100644 index 00000000..ed142166 --- /dev/null +++ b/helper-charts/common-test/tests/ingress/values_test.yaml @@ -0,0 +1,72 @@ +suite: ingress values +templates: + - common.yaml +tests: + - it: default should pass + set: + ingress.main.enabled: true + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].host + value: chart-example.local + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].path + value: "/" + + - it: custom host and path should pass + set: + ingress.main: + enabled: true + hosts: + - host: chart-test.local + paths: + - path: /test + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].host + value: chart-test.local + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].path + value: "/test" + + - it: host with template should pass + set: + ingress.main: + enabled: true + hosts: + - host: "{{ .Release.Name }}.hostname" + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].host + value: RELEASE-NAME.hostname + + - it: path with template should pass + set: + ingress.main: + enabled: true + hosts: + - host: chart-test.local + paths: + - path: "/{{ .Release.Name }}.path" + asserts: + - documentIndex: &IngressDocument 2 + isKind: + of: Ingress + - documentIndex: *IngressDocument + equal: + path: spec.rules[0].http.paths[0].path + value: "/RELEASE-NAME.path" diff --git a/helper-charts/common-test/tests/persistence/claimnames_test.yaml b/helper-charts/common-test/tests/persistence/claimnames_test.yaml new file mode 100644 index 00000000..81776125 --- /dev/null +++ b/helper-charts/common-test/tests/persistence/claimnames_test.yaml @@ -0,0 +1,78 @@ +suite: persistence claimnames +templates: + - common.yaml +tests: + - it: default should pass + set: + persistence: + config: + enabled: true + asserts: + - documentIndex: 1 + isKind: + of: Deployment + - documentIndex: 1 + equal: + path: spec.template.spec.volumes[0] + value: + name: config + persistentVolumeClaim: + claimName: RELEASE-NAME-common-test-config + + - it: with existingClaim should pass + set: + persistence: + existingClaim: + enabled: true + existingClaim: myClaim + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: existingClaim + persistentVolumeClaim: + claimName: myClaim + + - it: disabled suffix should pass + set: + persistence: + claimWithoutSuffix: + enabled: true + nameOverride: "-" + accessMode: ReadWriteMany + size: 1G + asserts: + - documentIndex: 1 + isKind: + of: Deployment + - documentIndex: 1 + equal: + path: spec.template.spec.volumes[0] + value: + name: claimWithoutSuffix + persistentVolumeClaim: + claimName: RELEASE-NAME-common-test + + - it: custom suffix should pass + set: + persistence: + claimWithNameOverride: + enabled: true + nameOverride: suffix + accessMode: ReadWriteMany + size: 1G + asserts: + - documentIndex: 1 + isKind: + of: Deployment + - documentIndex: 1 + equal: + path: spec.template.spec.volumes[0] + value: + name: claimWithNameOverride + persistentVolumeClaim: + claimName: RELEASE-NAME-common-test-suffix diff --git a/helper-charts/common-test/tests/persistence/emptydir_test.yaml b/helper-charts/common-test/tests/persistence/emptydir_test.yaml new file mode 100644 index 00000000..02cb1914 --- /dev/null +++ b/helper-charts/common-test/tests/persistence/emptydir_test.yaml @@ -0,0 +1,60 @@ +suite: persistence emptydir +templates: + - common.yaml +tests: + - it: default emptyDir should pass + set: + persistence: + config: + enabled: true + type: emptyDir + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: config + emptyDir: {} + + - it: emptyDir with medium should pass + set: + persistence: + config: + enabled: true + type: emptyDir + medium: memory + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: config + emptyDir: + medium: memory + + - it: emptyDir with medium and sizeLimit should pass + set: + persistence: + config: + enabled: true + type: emptyDir + medium: memory + sizeLimit: 1Gi + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: config + emptyDir: + medium: memory + sizeLimit: 1Gi diff --git a/helper-charts/common-test/tests/persistence/hostpath_test.yaml b/helper-charts/common-test/tests/persistence/hostpath_test.yaml new file mode 100644 index 00000000..40ce62cd --- /dev/null +++ b/helper-charts/common-test/tests/persistence/hostpath_test.yaml @@ -0,0 +1,45 @@ +suite: persistence hostpath +templates: + - common.yaml +tests: + - it: hostPath should pass + set: + persistence: + hostpathmounts-data: + enabled: true + type: hostPath + hostPath: "/tmp1" + mountPath: "/data" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: hostpathmounts-data + hostPath: + path: /tmp1 + + - it: hostPath with type should pass + set: + persistence: + hostpathmounts-with-type: + enabled: true + type: hostPath + hostPath: "/tmp2" + hostPathType: "Directory" + mountPath: "/data2" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: hostpathmounts-with-type + hostPath: + path: /tmp2 + type: Directory diff --git a/helper-charts/common-test/tests/persistence/types_test.yaml b/helper-charts/common-test/tests/persistence/types_test.yaml new file mode 100644 index 00000000..f0bed3c4 --- /dev/null +++ b/helper-charts/common-test/tests/persistence/types_test.yaml @@ -0,0 +1,127 @@ +suite: persistence types +templates: + - common.yaml +tests: + - it: custom persistence type should pass + set: + persistence: + custom-mount: + enabled: true + type: custom + volumeSpec: + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: custom-mount + downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + + - it: configmap persistence type should pass + set: + persistence: + configmap: + enabled: true + type: configMap + objectName: mySettings + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: configmap + configMap: + name: mySettings + + - it: configmap persistence type with name template should pass + set: + persistence: + configmap: + enabled: true + type: configMap + objectName: "{{ include \"tc.common.names.fullname\" $ }}-config" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: configmap + configMap: + name: RELEASE-NAME-common-test-config + + - it: secret persistence type should pass + set: + persistence: + secret: + enabled: true + type: secret + objectName: mySettings + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: secret + secret: + secretName: mySettings + + - it: secret persistence type with name template should pass + set: + persistence: + secret: + enabled: true + type: secret + objectName: "{{ .Release.Name }}-config" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: secret + secret: + secretName: RELEASE-NAME-config + + - it: nfs persistence type should pass + set: + persistence: + nfs: + enabled: true + type: nfs + server: 10.10.0.8 + path: /tank/nas/library + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.volumes[0] + value: + name: nfs + nfs: + path: /tank/nas/library + server: 10.10.0.8 diff --git a/helper-charts/common-test/tests/persistence/volumeclaimtemplates_test.yaml b/helper-charts/common-test/tests/persistence/volumeclaimtemplates_test.yaml new file mode 100644 index 00000000..7efc48a4 --- /dev/null +++ b/helper-charts/common-test/tests/persistence/volumeclaimtemplates_test.yaml @@ -0,0 +1,30 @@ +suite: persistence volumeclaimtemplates +templates: + - common.yaml +tests: + - it: volumeClaimTemplates should pass + set: + controller: + type: statefulset + volumeClaimTemplates: + - name: "storage" + accessMode: "ReadWriteOnce" + size: "10Gi" + storageClass: "storage" + asserts: + - documentIndex: 0 + isKind: + of: StatefulSet + - documentIndex: 0 + equal: + path: spec.volumeClaimTemplates[0] + value: + metadata: + name: storage + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: storage diff --git a/helper-charts/common-test/tests/pod/additionalcontainers_test.yaml b/helper-charts/common-test/tests/pod/additionalcontainers_test.yaml new file mode 100644 index 00000000..30a1043e --- /dev/null +++ b/helper-charts/common-test/tests/pod/additionalcontainers_test.yaml @@ -0,0 +1,45 @@ +suite: pod additional containers +templates: + - common.yaml +tests: + - it: with explicit name should pass + set: + additionalContainers: + additional1: + name: template-test + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[1].name + value: template-test + + - it: with implicit name should pass + set: + additionalContainers: + additional1: + image: template-test + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[1].name + value: additional1 + + - it: with templated name should pass + set: + additionalContainers: + additional1: + name: "{{ .Release.Name }}-container" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.containers[1].name + value: RELEASE-NAME-container diff --git a/helper-charts/common-test/tests/pod/initcontainers_test.yaml b/helper-charts/common-test/tests/pod/initcontainers_test.yaml new file mode 100644 index 00000000..51c0e753 --- /dev/null +++ b/helper-charts/common-test/tests/pod/initcontainers_test.yaml @@ -0,0 +1,45 @@ +suite: pod initContainers +templates: + - common.yaml +tests: + - it: with explicit name should pass + set: + initContainers: + init1: + name: template-test + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: template-test + + - it: with implicit name should pass + set: + initContainers: + init1: + image: template-test + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: init1 + + - it: with templated name should pass + set: + initContainers: + init1: + name: "{{ .Release.Name }}-container" + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: RELEASE-NAME-container diff --git a/helper-charts/common-test/tests/pod/installcontainers_test.yaml b/helper-charts/common-test/tests/pod/installcontainers_test.yaml new file mode 100644 index 00000000..78ad42fc --- /dev/null +++ b/helper-charts/common-test/tests/pod/installcontainers_test.yaml @@ -0,0 +1,51 @@ +suite: pod install initContainers +templates: + - common.yaml +tests: + - it: with explicit name should pass + set: + installContainers: + install1: + name: template-test + test: + install: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: template-test + + - it: with implicit name should pass + set: + installContainers: + install1: + image: template-test + test: + install: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: install1 + + - it: with templated name should pass + set: + installContainers: + install1: + name: "{{ .Release.Name }}-container" + test: + install: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: RELEASE-NAME-container diff --git a/helper-charts/common-test/tests/pod/network_test.yaml b/helper-charts/common-test/tests/pod/network_test.yaml new file mode 100644 index 00000000..295052a6 --- /dev/null +++ b/helper-charts/common-test/tests/pod/network_test.yaml @@ -0,0 +1,59 @@ +suite: pod replicas +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + isNull: + path: spec.template.spec.hostNetwork + - documentIndex: 0 + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + + - it: hostNetwork disabled should pass and set dnspolicy + set: + hostNetwork: false + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + isNull: + path: spec.template.spec.hostNetwork + - documentIndex: 0 + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirst + + - it: hostNetwork enabled should pass and set dnspolicy + set: + hostNetwork: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.hostNetwork + value: true + - documentIndex: 0 + equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirstWithHostNet + + - it: custom dnsPolicy should pass + set: + dnsPolicy: None + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.dnsPolicy + value: None diff --git a/helper-charts/common-test/tests/pod/replicas_test.yaml b/helper-charts/common-test/tests/pod/replicas_test.yaml new file mode 100644 index 00000000..7e4a3793 --- /dev/null +++ b/helper-charts/common-test/tests/pod/replicas_test.yaml @@ -0,0 +1,25 @@ +suite: pod replicas +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.replicas + value: 1 + + - it: custom replicas should pass + set: + controller.replicas: 3 + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.replicas + value: 3 diff --git a/helper-charts/common-test/tests/pod/upgradecontainers_test.yaml b/helper-charts/common-test/tests/pod/upgradecontainers_test.yaml new file mode 100644 index 00000000..ff42004a --- /dev/null +++ b/helper-charts/common-test/tests/pod/upgradecontainers_test.yaml @@ -0,0 +1,51 @@ +suite: pod upgrade initContainers +templates: + - common.yaml +tests: + - it: with explicit name should pass + set: + upgradeContainers: + upgrade1: + name: template-test + test: + upgrade: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: template-test + + - it: with implicit name should pass + set: + upgradeContainers: + upgrade1: + image: template-test + test: + upgrade: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: upgrade1 + + - it: with templated name should pass + set: + upgradeContainers: + aupgrade1: + name: "{{ .Release.Name }}-container" + test: + upgrade: true + asserts: + - documentIndex: 0 + isKind: + of: Deployment + - documentIndex: 0 + equal: + path: spec.template.spec.initContainers[1].name + value: RELEASE-NAME-container diff --git a/helper-charts/common-test/tests/portal/defaults_test.yaml b/helper-charts/common-test/tests/portal/defaults_test.yaml new file mode 100644 index 00000000..948e0c60 --- /dev/null +++ b/helper-charts/common-test/tests/portal/defaults_test.yaml @@ -0,0 +1,84 @@ +suite: portal defaults +templates: + - common.yaml +tests: + - it: uses "$node_ip" by default + set: + portal: + enabled: true + ingress: + main: + enabled: false + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.host + value: $node_ip + + - it: uses port "443" by default + set: + portal: + enabled: true + ixChartContext: + placeholder: true + ingress: + main: + enabled: false + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.port + value: "443" + + - it: uses protocol "http" by default + set: + portal: + enabled: true + ingress: + main: + enabled: false + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.protocol + value: http + + + - it: uses path "/" by default + set: + portal: + enabled: true + ixChartContext: + placeholder: true + ingress: + main: + enabled: true + asserts: + - hasDocuments: + count: 4 + - documentIndex: 3 + isKind: + of: ConfigMap + - documentIndex: 3 + equal: + path: data.path + value: / diff --git a/helper-charts/common-test/tests/portal/metadata_test.yaml b/helper-charts/common-test/tests/portal/metadata_test.yaml new file mode 100644 index 00000000..d4839103 --- /dev/null +++ b/helper-charts/common-test/tests/portal/metadata_test.yaml @@ -0,0 +1,96 @@ +suite: portal configmap metadata +templates: + - common.yaml +tests: + - it: with enabled portal should pass + set: + portal: + enabled: true + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: &ConfigmapDocument 2 + isKind: + of: ConfigMap + - documentIndex: *ConfigmapDocument + isNull: + path: metadata.annotations + - documentIndex: *ConfigmapDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + - documentIndex: *ConfigmapDocument + equal: + path: metadata.name + value: portal + + +## TODO: allow label and annotation changes for the portal +# - it: custom metadata should pass +# set: +# configmap: +# config: +# enabled: true +# annotations: +# test_annotation: test +# labels: +# test_label: test +# asserts: +# - documentIndex: &ConfigmapDocument 0 +# isKind: +# of: ConfigMap +# - documentIndex: *ConfigmapDocument +# equal: +# path: metadata.annotations +# value: +# test_annotation: test +# - documentIndex: *ConfigmapDocument +# equal: +# path: metadata.labels +# value: +# app.kubernetes.io/instance: RELEASE-NAME +# app.kubernetes.io/managed-by: Helm +# app.kubernetes.io/name: common-test +# helm.sh/chart: common-test-4.0.0 +# test_label: test +# +# - it: custom metadata with global metadata should pass +# set: +# global: +# labels: +# global_label: test +# annotations: +# global_annotation: test +# configmap: +# config: +# enabled: true +# annotations: +# test_annotation: test +# labels: +# test_label: test +# asserts: +# - documentIndex: &ConfigmapDocument 0 +# isKind: +# of: ConfigMap +# - documentIndex: *ConfigmapDocument +# equal: +# path: metadata.annotations +# value: +# global_annotation: test +# test_annotation: test +# - documentIndex: *ConfigmapDocument +# equal: +# path: metadata.labels +# value: +# app.kubernetes.io/instance: RELEASE-NAME +# app.kubernetes.io/managed-by: Helm +# app.kubernetes.io/name: common-test +# global_label: test +# helm.sh/chart: common-test-4.0.0 +# test_label: test diff --git a/helper-charts/common-test/tests/portal/nodeport_test.yaml b/helper-charts/common-test/tests/portal/nodeport_test.yaml new file mode 100644 index 00000000..708bc215 --- /dev/null +++ b/helper-charts/common-test/tests/portal/nodeport_test.yaml @@ -0,0 +1,27 @@ +suite: portal overrides +templates: + - common.yaml +tests: + - it: nodePort host defaults to node_ip + set: + portal: + enabled: true + ixChartContext: + placeholder: true + ingress: + main: + enabled: false + service: + main: + port: + nodePort: 666 + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.host + value: $node_ip diff --git a/helper-charts/common-test/tests/portal/overrides_test.yaml b/helper-charts/common-test/tests/portal/overrides_test.yaml new file mode 100644 index 00000000..90ee842b --- /dev/null +++ b/helper-charts/common-test/tests/portal/overrides_test.yaml @@ -0,0 +1,66 @@ +suite: portal overrides +templates: + - common.yaml +tests: + - it: ingressPort can be overridden + set: + portal: + enabled: true + ingressPort: 666 + ingress: + main: + enabled: true + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 4 + - documentIndex: 3 + isKind: + of: ConfigMap + - documentIndex: 3 + equal: + path: data.port + value: "666" + + - it: nodePort Host can be overridden + set: + portal: + enabled: true + host: "test.host" + ingress: + main: + enabled: false + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.host + value: test.host + + - it: path can be overridden + set: + portal: + enabled: true + path: "/path" + ingress: + main: + enabled: false + ixChartContext: + placeholder: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 2 + isKind: + of: ConfigMap + - documentIndex: 2 + equal: + path: data.path + value: /path diff --git a/helper-charts/common-test/tests/pvc/metadata_test.yaml b/helper-charts/common-test/tests/pvc/metadata_test.yaml new file mode 100644 index 00000000..51e24b0b --- /dev/null +++ b/helper-charts/common-test/tests/pvc/metadata_test.yaml @@ -0,0 +1,106 @@ +suite: pvc metadata +templates: + - common.yaml +tests: + - it: default should pass + set: + persistence.config.enabled: true + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + isNull: + path: metadata.annotations + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: retain enabled should pass + set: + persistence.config: + enabled: true + retain: true + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.annotations + value: + helm.sh/resource-policy: keep + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + persistence.config: + enabled: true + labels: + test_label: test + annotations: + test_annotation: test + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + persistence.config: + enabled: true + labels: + test_label: test + annotations: + test_annotation: test + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.annotations + value: + test_annotation: test + global_annotation: test + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/pvc/names_test.yaml b/helper-charts/common-test/tests/pvc/names_test.yaml new file mode 100644 index 00000000..deed6713 --- /dev/null +++ b/helper-charts/common-test/tests/pvc/names_test.yaml @@ -0,0 +1,66 @@ +suite: pvc names +templates: + - common.yaml +tests: + - it: disabled should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + not: true + isKind: + of: PersistentVolumeClaim + - documentIndex: 1 + not: true + isKind: + of: PersistentVolumeClaim + + - it: default should pass + set: + persistence.config.enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: 1 + not: true + isKind: + of: PersistentVolumeClaim + - documentIndex: 2 + not: true + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-config + + - it: without suffix should pass + set: + persistence.config: + enabled: true + nameOverride: "-" + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: with custom suffix should pass + set: + persistence.config: + enabled: true + nameOverride: "custom" + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-custom diff --git a/helper-charts/common-test/tests/pvc/storageclass_test.yaml b/helper-charts/common-test/tests/pvc/storageclass_test.yaml new file mode 100644 index 00000000..4b24a1ec --- /dev/null +++ b/helper-charts/common-test/tests/pvc/storageclass_test.yaml @@ -0,0 +1,42 @@ +suite: pvc storageclass +templates: + - common.yaml +tests: + - it: default should pass + set: + persistence.config.enabled: true + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + isNull: + path: spec.storageClassName + + - it: custom should pass + set: + persistence.config: + enabled: true + storageClass: custom + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: spec.storageClassName + value: custom + + - it: empty should pass + set: + persistence.config: + enabled: true + storageClass: "-" + asserts: + - documentIndex: &PersistentVolumeClaimDocument 0 + isKind: + of: PersistentVolumeClaim + - documentIndex: *PersistentVolumeClaimDocument + equal: + path: spec.storageClassName + value: "" diff --git a/helper-charts/common-test/tests/service/metadata_test.yaml b/helper-charts/common-test/tests/service/metadata_test.yaml new file mode 100644 index 00000000..efe37931 --- /dev/null +++ b/helper-charts/common-test/tests/service/metadata_test.yaml @@ -0,0 +1,81 @@ +suite: service metadata +templates: + - common.yaml +tests: + - it: default metadata should pass + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + isNull: + path: metadata.annotations + - documentIndex: *ServiceDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + + - it: custom metadata should pass + set: + service: + main: + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: metadata.annotations + value: + test_annotation: test + - documentIndex: *ServiceDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + helm.sh/chart: common-test-4.0.0 + test_label: test + + - it: custom metadata with global metadata should pass + set: + global: + labels: + global_label: test + annotations: + global_annotation: test + service: + main: + annotations: + test_annotation: test + labels: + test_label: test + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: metadata.annotations + value: + global_annotation: test + test_annotation: test + - documentIndex: *ServiceDocument + equal: + path: metadata.labels + value: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: common-test + global_label: test + helm.sh/chart: common-test-4.0.0 + test_label: test diff --git a/helper-charts/common-test/tests/service/names_test.yaml b/helper-charts/common-test/tests/service/names_test.yaml new file mode 100644 index 00000000..3598dc6e --- /dev/null +++ b/helper-charts/common-test/tests/service/names_test.yaml @@ -0,0 +1,29 @@ +suite: service names +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test + + - it: custom name suffix should pass + set: + service: + main: + nameOverride: http + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: metadata.name + value: RELEASE-NAME-common-test-http diff --git a/helper-charts/common-test/tests/service/port_names_test.yaml b/helper-charts/common-test/tests/service/port_names_test.yaml new file mode 100644 index 00000000..ca9563b3 --- /dev/null +++ b/helper-charts/common-test/tests/service/port_names_test.yaml @@ -0,0 +1,63 @@ +suite: service port names +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0] + value: + name: main + port: 8080 + protocol: TCP + targetPort: main + + - it: custom name should pass + set: + service: + main: + ports: + main: + enabled: false + server: + enabled: true + port: 8080 + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0] + value: + name: server + port: 8080 + protocol: TCP + targetPort: server + + - it: custom target port should pass + set: + service: + main: + ports: + main: + enabled: true + targetPort: 80 + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0] + value: + name: main + port: 8080 + protocol: TCP + targetPort: 80 diff --git a/helper-charts/common-test/tests/service/port_protocols_test.yaml b/helper-charts/common-test/tests/service/port_protocols_test.yaml new file mode 100644 index 00000000..462879f8 --- /dev/null +++ b/helper-charts/common-test/tests/service/port_protocols_test.yaml @@ -0,0 +1,71 @@ +suite: service protocols +templates: + - common.yaml +tests: + - it: default should pass + asserts: + - hasDocuments: + count: 2 + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0].protocol + value: TCP + + - it: explicit TCP should pass + set: + service.main.ports.main.protocol: TCP + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0].protocol + value: TCP + + - it: explicit UDP should pass + set: + service.main.ports.main.protocol: UDP + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0].protocol + value: UDP + + - it: explicit HTTP should pass + set: + service.main.ports.main.protocol: HTTP + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0].protocol + value: TCP + - documentIndex: *ServiceDocument + isNull: + path: metadata.annotations + + - it: explicit HTTPS should pass + set: + service.main.ports.main.protocol: HTTPS + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.ports[0].protocol + value: TCP + - documentIndex: *ServiceDocument + equal: + path: metadata.annotations + value: + traefik.ingress.kubernetes.io/service.serversscheme: https diff --git a/helper-charts/common-test/tests/service/values_test.yaml b/helper-charts/common-test/tests/service/values_test.yaml new file mode 100644 index 00000000..b7edd82f --- /dev/null +++ b/helper-charts/common-test/tests/service/values_test.yaml @@ -0,0 +1,33 @@ +suite: service values +templates: + - common.yaml +tests: + - it: externalTrafficPolicy should pass for NodePort service + set: + service: + main: + type: NodePort + externalTrafficPolicy: Local + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.externalTrafficPolicy + value: Local + + - it: externalTrafficPolicy should pass for LoadBalancer service + set: + service: + main: + type: LoadBalancer + externalTrafficPolicy: Local + asserts: + - documentIndex: &ServiceDocument 1 + isKind: + of: Service + - documentIndex: *ServiceDocument + equal: + path: spec.externalTrafficPolicy + value: Local diff --git a/tests/library/common/addon_codeserver_spec.rb b/tests/library/common/addon_codeserver_spec.rb deleted file mode 100644 index a1c32d4e..00000000 --- a/tests/library/common/addon_codeserver_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'addon::codeserver' do - baseValues = { - addons: { - codeserver: { - enabled: true - } - } - } - - it 'defaults to disabled' do - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - codeserverContainer = containers.find{ |c| c["name"] == "codeserver" } - - assert_nil(codeserverContainer) - end - - it 'can be enabled' do - values = baseValues - - chart.value values - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - codeserverContainer = containers.find{ |c| c["name"] == "codeserver" } - - refute_nil(codeserverContainer) - end - - it 'a git deployKey can be passed' do - values = baseValues.deep_merge_override({ - addons: { - codeserver: { - git: { - deployKey: "testKey" - } - } - } - }) - - chart.value values - deployment = chart.resources(kind: "Deployment").first - secret = chart.resources(kind: "Secret").first - containers = deployment["spec"]["template"]["spec"]["containers"] - volumes = deployment["spec"]["template"]["spec"]["volumes"] - codeserverContainer = containers.find{ |c| c["name"] == "codeserver" } - expectedSecretContent = { "id_rsa" => values[:addons][:codeserver][:git][:deployKey] } - - # Check that the secret has been created - refute_nil(secret) - assert_equal("common-test-deploykey", secret["metadata"]["name"]) - assert_equal(expectedSecretContent, secret["stringData"]) - - # Make sure the deployKey volumeMount is present in the sidecar container - deploykeyVolumeMount = codeserverContainer["volumeMounts"].find { |v| v["name"] == "deploykey"} - refute_nil(deploykeyVolumeMount) - assert_equal("/root/.ssh/id_rsa", deploykeyVolumeMount["mountPath"]) - assert_equal("id_rsa", deploykeyVolumeMount["subPath"]) - - # Make sure the deployKey volume is present in the Deployment - deploykeyVolume = volumes.find{ |v| v["name"] == "deploykey" } - refute_nil(deploykeyVolume) - assert_equal("common-test-deploykey", deploykeyVolume["secret"]["secretName"]) - end - - it 'a git deployKey can be passed in base64 format' do - values = baseValues.deep_merge_override({ - addons: { - codeserver: { - git: { - deployKeyBase64: "dGVzdEtleQ==" - } - } - } - }) - - chart.value values - deployment = chart.resources(kind: "Deployment").first - secret = chart.resources(kind: "Secret").first - containers = deployment["spec"]["template"]["spec"]["containers"] - volumes = deployment["spec"]["template"]["spec"]["volumes"] - codeserverContainer = containers.find{ |c| c["name"] == "codeserver" } - expectedSecretContent = { "id_rsa" => values[:addons][:codeserver][:git][:deployKeyBase64] } - - # Check that the secret has been created - refute_nil(secret) - assert_equal("common-test-deploykey", secret["metadata"]["name"]) - assert_equal(expectedSecretContent, secret["data"]) - - # Make sure the deployKey volumeMount is present in the sidecar container - deploykeyVolumeMount = codeserverContainer["volumeMounts"].find { |v| v["name"] == "deploykey"} - refute_nil(deploykeyVolumeMount) - assert_equal("/root/.ssh/id_rsa", deploykeyVolumeMount["mountPath"]) - assert_equal("id_rsa", deploykeyVolumeMount["subPath"]) - - # Make sure the deployKey volume is present in the Deployment - deploykeyVolume = volumes.find{ |v| v["name"] == "deploykey" } - refute_nil(deploykeyVolume) - assert_equal("common-test-deploykey", deploykeyVolume["secret"]["secretName"]) - end - end - end -end diff --git a/tests/library/common/addon_netshoot_spec.rb b/tests/library/common/addon_netshoot_spec.rb deleted file mode 100644 index 96387ab3..00000000 --- a/tests/library/common/addon_netshoot_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'addon::netshoot' do - it 'defaults to disabled' do - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - netshootContainer = containers.find{ |c| c["name"] == "netshoot" } - - assert_nil(netshootContainer) - end - - it 'netshoot can be enabled' do - values = { - addons: { - netshoot: { - enabled: true - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - netshootContainer = containers.find{ |c| c["name"] == "netshoot" } - - refute_nil(netshootContainer) - end - end - end -end diff --git a/tests/library/common/addon_promtail_spec.rb b/tests/library/common/addon_promtail_spec.rb deleted file mode 100644 index 5a62d546..00000000 --- a/tests/library/common/addon_promtail_spec.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'addon::promtail' do - it 'defaults to disabled' do - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - promtailContainer = containers.find{ |c| c["name"] == "promtail" } - - assert_nil(promtailContainer) - end - - it 'promtail can be enabled' do - values = { - addons: { - promtail: { - enabled: true - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - promtailContainer = containers.find{ |c| c["name"] == "promtail" } - - refute_nil(promtailContainer) - end - end - end -end diff --git a/tests/library/common/addon_vpn_spec.rb b/tests/library/common/addon_vpn_spec.rb deleted file mode 100644 index 09821c06..00000000 --- a/tests/library/common/addon_vpn_spec.rb +++ /dev/null @@ -1,106 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'addon::vpn' do - it 'defaults to disabled' do - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - openvpnContainer = containers.find{ |c| c["name"] == "openvpn" } - wireguardContainer = containers.find{ |c| c["name"] == "wireguard" } - - assert_nil(openvpnContainer) - assert_nil(wireguardContainer) - end - - it 'openvpn can be enabled' do - values = { - addons: { - vpn: { - type: "openvpn" - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - vpnContainer = containers.find{ |c| c["name"] == "openvpn" } - - refute_nil(vpnContainer) - end - - it 'wireguard can be enabled' do - values = { - addons: { - vpn: { - type: "wireguard" - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - containers = deployment["spec"]["template"]["spec"]["containers"] - wireguardContainer = containers.find{ |c| c["name"] == "wireguard" } - - refute_nil(wireguardContainer) - end - - it 'a openvpn configuration file can be passed' do - values = { - addons: { - vpn: { - type: "openvpn", - configFile: { - enabled: true, - hostPath: "/test.conf" - } - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - secret = chart.resources(kind: "Secret").first - containers = deployment["spec"]["template"]["spec"]["containers"] - volumes = deployment["spec"]["template"]["spec"]["volumes"] - vpnContainer = containers.find{ |c| c["name"] == "openvpn" } - - # Make sure the deployKey volumeMount is present in the sidecar container - vpnconfigVolumeMount = vpnContainer["volumeMounts"].find { |v| v["name"] == "vpnconfig"} - refute_nil(vpnconfigVolumeMount) - assert_equal("/vpn/vpn.conf", vpnconfigVolumeMount["mountPath"]) - end - - it 'a wireguard configuration file can be passed' do - values = { - addons: { - vpn: { - type: "wireguard", - configFile: { - enabled: true, - hostPath: "/test.conf" - } - } - } - } - - chart.value values - deployment = chart.resources(kind: "Deployment").first - secret = chart.resources(kind: "Secret").first - containers = deployment["spec"]["template"]["spec"]["containers"] - volumes = deployment["spec"]["template"]["spec"]["volumes"] - vpnContainer = containers.find{ |c| c["name"] == "wireguard" } - - # Make sure the deployKey volumeMount is present in the sidecar container - vpnconfigVolumeMount = vpnContainer["volumeMounts"].find { |v| v["name"] == "vpnconfig"} - refute_nil(vpnconfigVolumeMount) - assert_equal("/etc/wireguard/wg0.conf", vpnconfigVolumeMount["mountPath"]) - end - end - end -end diff --git a/tests/library/common/autoPermissions_spec.rb b/tests/library/common/autoPermissions_spec.rb deleted file mode 100644 index 8b27a276..00000000 --- a/tests/library/common/autoPermissions_spec.rb +++ /dev/null @@ -1,288 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'initContainer::permissions' do - it 'initContainer exists by default' do - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - refute_nil(initContainer) - end - - it 'persistenceList do not affect permissions job by default' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - mountPath: "/data", - hostPath: "/tmp" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - assert_nil(deployment["spec"]["template"]["spec"]["initContainers"][0]["volumeMounts"]) - end - it 'persistenceList.setPermissions adds volume(mounts)' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - assert_equal("data", deployment["spec"]["template"]["spec"]["volumes"][0]["name"]) - assert_equal("data", deployment["spec"]["template"]["spec"]["initContainers"][0]["volumeMounts"][0]["name"]) - end - it 'supports multiple persistenceList' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp" - }, - { - name: "configlist", - enabled: true, - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - - # Check that all persistenceList volumes have mounts - values[:persistenceList].each { |value| - volumeMount = initContainer["volumeMounts"].find{ |v| v["name"] == "" + value[:name].to_s } - refute_nil(volumeMount) - } - end - - it 'supports setting mountPath' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - - volumeMount = initContainer["volumeMounts"].find{ |v| v["name"] == "data" } - refute_nil(volumeMount) - assert_equal("/data", volumeMount["mountPath"]) - end - - it 'could mount multiple volumes' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - type: "hostPath", - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - type: "hostPath", - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - volumes = deployment["spec"]["template"]["spec"]["volumes"] - - volume = volumes.find{ |v| v["name"] == "data"} - refute_nil(volume) - assert_equal('/tmp1', volume["hostPath"]["path"]) - - volume = volumes.find{ |v| v["name"] == "configlist"} - refute_nil(volume) - assert_equal('/tmp2', volume["hostPath"]["path"]) - end - - it 'can process default (568:568) permissions for multiple volumes' do - results= { - command: ["/bin/sh", "-c", "echo 'Automatically correcting permissions...';chown -R :568 '/configlist'; chmod -R g+w || echo 'chmod failed for /configlist, are you running NFSv4 ACLs?' '/configlist';chown -R :568 '/data'; chmod -R g+w || echo 'chmod failed for /data, are you running NFSv4 ACLs?' '/data';"] - } - values = { - persistenceList: [ - { - name: "data", - enabled: true, - type: "hostPath", - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - type: "hostPath", - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - assert_equal(results[:command], initContainer["command"]) - end - - it 'outputs default permissions with irrelevant podSecurityContext' do - results= { - command: ["/bin/sh", "-c", "echo 'Automatically correcting permissions...';chown -R :568 '/configlist'; chmod -R g+w || echo 'chmod failed for /configlist, are you running NFSv4 ACLs?' '/configlist';chown -R :568 '/data'; chmod -R g+w || echo 'chmod failed for /data, are you running NFSv4 ACLs?' '/data';"] - } - values = { - podSecurityContext: { - allowPrivilegeEscalation: false - }, - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - assert_equal(results[:command], initContainer["command"]) - end - - it 'outputs fsgroup permissions for multiple volumes when set' do - results= { - command: ["/bin/sh", "-c", "echo 'Automatically correcting permissions...';chown -R :666 '/configlist'; chmod -R g+w || echo 'chmod failed for /configlist, are you running NFSv4 ACLs?' '/configlist';chown -R :666 '/data'; chmod -R g+w || echo 'chmod failed for /data, are you running NFSv4 ACLs?' '/data';"] - } - values = { - podSecurityContext: { - fsGroup: 666 - }, - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - assert_equal(results[:command], initContainer["command"]) - end - - it 'outputs runAsUser permissions for multiple volumes when set' do - results= { - command: ["/bin/sh", "-c", "echo 'Automatically correcting permissions...';chown -R :568 '/configlist'; chmod -R g+w || echo 'chmod failed for /configlist, are you running NFSv4 ACLs?' '/configlist';chown -R :568 '/data'; chmod -R g+w || echo 'chmod failed for /data, are you running NFSv4 ACLs?' '/data';"] - } - values = { - podSecurityContext: { - runAsUser: 999 - }, - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - assert_equal(results[:command], initContainer["command"]) - end - - it 'outputs fsGroup AND runAsUser permissions for multiple volumes when both are set' do - results= { - command: ["/bin/sh", "-c", "echo 'Automatically correcting permissions...';chown -R :666 '/configlist'; chmod -R g+w || echo 'chmod failed for /configlist, are you running NFSv4 ACLs?' '/configlist';chown -R :666 '/data'; chmod -R g+w || echo 'chmod failed for /data, are you running NFSv4 ACLs?' '/data';"] - } - values = { - podSecurityContext: { - fsGroup: 666, - runAsUser: 999 - }, - persistenceList: [ - { - name: "data", - enabled: true, - setPermissions: true, - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - enabled: true, - setPermissions: true, - mountPath: "/configlist", - hostPath: "/tmp2" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - initContainer = deployment["spec"]["template"]["spec"]["initContainers"][0] - assert_equal(results[:command], initContainer["command"]) - end - end - end -end diff --git a/tests/library/common/cert_spec.rb b/tests/library/common/cert_spec.rb deleted file mode 100644 index e84343c4..00000000 --- a/tests/library/common/cert_spec.rb +++ /dev/null @@ -1,322 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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-tls-0-ixcert-1-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-tls-0-ixcert-1-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" } - refute_nil(ingress) - assert_equal("common-test-tls-0-ixcert-1-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-tls-0-ixcert-1-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-tls-1-ixcert-2-1" } - 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" } - refute_nil(ingress) - assert_equal("common-test-tls-0-ixcert-1-1", ingress["spec"]["tls"][0]["secretName"]) - assert_equal("common-test-tls-1-ixcert-2-1", ingress["spec"]["tls"][1]["secretName"]) - end - end - end -end diff --git a/tests/library/common/container_resources_spec.rb b/tests/library/common/container_resources_spec.rb deleted file mode 100644 index 4f66eeb4..00000000 --- a/tests/library/common/container_resources_spec.rb +++ /dev/null @@ -1,90 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'container::resources' do - it 'specific 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"=>{"cpu"=>"4000m", "memory"=>"8Gi"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}}, 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"=>{"cpu"=>"4000m", "memory"=>"8Gi"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}, "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"=>{"cpu"=>"4000m", "memory"=>"8Gi", "testlimitkey"=>"testlimitvalue"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}}, 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"=>{"cpu"=>"4000m", "memory"=>"8Gi", "testlimitkey"=>"testlimitvalue"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}, "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"=>{"cpu"=>"4000m", "intelblabla"=>1, "memory"=>"8Gi"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}}, 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"=>{"cpu"=>"4000m", "intelblabla"=>1, "memory"=>"8Gi", "testlimitkey"=>"testlimitvalue"}, "requests"=>{"cpu"=>"10m", "memory"=>"50Mi"}, "testresourcekey"=>"testresourcevalue"}, mainContainer["resources"]) - end - end - end -end diff --git a/tests/library/common/container_spec.rb b/tests/library/common/container_spec.rb deleted file mode 100644 index e8a281be..00000000 --- a/tests/library/common/container_spec.rb +++ /dev/null @@ -1,276 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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 = { - securityContext: { - runAsNonRoot: false, - readOnlyRootFilesystem: false - } - } - 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"][11]) - end - - it 'set static "k/v pair style" environment variables' do - values = { - env: { - BOOL_ENV: false, - FLOAT_ENV: 4.2, - INT_ENV: 42, - STRING_ENV: 'value_of_env' - } - } - 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"][11]["name"]) - assert_equal(values[:env].values[0].to_s, mainContainer["env"][11]["value"]) - assert_equal(values[:env].keys[1].to_s, mainContainer["env"][12]["name"]) - assert_equal(values[:env].values[1].to_s, mainContainer["env"][12]["value"]) - assert_equal(values[:env].keys[2].to_s, mainContainer["env"][13]["name"]) - assert_equal(values[:env].values[2].to_s, mainContainer["env"][13]["value"]) - assert_equal(values[:env].keys[3].to_s, mainContainer["env"][14]["name"]) - assert_equal(values[:env].values[3].to_s, mainContainer["env"][14]["value"]) - end - - it 'set list of static "kubernetes style" 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"][11]["name"]) - assert_equal(values[:envList][0][:value].to_s, mainContainer["env"][11]["value"]) - end - - it 'set both static "k/v pair style" and static "k/valueFrom style" environment variables' do - values = { - env: { - STATIC_ENV: 'value_of_env', - STATIC_ENV_FROM: { - valueFrom: { - 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[:env].keys[0].to_s, mainContainer["env"][11]["name"]) - assert_equal(values[:env].values[0].to_s, mainContainer["env"][11]["value"]) - assert_equal(values[:env].keys[1].to_s, mainContainer["env"][12]["name"]) - assert_equal(values[:env].values[1][:valueFrom][:fieldRef][:fieldPath], mainContainer["env"][12]["valueFrom"]["fieldRef"]["fieldPath"]) - end - - it 'set static "k/explicitValueFrom pair style" environment variables' do - values = { - env: { - NODE_NAME: { - valueFrom: { - 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[:env].keys[0].to_s, mainContainer["env"][11]["name"]) - assert_equal(values[:env].values[0][:valueFrom][:fieldRef][:fieldPath], mainContainer["env"][11]["valueFrom"]["fieldRef"]["fieldPath"]) - end - - it 'set static "k/implicitValueFrom pair style" environment variables' do - values = { - env: { - 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[:env].keys[0].to_s, mainContainer["env"][11]["name"]) - assert_equal(values[:env].values[0][:fieldRef][:fieldPath], mainContainer["env"][11]["valueFrom"]["fieldRef"]["fieldPath"]) - end - - it 'set both static "k/v pair style" and templated "k/v pair style" environment variables' do - values = { - env: { - DYN_ENV: "{{ .Release.Name }}-admin", - STATIC_ENV: 'value_of_env' - } - } - 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"][11]["name"]) - assert_equal("common-test-admin", mainContainer["env"][11]["value"]) - assert_equal(values[:env].keys[1].to_s, mainContainer["env"][12]["name"]) - assert_equal(values[:env].values[1].to_s, mainContainer["env"][12]["value"]) - end - - it 'set templated "k/v pair style" environment variables' do - values = { - env: { - 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"][11]["name"]) - assert_equal("common-test-admin", mainContainer["env"][11]["value"]) - end - - it 'set static "k/v pair style", templated "k/v pair style", static "k/explicitValueFrom pair style", and static "k/implicitValueFrom pair style" environment variables' do - values = { - env: { - DYN_ENV: "{{ .Release.Name }}-admin", - STATIC_ENV: 'value_of_env', - STATIC_EXPLICIT_ENV_FROM: { - valueFrom: { - fieldRef: { - fieldPath: "spec.nodeName" - } - } - }, - STATIC_IMPLICIT_ENV_FROM: { - 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[:env].keys[0].to_s, mainContainer["env"][11]["name"]) - assert_equal("common-test-admin", mainContainer["env"][11]["value"]) - assert_equal(values[:env].keys[1].to_s, mainContainer["env"][12]["name"]) - assert_equal(values[:env].values[1].to_s, mainContainer["env"][12]["value"]) - assert_equal(values[:env].keys[2].to_s, mainContainer["env"][13]["name"]) - assert_equal(values[:env].values[2][:valueFrom][:fieldRef][:fieldPath], mainContainer["env"][13]["valueFrom"]["fieldRef"]["fieldPath"]) - assert_equal(values[:env].keys[3].to_s, mainContainer["env"][14]["name"]) - assert_equal(values[:env].values[3][:fieldRef][:fieldPath], mainContainer["env"][14]["valueFrom"]["fieldRef"]["fieldPath"]) - 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 - - end -end diff --git a/tests/library/common/controller_spec.rb b/tests/library/common/controller_spec.rb deleted file mode 100644 index 76c1046c..00000000 --- a/tests/library/common/controller_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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 controller: {type: 'statefulset'} - assert_nil(resource('Deployment')) - assert_nil(resource('DaemonSet')) - refute_nil(resource('StatefulSet')) - end - - it 'accepts "daemonset"' do - chart.value controller: {type: '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 controller: {type: 'statefulset'} - statefulset = chart.resources(kind: "StatefulSet").first - assert_nil(statefulset['spec']['volumeClaimTemplates']) - end - - it 'can set values for volumeClaimTemplates' do - values = { - controller: { - type: 'statefulset', - }, - volumeClaimTemplates: { - storage: { - accessMode: 'ReadWriteOnce', - size: '10Gi', - storageClass: 'storage' - } - } - } - - chart.value values - statefulset = chart.resources(kind: "StatefulSet").first - volumeClaimTemplate = statefulset["spec"]["volumeClaimTemplates"].find{ |c| c["metadata"]["name"] == "storage"} - refute_nil(volumeClaimTemplate) - assert_equal(values[:volumeClaimTemplates][:storage][:accessMode], volumeClaimTemplate["spec"]["accessModes"][0]) - assert_equal(values[:volumeClaimTemplates][:storage][:size], volumeClaimTemplate["spec"]["resources"]["requests"]["storage"]) - assert_equal(values[:volumeClaimTemplates][:storage][:storageClass], volumeClaimTemplate["spec"]["storageClassName"]) - end - end - end -end diff --git a/tests/library/common/hpa_spec.rb b/tests/library/common/hpa_spec.rb deleted file mode 100644 index 5b16ec53..00000000 --- a/tests/library/common/hpa_spec.rb +++ /dev/null @@ -1,120 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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 diff --git a/tests/library/common/ingress_spec.rb b/tests/library/common/ingress_spec.rb deleted file mode 100644 index 3ab89bc8..00000000 --- a/tests/library/common/ingress_spec.rb +++ /dev/null @@ -1,240 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'ingress' do - baseValues = { - ingress: { - main: { - enabled: true - } - }, - service: { - main: { - ports: { - http: { - port: 8080 - } - } - } - } - } - - it 'disabled when ingress.main.enabled: false' do - values = baseValues.deep_merge_override({ - ingress: { - main: { - enabled: false - } - } - }) - chart.value values - - assert_nil(resource('Ingress')) - end - - it 'enabled when ingress.main.enabled: true' do - values = baseValues - chart.value values - - refute_nil(resource('Ingress')) - end - - it 'tls can be provided' do - expectedPath = 'common-test.path' - values = baseValues.deep_merge_override({ - ingress: { - main: { - tls: [ - { - hosts: [ 'hostname' ], - secretName: 'secret-name' - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 = baseValues.deep_merge_override({ - ingress: { - main:{ - tls: [ - { - hosts: [ 'hostname' ] - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 = baseValues.deep_merge_override({ - ingress: { - main: { - tls: [ - { - secretName: '{{ .Release.Name }}-secret' - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 = baseValues.deep_merge_override({ - ingress: { - main: { - hosts: [ - { - host: 'test.local', - paths: [ - { - path: '{{ .Release.Name }}.path' - } - ] - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - refute_nil(ingress) - assert_equal(expectedPath, ingress["spec"]["rules"][0]["http"]["paths"][0]["path"]) - end - - it 'hosts can be provided' do - values = baseValues.deep_merge_override({ - ingress: { - main: { - hosts: [ - { - host: 'hostname', - paths: [ - { - path: "/" - } - ] - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 = baseValues.deep_merge_override({ - ingress: { - main: { - hosts: [ - { - host: '{{ .Release.Name }}.hostname', - paths: [ - { - path: "/" - } - ] - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 = baseValues.deep_merge_override({ - ingress: { - main: { - hosts: [ - { - host: 'test.local', - paths: [ - { - path: '/' - }, - { - path: '/second', - service: { - name: 'pathService', - port: 1234 - } - } - ] - } - ] - } - } - }) - chart.value values - - ingress = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - 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 - - it 'multiple ingress objects can be specified' do - values = baseValues.deep_merge_override({ - ingress: { - main: { - enabled: true, - primary: true - }, - secondary: { - enabled: true - } - } - }) - chart.value values - - ingressMain = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test" } - ingressExtra = chart.resources(kind: "Ingress").find{ |s| s["metadata"]["name"] == "common-test-secondary" } - refute_nil(ingressMain) - refute_nil(ingressExtra) - end - end - end -end diff --git a/tests/library/common/persistence_spec.rb b/tests/library/common/persistence_spec.rb deleted file mode 100644 index cef7ac6b..00000000 --- a/tests/library/common/persistence_spec.rb +++ /dev/null @@ -1,368 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - - describe 'pod::persistence' do - it 'multiple volumes' do - values = { - persistence: { - cache: { - enabled: true, - type: "emptyDir" - }, - config: { - enabled: true, - existingClaim: "configClaim" - }, - 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 - } - } - } - 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, - nameOverride: "test" - } - } - } - 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, - nameOverride: "-" - } - } - } - 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, - type: "emptyDir" - } - } - } - 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, - type: "emptyDir", - 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, - type: "emptyDir", - 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::persistenceList' do - it 'multiple volumes' do - values = { - persistenceList: [ - { - name: "data", - enabled: true, - type: "hostPath", - mountPath: "/data", - hostPath: "/tmp1" - }, - { - name: "configlist", - type: "hostPath", - 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"] == "data"} - refute_nil(volume) - assert_equal('/tmp1', volume["hostPath"]["path"]) - - volume = volumes.find{ |v| v["name"] == "configlist"} - refute_nil(volume) - assert_equal('/tmp2', volume["hostPath"]["path"]) - end - - it 'emptyDir can be enabled' do - values = { - persistenceList: [ - { - name: "data", - type: "emptyDir", - enabled: true, - mountPath: "/data" - } - ] - } - chart.value values - deployment = chart.resources(kind: "Deployment").first - volumes = deployment["spec"]["template"]["spec"]["volumes"] - volume = volumes.find{ |v| v["name"] == "data"} - refute_nil(volume) - assert_equal(Hash.new, volume["emptyDir"]) - end - end - - - describe 'container::persistence' do - it 'supports multiple volumeMounts' do - values = { - persistence: { - cache: { - enabled: true, - type: "emptyDir" - }, - 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::persistenceList' do - it 'supports multiple persistenceList' do - values = { - persistenceList: [ - { - 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 persistenceList volumes have mounts - values[:persistenceList].each { |value| - volumeMount = mainContainer["volumeMounts"].find{ |v| v["name"] == value[:name].to_s } - refute_nil(volumeMount) - } - end - - it 'supports setting mountPath' do - values = { - persistenceList: [ - { - 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"] == "data" } - refute_nil(volumeMount) - assert_equal("/data", volumeMount["mountPath"]) - end - - it 'supports setting subPath' do - values = { - persistenceList: [ - { - 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"] == "data" } - refute_nil(volumeMount) - assert_equal("mySubPath", volumeMount["subPath"]) - end - end - end -end diff --git a/tests/library/common/pod_spec.rb b/tests/library/common/pod_spec.rb deleted file mode 100644 index aa3ec2ac..00000000 --- a/tests/library/common/pod_spec.rb +++ /dev/null @@ -1,109 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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 - values = { - controller: { - replicas: 3 - } - } - chart.value values - 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 - end -end diff --git a/tests/library/common/portal_spec.rb b/tests/library/common/portal_spec.rb deleted file mode 100644 index ab6f675c..00000000 --- a/tests/library/common/portal_spec.rb +++ /dev/null @@ -1,311 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'portal::configmap::defaults' do - it 'no configmap exists by default' do - configmap = chart.resources(kind: "ConfigMap").first - assert_nil(configmap) - end - - it 'creates configmap when 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 "http" by default' do - values = { - portal: { - enabled: true - }, - ingress: { - main: { - enabled: false - } - } - } - chart.value values - configmap = chart.resources(kind: "ConfigMap").first - assert_equal("http", 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 'portal::configmap::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 'portal::configmap::nodeport' do - it 'nodePort host defaults to "$node_ip"' do - values = { - portal: { - enabled: true - }, - ingress: { - main: { - enabled: false - } - }, - service: { - main: { - type: "NodePort", - ports: { - main: { - 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 - }, - service: { - main: { - type: "NodePort", - ports: { - main: { - enabled: true, - port: 8080, - 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 - }, - service: { - main: { - type: "NodePort", - ports: { - main: { - enabled: true, - port: 8080, - nodePort: 666, - protocol: "HTTPS" - } - } - } - } - } - chart.value values - configmap = chart.resources(kind: "ConfigMap").first - assert_equal("https", configmap["data"]["protocol"]) - end - - it 'uses nodeport port protocol as protocol (HTTP)' do - values = { - portal: { - enabled: true - }, - service: { - main: { - type: "NodePort", - ports: { - main: { - enabled: true, - nodePort: 666, - protocol: "HTTP" - } - } - } - } - } - chart.value values - configmap = chart.resources(kind: "ConfigMap").first - assert_equal("http", configmap["data"]["protocol"]) - end - end - - describe 'portal::configmap::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 diff --git a/tests/library/common/pvc_spec.rb b/tests/library/common/pvc_spec.rb deleted file mode 100644 index 3e0ca0cf..00000000 --- a/tests/library/common/pvc_spec.rb +++ /dev/null @@ -1,181 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/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, - nameOverride: 'customSuffix' - } - } - } - chart.value values - pvc = chart.resources(kind: "PersistentVolumeClaim").find{ |s| s["metadata"]["name"] == "common-test-customSuffix" } - refute_nil(pvc) - end - - it 'nameSuffix can be skipped' do - values = { - persistence: { - config: { - enabled: true, - nameOverride: '-' - } - } - } - 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 on demand' 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 'generate TrueNAS SCALE zfs storageClass as default when isSCALE' do - values = { - global: { - isSCALE: true - }, - persistence: { - config: { - enabled: true - } - } - } - 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 'can override storageClass when isSCALE' do - values = { - global: { - isSCALE: true - }, - 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 'generate TrueNAS SCALE zfs storageClass as default when global ixChartContext' do - values = { - global: { - ixChartContext: "somethingsomething" - }, - persistence: { - config: { - enabled: true - } - } - } - 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 'generate TrueNAS SCALE zfs storageClass as default when ixChartContext' do - values = { - ixChartContext: "somethingsomething", - persistence: { - config: { - enabled: true - } - } - } - 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 'check SCALE storageClass when isSCALE and ixchartcontext' do - values = { - global: { - ixChartContext: "somethingsomething" - }, - ixChartContext: "somethingsomething", - persistence: { - config: { - enabled: true - } - } - } - 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 diff --git a/tests/library/common/service_spec.rb b/tests/library/common/service_spec.rb deleted file mode 100644 index 043d507b..00000000 --- a/tests/library/common/service_spec.rb +++ /dev/null @@ -1,290 +0,0 @@ -# frozen_string_literal: true -require_relative '../../test_helper' - -class Test < ChartTest - @@chart = Chart.new('helper-charts/common-test') - - describe @@chart.name do - describe 'service::ports settings' do - baseValues = { - service: { - main: { - ports: { - main: { - port: 8080 - } - } - } - } - } - - default_name = 'main' - default_port = 8080 - - it 'defaults to name "http" on port 8080' do - values = baseValues - 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(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 set' do - values = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - enabled: false - }, - server: { - enabled: true, - port: 8080 - } - } - } - } - }) - 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('server', service["spec"]["ports"].first["targetPort"]) - assert_equal('server', 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('server', mainContainer["ports"].first["name"]) - end - - it 'name suffix can be overridden' do - values = baseValues.deep_merge_override({ - service: { - main: { - nameOverride: 'http' - } - } - }) - chart.value values - - service = chart.resources(kind: "Service").find{ |s| s["metadata"]["name"] == "common-test-#{values[:service][:main][:nameOverride]}" } - refute_nil(service) - end - - it 'targetPort can be overridden' do - values = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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(80, 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(80, mainContainer["ports"].first["containerPort"]) - assert_equal(default_name, mainContainer["ports"].first["name"]) - end - - it 'targetPort cannot be a named port' do - values = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 test)", exception.message) - end - - it 'protocol defaults to TCP' do - values = baseValues - 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 TCP explicitly' do - values = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 - values = baseValues - 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 'TCP port protocol does not set annotations' do - values = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 = baseValues.deep_merge_override({ - service: { - main: { - ports: { - main: { - 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 diff --git a/tests/test_helper.rb b/tests/test_helper.rb deleted file mode 100644 index 6170486b..00000000 --- a/tests/test_helper.rb +++ /dev/null @@ -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