(tests) move back to ruby based tests (#1051)

* (tests) move back to ruby based tests

* move workflow back to using Ruby
This commit is contained in:
Kjeld Schouten-Lebbing 2021-09-28 15:11:36 +02:00 committed by GitHub
parent caa51471c7
commit 79a0923eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 2758 additions and 3430 deletions

View File

@ -1,32 +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": "TrueCharts-Dev",
"build": {
"context": "..",
"dockerfile": "containers/dev/devcontainer/Dockerfile",
"args": {
"VERSION": "1.16",
}
},
// 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",
"golang.go"
],
// 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"
}

View File

@ -123,47 +123,22 @@ jobs:
# Unit-Test section
##
# Get values for cache paths to be used in later steps
- id: go-cache-paths
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
run: |
echo "::set-output name=go-build::$(go env GOCACHE)"
echo "::set-output name=go-mod::$(go env GOMODCACHE)"
# Cache go build cache, used to speedup go test
- name: Go Build Cache
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
uses: actions/cache@v2
- name: Install Ruby for unittests
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
uses: ruby/setup-ruby@v1
with:
path: ${{ steps.go-cache-paths.outputs.go-build }}
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
ruby-version: 2.7
- name: Download modules
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
- name: Install dependencies
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
run: |
go mod download
- name: Run unit tests
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
run: |
go test ./charts/.../tests -json | tee test.json
- name: Annotate unit tests
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
uses: guyarb/golang-test-annotations@v0.5.0
with:
test-results: test.json
export RUBYJQ_USE_SYSTEM_LIBRARIES=1
bundle install
- name: Parse Unit Tests
if: ${{ steps.prep-lint.outputs.unittests == 'true' }}
- name: Run common unit tests
if: ${{ matrix.app == 'common' && matrix.app != '.gitkee' }}
run: |
if grep -q "FAIL" test.json
then
echo "Unit Test reported FAILED";
exit 1
else
echo "Unit Test reported OK";
exit 0
fi
bundle exec m -r tests
##
# Chart-Testing Section

View File

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

36
.vscode/launch.json vendored
View File

@ -1,18 +1,34 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Common",
"type": "go",
"name": "UnitTest - active spec file only",
"type": "Ruby",
"request": "launch",
"mode": "test",
"remotePath": "",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}/charts/library/common/tests/",
"env": {},
"args": ["-test.v"],
"showLog": true
"cwd": "${workspaceRoot}",
"program": "/usr/local/bin/bundle",
"args": [
"exec",
"m",
"-r",
"${relativeFile}"
]
},
{
"name": "UnitTest - all spec files",
"type": "Ruby",
"request": "launch",
"cwd": "${workspaceRoot}",
"program": "/usr/local/bin/bundle",
"args": [
"exec",
"m",
"-r",
"${workspaceFolder}/tests"
]
}
]
}

12
Gemfile Normal file
View File

@ -0,0 +1,12 @@
# 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

15
go.mod
View File

@ -1,15 +0,0 @@
module github.com/truecharts/apps
go 1.16
require (
github.com/Jeffail/gabs/v2 v2.6.1
github.com/stretchr/testify v1.7.0
helm.sh/helm/v3 v3.6.1
sigs.k8s.io/yaml v1.3.0
)
replace (
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
)

1146
go.sum

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
podgrab
homer
code
deepstack
navidrome
pgadmin4
openvpn-client
eclipse-mosquitto
dockeryourxyzzy
esphome
core
focalboard
owncast
unpackerr
komga
mealie
home-assistant
gaps
truecommand
unifi
jellyfin
flood
handbrake
jdownloader-2
lychee-laravel
deconz
omada-controller
piaware
nextcloud
netshoot
node-red
octoprint
organizr
openldap
phpldapadmin
ocis
photoprism
pihole
postgres
py-kms
k8s_gateway
gonic
protonmail-bridge
hyperion.ng
stash
syncthing
ser2sock
thelounge
traefik
server
dizquetv
zwavejs2mqtt

View File

@ -1,133 +0,0 @@
package helmunit
import (
"io"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
v "helm.sh/helm/v3/pkg/cli/values"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/releaseutil"
"sigs.k8s.io/yaml"
)
var settings *cli.EnvSettings
type HelmChart struct {
Name string
ChartPath string
Manifests manifestCollection
Hooks manifestCollection
Notes string
Values map[string]interface{}
}
func New(name string, chartPath string) HelmChart {
h := HelmChart{
Name: name,
ChartPath: chartPath,
Manifests: make(manifestCollection),
Hooks: make(manifestCollection),
}
return h
}
func (c *HelmChart) UpdateDependencies() error {
settings = cli.New()
client := defaultClient(c.Name, settings.Namespace())
p := getter.All(&cli.EnvSettings{})
// Check chart dependencies to make sure all are present in /charts
chartRequested, err := loader.Load(c.ChartPath)
if err != nil {
return err
}
if req := chartRequested.Metadata.Dependencies; req != nil {
if err := action.CheckDependencies(chartRequested, req); err != nil {
if client.DependencyUpdate {
man := &downloader.Manager{
Out: io.Discard,
ChartPath: c.ChartPath,
Keyring: client.ChartPathOptions.Keyring,
SkipUpdate: false,
Getters: p,
}
if err := man.Update(); err != nil {
return err
}
}
}
}
return nil
}
func (c *HelmChart) Render(valueFilePaths, stringValues []string, rawYamlValues *string) error {
settings = cli.New()
client := defaultClient(c.Name, settings.Namespace())
c.Manifests.Initialize()
c.Hooks.Initialize()
p := getter.All(&cli.EnvSettings{})
valueOpts := &v.Options{
ValueFiles: valueFilePaths,
Values: stringValues,
}
values, err := valueOpts.MergeValues(p)
if err != nil {
return err
}
if !(rawYamlValues == nil) {
currentMap := map[string]interface{}{}
if err := yaml.Unmarshal([]byte(*rawYamlValues), &currentMap); err != nil {
panic(err)
}
values = mergeMaps(currentMap, values)
}
c.Values = values
chartRequested, err := loader.Load(c.ChartPath)
if err != nil {
return err
}
release, err := client.Run(chartRequested, values)
if err != nil {
return err
}
for _, manifest := range releaseutil.SplitManifests(release.Manifest) {
err := c.Manifests.Add([]byte(manifest))
if err != nil {
return err
}
}
for _, manifest := range release.Hooks {
err := c.Hooks.Add([]byte(manifest.Manifest))
if err != nil {
return err
}
}
c.Notes = release.Info.Notes
return nil
}
func defaultClient(name, namespace string) *action.Install {
client := action.NewInstall(&action.Configuration{})
client.Version = ">0.0.0-0"
client.ReleaseName = name
client.Namespace = namespace
client.ClientOnly = true
client.DryRun = true
client.DependencyUpdate = true
return client
}

View File

@ -1,47 +0,0 @@
package helmunit
import (
"errors"
"strings"
"github.com/Jeffail/gabs/v2"
)
type manifestCollection map[string]map[string]gabs.Container
func (c *manifestCollection) Initialize() {
*c = make(manifestCollection)
}
func (c *manifestCollection) Add(yamlInput []byte) error {
collection := *c
jsonManifest, err := yamlToJson(yamlInput)
if err != nil {
return err
}
kind := strings.ToLower(jsonManifest.Path("kind").Data().(string))
name := strings.ToLower(jsonManifest.Path("metadata.name").Data().(string))
if kind == "" || name == "" {
return errors.New("invalid manifest")
}
data, ok := collection[kind]
if !ok {
data = make(map[string]gabs.Container)
collection[kind] = data
}
data[name] = *jsonManifest
return nil
}
func (c *manifestCollection) Get(kind string, name string) *gabs.Container {
collection := *c
manifest, ok := collection[strings.ToLower(kind)][strings.ToLower(name)]
if !ok {
return nil
}
return &manifest
}

View File

@ -1,37 +0,0 @@
package helmunit
import (
"github.com/Jeffail/gabs/v2"
"sigs.k8s.io/yaml"
)
func mergeMaps(a, b map[string]interface{}) map[string]interface{} {
out := make(map[string]interface{}, len(a))
for k, v := range a {
out[k] = v
}
for k, v := range b {
if v, ok := v.(map[string]interface{}); ok {
if bv, ok := out[k]; ok {
if bv, ok := bv.(map[string]interface{}); ok {
out[k] = mergeMaps(bv, v)
continue
}
}
}
out[k] = v
}
return out
}
func yamlToJson(yamlInput []byte) (jsonOutput *gabs.Container, err error) {
jsonBytes, err := yaml.YAMLToJSON(yamlInput)
if err != nil {
return nil, err
}
jsonParsed, err := gabs.ParseJSON(jsonBytes)
if err != nil {
return nil, err
}
return jsonParsed, nil
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

146
tests/test_helper.rb Normal file
View File

@ -0,0 +1,146 @@
# 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