feat(ingress) refactor + tests (#621)

**Description**
<!--
Please include a summary of the change and which issue is fixed. Please
also include relevant motivation and context. List any dependencies that
are required for this change.
-->
⚒️ Fixes  # <!--(issue)-->

Partially solves https://github.com/truecharts/charts/issues/11205
Partially solves https://github.com/truecharts/charts/issues/14160
Partially solves https://github.com/truecharts/charts/issues/8080
Partially solves https://github.com/truecharts/charts/issues/9635

All the above are "partially" because changes need to be performed on
the chart it self
Eg. Set the targetSelector for the "other" ingress to point to the
"other" service

**⚙️ Type of change**

- [x] ⚙️ Feature/App addition
- [x] 🪛 Bugfix
- [ ] ⚠️ Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [x] 🔃 Refactor of current code

**🧪 How Has This Been Tested?**
<!--
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration
-->

**📃 Notes:**
<!-- Please enter any other relevant information here -->

**✔️ Checklist:**

- [x] ⚖️ My code follows the style guidelines of this project
- [x] 👀 I have performed a self-review of my own code
- [x] #️⃣ I have commented my code, particularly in hard-to-understand
areas
- [ ] 📄 I have made corresponding changes to the documentation
- [ ] ⚠️ My changes generate no new warnings
- [x] 🧪 I have added tests to this description that prove my fix is
effective or that my feature works
- [x] ⬆️ I increased versions for any altered app according to semantic
versioning

** App addition**

If this PR is an app addition please make sure you have done the
following.

- [ ] 🪞 I have opened a PR on
[truecharts/containers](https://github.com/truecharts/containers) adding
the container to TrueCharts mirror repo.
- [ ] 🖼️ I have added an icon in the Chart's root directory called
`icon.png`

---

_Please don't blindly check all the boxes. Read them and only check
those that apply.
Those checkboxes are there for the reviewer to see what is this all
about and
the status of this PR with a quick glance._
This commit is contained in:
Stavros Kois
2023-12-08 16:44:11 +02:00
committed by GitHub
parent ccce227e18
commit 913fd78ae2
32 changed files with 2626 additions and 850 deletions

View File

@@ -3,7 +3,7 @@ appVersion: ""
dependencies:
- name: common
repository: file://../common
version: ~16.0.0
version: ~16.1.0
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

View File

@@ -53,9 +53,6 @@ ingress:
paths:
- path: /
pathType: Prefix
service:
name:
port:
tls: []
scalecert:

View File

@@ -0,0 +1,115 @@
suite: ingress - cert manager metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with ingress created with annotations from cert manager
set:
operator: &operator
verify:
enabled: false
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik: &traefik
enabled: false
certManager:
enabled: true
certificateIssuer: some-issuer
hosts: &hosts
- host: test-host
paths:
- path: /test-path
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
cert-manager.io/cluster-issuer: some-issuer
cert-manager.io/private-key-rotation-policy: Always
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with ingress created without cert manager annotations when cert manager false
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik: *traefik
certManager:
enabled: false
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
isNull:
path: metadata.annotations
# Failures
- it: should fail with missing certificateIssuer
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
certManager:
enabled: true
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected a non-empty [integrations.certManager.certificateIssuer]
- it: should fail with certificateIssuer not a string
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
certManager:
enabled: true
certificateIssuer:
- some-issuer
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.certManager.certificateIssuer] to be a [string], but got [slice]

View File

@@ -0,0 +1,152 @@
suite: ingress - homepage metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with ingress created with annotations from homepage enabled
set:
k1: some-name
k2: some-desc
k3: some-icon
k4: some-url
k5: some-type
k6: some-group
operator: &operator
verify:
enabled: false
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
someHost: test-host
somePath: /test-path
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik: &traefik
enabled: false
homepage:
enabled: true
hosts:
- host: "{{ .Values.someHost }}"
paths:
- path: "{{ .Values.somePath }}"
my-ingress2:
enabled: true
integrations:
traefik: *traefik
homepage:
enabled: true
name: "{{ .Values.k1 }}"
description: "{{ .Values.k2 }}"
icon: "{{ .Values.k3 }}"
group: "{{ .Values.k6 }}"
weight: 1
podSelector:
- main
- other
widget:
url: "{{ .Values.k4 }}"
type: "{{ .Values.k5 }}"
custom:
some-key: some-value
some-other-key: some-other-value
hosts: &hosts
- host: test-host
paths:
- path: /test-path
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
gethomepage.dev/enabled: "true"
gethomepage.dev/name: CommonTest
gethomepage.dev/description: Helper chart to test different use cases of the common library
gethomepage.dev/icon: https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png
gethomepage.dev/widget.type: common-test
gethomepage.dev/widget.url: "https://test-host/test-path"
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- documentIndex: &otherIngressDoc 2
isKind:
of: Ingress
- documentIndex: *otherIngressDoc
equal:
path: metadata.annotations
value:
gethomepage.dev/enabled: "true"
gethomepage.dev/name: some-name
gethomepage.dev/description: some-desc
gethomepage.dev/group: some-group
gethomepage.dev/icon: some-icon
gethomepage.dev/widget.url: some-url
gethomepage.dev/weight: "1"
gethomepage.dev/widget.type: some-type
gethomepage.dev/pod-selector: pod.name in (main,other)
gethomepage.dev/widget.some-key: some-value
gethomepage.dev/widget.some-other-key: some-other-value
- documentIndex: *otherIngressDoc
equal:
path: metadata.name
value: test-release-name-common-test-my-ingress2
- documentIndex: *otherIngressDoc
equal:
path: metadata.namespace
value: test-release-namespace
# Failures
- it: should fail with podSelector not a slice
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
homepage:
enabled: true
podSelector: main
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.homepage.podSelector] to be a [slice], but got [string]
- it: should fail with custom widget not a map
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
homepage:
enabled: true
widget:
custom: "not a map"
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.homepage.widget.custom] to be a [map], but got [string]

View File

@@ -1,4 +1,4 @@
suite: ingress metadata
suite: ingress metadata test
templates:
- common.yaml
chart:
@@ -7,135 +7,66 @@ release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: default metadata should pass
- it: should pass with ingress created with labels and annotations
set:
operator:
label1: label1
label2: global_label2
annotation1: annotation1
annotation2: global_annotation2
global:
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"
annotations:
g_annotation1: global_annotation1
g_annotation2: "{{ .Values.annotation2 }}"
operator: &operator
verify:
enabled: false
ingress.main.enabled: true
service:
main:
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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: tc-system-chain-basic@kubernetescrd
- documentIndex: *ingressDocument
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
- it: cors metadata should pass
set:
operator:
verify:
enabled: false
port: 80
ingress:
main:
enabled: true
allowCors: true
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
my-ingress1:
enabled: true
primary: true
type: Deployment
podSpec: {}
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: tc-system-tc-opencors-chain@kubernetescrd
- documentIndex: *ingressDocument
equal:
path: metadata.labels
value:
app: common-test-1.0.0
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
- it: custom metadata should pass
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
ingress:
main:
enabled: true
annotations:
test_annotation: test
labels:
test_label: test
label1: "{{ .Values.label1 }}"
label2: label2
annotations:
annotation1: "{{ .Values.annotation1 }}"
annotation2: annotation2
integrations: &integrations
traefik:
enabled: false
hosts: &hosts
- host: test-host
paths:
- path: /test-path
my-ingress2:
enabled: true
primary: false
integrations: *integrations
hosts: *hosts
asserts:
- documentIndex: &ingressDocument 2
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDocument
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
test_annotation: test
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: tc-system-chain-basic@kubernetescrd
- documentIndex: *ingressDocument
annotation1: annotation1
annotation2: annotation2
g_annotation1: global_annotation1
g_annotation2: global_annotation2
- documentIndex: *ingressDoc
equal:
path: metadata.labels
value:
@@ -143,8 +74,121 @@ tests:
release: test-release-name
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
app.kubernetes.io/name: common-test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/version: *appVer
test_label: test
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/name: common-test
g_label1: global_label1
g_label2: global_label2
label1: label1
label2: label2
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- documentIndex: &otherIngressDoc 2
isKind:
of: Ingress
- documentIndex: *otherIngressDoc
equal:
path: metadata.labels
value:
app: common-test-1.0.0
app.kubernetes.io/instance: test-release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: common-test
app.kubernetes.io/version: *appVer
g_label1: global_label1
g_label2: global_label2
helm-revision: "0"
helm.sh/chart: common-test-1.0.0
release: test-release-name
- documentIndex: *otherIngressDoc
equal:
path: metadata.name
value: test-release-name-common-test-my-ingress2
- documentIndex: *otherIngressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with ingress created with object namespace from tpl
set:
key: some-namespace
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
namespace: "{{ .Values.key }}"
integrations: *integrations
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: some-namespace
- it: should pass with ingress created with global namespace from tpl
set:
key: global-namespace
global:
namespace: "{{ .Values.key }}"
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations: *integrations
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: global-namespace
- it: should pass with ingress created with root namespace from tpl
set:
key: local-namespace
namespace: "{{ .Values.key }}"
global:
namespace: global-namespace
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations: *integrations
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: local-namespace
- it: should pass with ingress created with namespace in TrueNAS SCALE
set:
global:
ixChartContext:
iAmNotEmpty: true
namespace: ix-namespace
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations: *integrations
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: ix-namespace

View File

@@ -0,0 +1,67 @@
suite: ingress name test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should generate correct name
set:
operator:
verify:
enabled: false
service:
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress1:
enabled: true
primary: true
hosts: &hosts
- host: test-host
paths:
- path: /test-path
my-ingress2:
enabled: true
hosts: *hosts
my-ingress3:
enabled: true
expandObjectName: false
hosts: *hosts
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
isAPIVersion:
of: networking.k8s.io/v1
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: &otherIngressDoc 2
isKind:
of: Ingress
- documentIndex: *otherIngressDoc
isAPIVersion:
of: networking.k8s.io/v1
- documentIndex: *otherIngressDoc
equal:
path: metadata.name
value: test-release-name-common-test-my-ingress2
- documentIndex: &thirdIngressDoc 3
isKind:
of: Ingress
- documentIndex: *thirdIngressDoc
isAPIVersion:
of: networking.k8s.io/v1
- documentIndex: *thirdIngressDoc
equal:
path: metadata.name
value: my-ingress3

View File

@@ -1,93 +0,0 @@
suite: ingress presence
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: default should pass
asserts:
- hasDocuments:
count: 0
- it: explicitly disabled should pass
set:
ingress.main.enabled: false
asserts:
- hasDocuments:
count: 0
- it: explicitly enabled should pass
set:
operator:
verify:
enabled: false
ingress.main.enabled: true
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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:
operator:
verify:
enabled: false
ingress.main.enabled: true
ingress.test.enabled: true
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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

View File

@@ -0,0 +1,199 @@
suite: ingress - rules test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with ingress created with ingressClassName
set:
operator: &operator
verify:
enabled: false
service:
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
ingressClassName: some-class
hosts:
- host: test-host
paths:
- path: /test-path
integrations: &integrations
traefik:
enabled: false
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.ingressClassName
value: some-class
- it: should pass with ingress created with rules
set:
operator: &operator
verify:
enabled: false
service:
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
someHost: test-host
somePath: /test-path
someType: Exact
ingress:
my-ingress:
enabled: true
primary: true
hosts: &hosts
- host: "{{ .Values.someHost }}"
paths:
- path: "{{ .Values.somePath }}"
pathType: "{{ .Values.someType }}"
- host: test-other-host
paths:
- path: /test-other-path
- path: /test-other-path2
overrideService:
name: other-service
port: 8080
integrations: *integrations
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.rules
value:
- host: test-host
http:
paths:
- path: /test-path
pathType: Exact
backend:
service:
name: test-release-name-common-test
port:
number: 80
- host: test-other-host
http:
paths:
- path: /test-other-path
pathType: Prefix
backend:
service:
name: test-release-name-common-test
port:
number: 80
- path: /test-other-path2
pathType: Prefix
backend:
service:
name: other-service
port:
number: 8080
- it: should pass with ingress created with rules with targetSelector
set:
operator: &operator
verify:
enabled: false
service:
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
my-service2:
enabled: true
ports:
my-port2:
enabled: true
port: 9000
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
my-service2: my-port2
hosts: &hosts
- host: test-host
paths:
- path: /test-path
- host: test-other-host
paths:
- path: /test-other-path
- path: /test-other-path2
overrideService:
name: other-service
port: 8080
integrations: *integrations
asserts:
- documentIndex: &ingressDoc 2
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.rules
value:
- host: test-host
http:
paths:
- path: /test-path
pathType: Prefix
backend:
service:
name: test-release-name-common-test-my-service2
port:
number: 9000
- host: test-other-host
http:
paths:
- path: /test-other-path
pathType: Prefix
backend:
service:
name: test-release-name-common-test-my-service2
port:
number: 9000
- path: /test-other-path2
pathType: Prefix
backend:
service:
name: other-service
port:
number: 8080

View File

@@ -1,79 +0,0 @@
suite: ingress service reference
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: default should pass
set:
operator:
verify:
enabled: false
ingress.main.enabled: true
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
asserts:
- documentIndex: &ingressDocument 2
isKind:
of: Ingress
- documentIndex: *ingressDocument
equal:
path: spec.rules[0].http.paths[0].backend.service
value:
name: test-release-name-common-test
port:
number: 12345
- it: custom service reference should pass
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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.service
value:
name: pathService
port:
number: 1234

View File

@@ -1,143 +1,195 @@
suite: ingress tls
suite: ingress - tls test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: default should pass
- it: should pass with ingress created with certManager integration
set:
operator:
operator: &operator
verify:
enabled: false
service:
main:
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
port: 80
ingress:
my-ingress:
enabled: true
primary: true
type: Deployment
podSpec: {}
ingress.main.enabled: true
hosts:
- host: test-host
paths:
- path: /test-path
- host: other-test-host
paths:
- path: /other-test-path
integrations: &integrations
traefik:
enabled: false
certManager:
enabled: true
certificateIssuer: some-issuer
asserts:
- documentIndex: &ingressDocument 2
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDocument
isNull:
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.tls
value:
- hosts:
- test-host
secretName: test-release-name-common-test-tls-0
- hosts:
- other-test-host
secretName: test-release-name-common-test-tls-1
- it: tls enabled should pass
- it: should pass with ingress created with tls with scaleCert
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
operator: *operator
service: *service
namespace: ix-test-namespace
global:
ixChartContext:
imNotEmpty: true
ixCertificates:
"1":
certificate: some_cert
privatekey: some_key
"2":
certificate: some_other_cert
privatekey: some_other_key
ingress:
my-ingress:
enabled: true
primary: true
type: Deployment
podSpec: {}
ingress.main:
enabled: true
tls:
- secretName: test
hosts:
- hostname
hosts:
- host: test-host
paths:
- path: /test-path
- host: other-test-host
paths:
- path: /other-test-path
tls:
- hosts:
- test-host
- other-test-host
scaleCert: "1"
- hosts:
- some-other-test-host
scaleCert: "2"
integrations: &integrations
traefik:
enabled: false
asserts:
- documentIndex: &ingressDocument 2
- documentIndex: &secretDoc 2
isKind:
of: Secret
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-scale-tls-0
- documentIndex: *secretDoc
equal:
path: data
value:
tls.crt: c29tZV9jZXJ0
tls.key: c29tZV9rZXk=
- documentIndex: *secretDoc
equal:
path: type
value: kubernetes.io/tls
- documentIndex: &secretDoc 3
isKind:
of: Secret
- documentIndex: *secretDoc
equal:
path: metadata.name
value: test-release-name-common-test-scale-tls-1
- documentIndex: *secretDoc
equal:
path: data
value:
tls.crt: c29tZV9vdGhlcl9jZXJ0
tls.key: c29tZV9vdGhlcl9rZXk=
- documentIndex: *secretDoc
equal:
path: type
value: kubernetes.io/tls
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDocument
- documentIndex: *ingressDoc
equal:
path: spec.tls[0]
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.tls
value:
secretName: test
hosts:
- hostname
- hosts:
- test-host
- other-test-host
secretName: test-release-name-common-test-scale-tls-0
- hosts:
- some-other-test-host
secretName: test-release-name-common-test-scale-tls-1
- it: tls enabled without secret should pass
- it: should pass with ingress created with tls with certificateIssuer
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
type: Deployment
podSpec: {}
ingress.main:
enabled: true
tls:
- hosts:
- hostname
hosts:
- host: test-host
paths:
- path: /test-path
- host: other-test-host
paths:
- path: /other-test-path
tls:
- hosts:
- test-host
- other-test-host
certificateIssuer: some-issuer
- hosts:
- some-other-test-host
certificateIssuer: some-other-issuer
integrations: &integrations
traefik:
enabled: false
asserts:
- documentIndex: &ingressDocument 2
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDocument
- documentIndex: *ingressDoc
equal:
path: spec.tls[0]
value:
hosts:
- hostname
- it: tls enabled with secret template should pass
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
ingress.main:
enabled: true
tls:
- secretName: "{{ .Release.Name }}-secret"
hosts:
- hostname
asserts:
- documentIndex: &ingressDocument 2
isKind:
of: Ingress
- documentIndex: *ingressDocument
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: spec.tls[0]
path: spec.tls
value:
secretName: test-release-name-secret
hosts:
- hostname
- hosts:
- test-host
- other-test-host
secretName: test-release-name-common-test-tls-0
- hosts:
- some-other-test-host
secretName: test-release-name-common-test-tls-1

View File

@@ -0,0 +1,466 @@
suite: ingress - traefik metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with ingress created with annotations from traefik
set:
operator: &operator
verify:
enabled: false
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
hosts: &hosts
- host: test-host
paths:
- path: /test-path
asserts:
- documentIndex: &ingressDoc 1
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with ingress created without traefik annotations when traefik false
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: false
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
isNull:
path: metadata.annotations
- it: should replace local fixedMiddlewares when allowCors true
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
allowCors: true
fixedMiddlewares:
- some-fixed-middleware
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: tc-opencors-chain-tc-system@kubernetescrd
- it: should replace global fixedMiddlewares when allowCors true
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
allowCors: true
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: tc-opencors-chain-tc-system@kubernetescrd
- it: should replace global fixedMiddlewares when local fixedMiddlewares is defined
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
fixedMiddlewares:
- some-fixed-middleware
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: some-fixed-middleware-tc-system@kubernetescrd
- it: should override default entrypoint(s)
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- web
- websecure
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd
- it: should not contain fixed middlewares when global is disabled
set:
operator: *operator
service: *service
global:
traefik:
enableFixedMiddlewares: false
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
- it: should not contain fixed middlewares when local is disabled
set:
operator: *operator
service: *service
global:
traefik:
enableFixedMiddlewares: true
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
enableFixedMiddlewares: false
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
- it: should set correct namespace when operator is registered
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- web
- websecure
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-some-ns@kubernetescrd
- it: should set correct namespace when ingressClassName is defined regardless of operator
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
someclass: some-class
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
ingressClassName: "{{ .Values.someclass }}"
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-some-class@kubernetescrd
- it: should set correct namespace when ingressClassName is defined in SCALE regardless of operator
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
service: *service
global:
ixChartContext:
imNotEmpty: true
namespace: ix-namespace
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
ingressClassName: some-class
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-ix-some-class@kubernetescrd
- it: should add the defined middlewares to the ingress
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares:
- some-middleware
- some-other-middleware
hosts: *hosts
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd,some-middleware-tc-system@kubernetescrd,some-other-middleware-tc-system@kubernetescrd
# Failures
- it: should fail with entrypoint not a slice
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints: "not a string"
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.entrypoints] to be a [slice], but got [string]
- it: should fail with middlewares not a slice
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares: "not a slice"
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.middlewares] to be a [slice], but got [string]
- it: should fail with fixedMiddlewares not a slice
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
fixedMiddlewares: "not a slice"
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.fixedMiddlewares] to be a [slice], but got [string]
- it: should fail with duplicate middlewares
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares:
- chain-basic
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Combined traefik middlewares contain duplicates [chain-basic, chain-basic]
- it: should fail with duplicate entrypoints
set:
operator: *operator
service: *service
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- websecure
- websecure
hosts: *hosts
asserts:
- failedTemplate:
errorMessage: Ingress - Combined traefik entrypoints contain duplicates [websecure, websecure]

View File

@@ -0,0 +1,607 @@
suite: ingress validation test
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should fail if required is true but enabled is false
set:
operator: &operator
verify:
enabled: false
service: &service
my-service:
enabled: true
primary: true
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: false
required: true
asserts:
- failedTemplate:
errorMessage: Ingress - Expected ingress [my-ingress] to be enabled. This chart is designed to work only with ingress enabled.
- it: should fail with name longer than 253 characters
set:
operator: *operator
service: *service
ingress:
my-ing:
enabled: true
primary: true
hosts: &hosts
- host: test-host
paths:
- path: /test-path
my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-long-long-long-long-long-long-long-name:
enabled: true
asserts:
- failedTemplate:
errorMessage: Name [test-release-name-common-test-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-name-that-is-longer-than-253-characters-my-ingress-super-long-long-long-long-long-long-long-long-name] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters.
- it: should fail with name starting with underscore
set:
operator: *operator
service: *service
ingress:
my-ing:
enabled: true
primary: true
hosts: *hosts
_my-ingress:
enabled: true
asserts:
- failedTemplate:
errorMessage: Name [test-release-name-common-test-_my-ingress] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 253 characters.
- it: should fail with namespace longer than 63 characters
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
namespace: my-extra-super-duper-long-name-that-is-longer-than-63-characters
asserts:
- failedTemplate:
errorMessage: Ingress - Namespace [my-extra-super-duper-long-name-that-is-longer-than-63-characters] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters.
- it: should fail with namespace not starting with [ix-] in TrueNAS SCALE
set:
global:
ixChartContext:
iAmNotEmpty: true
operator: *operator
service:
my-service:
enabled: true
primary: true
namespace: ix-namespace
ports:
main:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
namespace: my-namespace
asserts:
- failedTemplate:
errorMessage: Ingress - Namespace [my-namespace] expected to have [ix-] prefix when installed in TrueNAS SCALE
- it: should fail with labels not a dict
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
labels: "not a dict"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [labels] to be a dictionary, but got [string]
- it: should fail with annotations not a dict
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
annotations: "not a dict"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [annotations] to be a dictionary, but got [string]
- it: should fail with empty enabled
set:
operator: *operator
ingress:
my-ingress:
enabled:
asserts:
- failedTemplate:
errorMessage: Ingress - Expected the defined key [enabled] in [ingress.my-ingress] to not be empty
- it: should fail with targetSelector not a map
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
targetSelector: "not a map"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [targetSelector] to be a [map], but got [string]
- it: should fail with targetSelector having more than one key
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
main: main
other: other
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [targetSelector] to have exactly one key, but got [2]
- it: should fail with targetSelector key missing value
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
main:
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [targetSelector.main] to have a value
- it: should fail with targetSelector key having non-string value
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
main:
- not a string
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [targetSelector.main] to be a [string], but got [slice]
- it: should fail with no hosts
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts: []
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [hosts]
- it: should fail with hosts not a slice
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts: not-a-slice
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts] to be a [slice], but got [string]
- it: should fail with no hosts.host
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [hosts.host]
- it: should fail with host starting with https://
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: https://test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.host] to not start with [https://], but got [https://test-host]
- it: should fail with host starting with http://
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: http://test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.host] to not start with [http://], but got [http://test-host]
- it: should fail with host contain ":"
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host:123
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.host] to not contain [:], but got [test-host:123]
- it: should fail without paths
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [hosts.paths]
- it: should fail with paths not a slice
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths: not-a-slice
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.paths] to be a [slice], but got [string]
- it: should fail with invalid pathType
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths:
- path: /test-path
pathType: not-a-valid-path-type
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.paths.pathType] to be one of [Prefix, Exact, ImplementationSpecific], but got [not-a-valid-path-type]
- it: should fail with path not starting with / (only on pathType Exact and Prefix)
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths:
- path: test-path
pathType: Prefix
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [hosts.paths.path] to start with [/], but got [test-path]
- it: should fail if name in the overrideService is missing
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths:
- path: /test-path
overrideService:
port: 80
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [hosts.paths.overrideService.name]
- it: should fail if port in the overrideService is missing
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths:
- path: /test-path
overrideService:
name: test-service
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [hosts.paths.overrideService.port]
- it: should fail if targeted service does not exist
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
my-service: my-port
hosts:
- host: test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected targeted service [my-service] to exist
- it: should fail if targeted service is not enabled
set:
operator: *operator
service:
my-service:
enabled: false
primary: true
ports:
my-port:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
my-service: my-port
hosts:
- host: test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected targeted service [my-service] to be enabled
- it: should fail without primary service or a targetSelector
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
hosts:
- host: test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [targetSelector] or a primary service to exist
- it: should fail if the targeted service does not have the targeted port
set:
operator: *operator
service:
my-service:
enabled: true
primary: true
ports:
my-other-port:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
my-service: my-port
hosts:
- host: test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected targeted service [my-service] to have port [my-port]
- it: should fail if the targeted service port is not enabled
set:
operator: *operator
service:
my-service:
enabled: true
primary: true
ports:
my-port:
enabled: false
primary: true
port: 80
my-other-port:
enabled: true
primary: true
port: 80
ingress:
my-ingress:
enabled: true
primary: true
targetSelector:
my-service: my-port
hosts:
- host: test-host
paths:
- path: /test-path
asserts:
- failedTemplate:
errorMessage: Ingress - Expected targeted service port [my-port] to be enabled
- it: should fail if tls.hosts are empty
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts: []
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty [tls.hosts]
- it: should fail if tls.hosts is not a slice
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts: not-a-slice
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [tls.hosts] to be a [slice], but got [string]
- it: should fail if tls.hosts.host is empty
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- ""
asserts:
- failedTemplate:
errorMessage: Ingress - Expected non-empty entry in [tls.hosts]
- it: should fail if tls.hosts.host starts with https://
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- https://test-host
asserts:
- failedTemplate:
errorMessage: Ingress - Expected entry in [tls.hosts] to not start with [https://], but got [https://test-host]
- it: should fail if tls.hosts.host starts with http://
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- http://test-host
asserts:
- failedTemplate:
errorMessage: Ingress - Expected entry in [tls.hosts] to not start with [http://], but got [http://test-host]
- it: should fail if tls.hosts.host contains ":"
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- test-host:123
asserts:
- failedTemplate:
errorMessage: Ingress - Expected entry in [tls.hosts] to not contain [:], but got [test-host:123]
- it: should fail if more than 1 cert option is set under tls
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- test-host
secretName: test-secret
scaleCert: "1"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected only one of [scaleCert, secretName] to be set, but got [scaleCert, secretName]
- it: should fail with scaleCert outside of SCALE
set:
operator: *operator
service: *service
ingress:
my-ingress:
enabled: true
primary: true
hosts: *hosts
tls:
- hosts:
- test-host
scaleCert: "1"
asserts:
- failedTemplate:
errorMessage: Ingress - [tls.scalecert] can only be used in TrueNAS SCALE

View File

@@ -1,143 +0,0 @@
suite: ingress values
templates:
- common.yaml
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: default should pass
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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: test-release-name.hostname
- it: path with template should pass
set:
operator:
verify:
enabled: false
service:
main:
enabled: true
ports:
main:
enabled: true
primary: true
port: 12345
workload:
my-workload:
enabled: true
primary: true
type: Deployment
podSpec: {}
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: "/test-release-name.path"

View File

@@ -113,11 +113,13 @@ tests:
path: metadata.namespace
value: test-release-namespace
- it: should pass with service type LoadBalancer, with https port and addMetalLBAnnotations/Traefik true
- it: should pass with service type LoadBalancer, with https port and metallb.addServiceAnnotations/Traefik true
set:
global:
addMetalLBAnnotations: true
addTraefikAnnotations: true
metallb:
addServiceAnnotations: true
traefik:
addServiceAnnotations: true
proto: https
service:
my-service1:

View File

@@ -15,4 +15,4 @@ maintainers:
name: common
sources: null
type: library
version: 16.0.0
version: 16.1.0

View File

@@ -1,157 +1,93 @@
{{/*
This template serves as a blueprint for all Ingress objects that are created
within the common library.
{{/* Ingress Class */}}
{{/* Call this template:
{{ include "tc.v1.common.class.ingress" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the Ingress.
*/}}
{{- define "tc.v1.common.class.ingress" -}}
{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}}
{{- $ingressName := $fullName -}}
{{- $values := .Values.ingress -}}
{{- if hasKey . "ObjectValues" -}}
{{- with .ObjectValues.ingress -}}
{{- $values = . -}}
{{- end -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $svcData := (include "tc.v1.common.lib.ingress.targetSelector" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) -}}
{{- if not (hasKey $objectData "integrations") -}}
{{- $_ := set $objectData "integrations" dict -}}
{{- end -}}
{{- $ingressLabels := $values.labels -}}
{{- $ingressAnnotations := $values.annotations -}}
{{- $ingressName = $values.name -}}
{{/* Get the name of the primary service, if any */}}
{{- $primaryServiceName := (include "tc.v1.common.lib.util.service.primary" (dict "services" .Values.service "root" .)) -}}
{{/* Get service values of the primary service, if any */}}
{{- $primaryService := get .Values.service $primaryServiceName -}}
{{- $defaultServiceName := $fullName -}}
{{- if and (hasKey $primaryService "nameOverride") $primaryService.nameOverride -}}
{{- $defaultServiceName = printf "%v-%v" $defaultServiceName $primaryService.nameOverride -}}
{{- end -}}
{{- $defaultServicePort := get $primaryService.ports (include "tc.v1.common.lib.util.service.ports.primary" (dict "svcValues" $primaryService "svcName" $primaryServiceName )) -}}
{{- $mddwrNamespace := "tc-system" -}}
{{- if $.Values.operator.traefik -}}
{{- if $.Values.operator.traefik.namespace -}}
{{- $mddwrNamespace = $.Values.operator.traefik.namespace -}}
{{- end -}}
{{- if not (hasKey $objectData "annotations") -}}
{{- $_ := set $objectData "annotations" dict -}}
{{- end -}}
{{- if $values.ingressClassName -}}
{{- if $.Values.global.ixChartContext -}}
{{- $mddwrNamespace = (printf "ix-%s" $values.ingressClassName) -}}
{{- else -}}
{{- $mddwrNamespace = $values.ingressClassName -}}
{{- end -}}
{{- end -}}
{{- $fixedMiddlewares := "" -}}
{{- if $values.enableFixedMiddlewares -}}
{{/* If cors is enabled, replace the default fixedMiddleware with the opencors chain */}}
{{- if $values.allowCors -}}
{{- $corsMiddlewares := list "tc-opencors-chain" }}
{{- $_ := set $values "fixedMiddlewares" $corsMiddlewares -}}
{{- end -}}
{{- range $index, $fixedMiddleware := $values.fixedMiddlewares -}}
{{- if $index -}}
{{- $fixedMiddlewares = ( printf "%v, %v-%v@%v" $fixedMiddlewares $mddwrNamespace $fixedMiddleware "kubernetescrd" ) -}}
{{- else -}}
{{- $fixedMiddlewares = ( printf "%v-%v@%v" $mddwrNamespace $fixedMiddleware "kubernetescrd" ) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $middlewares := "" -}}
{{- range $index, $middleware := $values.middlewares -}}
{{- if $index -}}
{{- $middlewares = ( printf "%v, %v-%v@%v" $middlewares $mddwrNamespace $middleware "kubernetescrd" ) -}}
{{- else -}}
{{- $middlewares = ( printf "%v-%v@%v" $mddwrNamespace $middleware "kubernetescrd" ) -}}
{{- end -}}
{{ end }}
{{- if and ( $fixedMiddlewares ) ( $middlewares ) -}}
{{- $middlewares = ( printf "%v, %v" $fixedMiddlewares $middlewares ) -}}
{{- else if $fixedMiddlewares -}}
{{- $middlewares = ( printf "%s" $fixedMiddlewares ) -}}
{{- end }}
{{- include "tc.v1.common.lib.ingress.integration.certManager" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.lib.ingress.integration.traefik" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) }}
---
apiVersion: {{ include "tc.v1.common.capabilities.ingress.apiVersion" $ }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $ingressName }}
namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }}
{{- $labels := (mustMerge ($ingressLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }}
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Ingress") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (mustMerge ($ingressAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml) (include "tc.v1.common.lib.ingress.integration.homepage" (dict "objectData" $values "rootCtx" $) | fromYaml)) }}
{{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- with $values.certificateIssuer }}
cert-manager.io/cluster-issuer: {{ tpl ( toYaml . ) $ }}
cert-manager.io/private-key-rotation-policy: Always
{{- end }}
"traefik.ingress.kubernetes.io/router.entrypoints": {{ $values.entrypoint | default "websecure" }}
"traefik.ingress.kubernetes.io/router.middlewares": {{ $middlewares | quote }}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }}
{{- . | nindent 4 }}
{{- end }}
spec:
{{- if $values.ingressClassName }}
ingressClassName: {{ $values.ingressClassName }}
{{- end -}}
{{- if $values.certificateIssuer }}
tls:
{{- range $index, $hostsValues := $values.hosts }}
- hosts:
- {{ tpl $hostsValues.host $ | quote }}
secretName: {{ ( printf "%v-%v-%v" $ingressName "tls" $index ) }}
{{- end -}}
{{- else if $values.tls }}
tls:
{{- range $index, $tlsValues := $values.tls }}
{{- $tlsName := ( printf "%v-%v" "tls" $index ) }}
- hosts:
{{- range $tlsValues.hosts }}
- {{ tpl . $ | quote }}
{{- end -}}
{{- if $tlsValues.certificateIssuer }}
secretName: {{ printf "%v-%v" $ingressName $tlsName }}
{{- else if and ($tlsValues.scaleCert) ($.Values.global.ixChartContext) -}}
{{- $cert := dict }}
{{- $_ := set $cert "id" $tlsValues.scaleCert }}
{{- $_ := set $cert "nameOverride" $tlsName }}
secretName: {{ printf "%s-tls-%v" (include "tc.v1.common.lib.chart.names.fullname" $) $index }}
{{- else if .clusterCertificate }}
secretName: clusterissuer-templated-{{ tpl .clusterCertificate $ }}
{{- else if .secretName }}
secretName: {{ tpl .secretName $ | quote }}
{{- end -}}
{{- end -}}
{{- if $objectData.ingressClassName }}
ingressClassName: {{ tpl $objectData.ingressClassName $rootCtx }}
{{- end }}
rules:
{{- range $values.hosts }}
- host: {{ tpl .host $ | quote }}
{{- range $h := $objectData.hosts }}
- host: {{ tpl $h.host $rootCtx }}
http:
paths:
{{- range .paths -}}
{{- $service := $defaultServiceName -}}
{{- $port := $defaultServicePort.port -}}
{{- if .service -}}
{{- $service = default $service .service.name -}}
{{- $port = default $port .service.port -}}
{{- range $p := $h.paths -}}
{{- with $p.overrideService -}}
{{- $svcData = (dict "name" .name "port" .port) -}}
{{- end }}
- path: {{ tpl .path $ | quote }}
pathType: {{ default "Prefix" .pathType }}
- path: {{ tpl $p.path $rootCtx }}
pathType: {{ tpl ($p.pathType | default "Prefix") $rootCtx }}
backend:
service:
name: {{ $service }}
name: {{ $svcData.name }}
port:
number: {{ $port }}
number: {{ $svcData.port }}
{{- end -}}
{{- end -}}
{{/* If a certificateIssuer is defined in the whole ingress, use that */}}
{{- if and $objectData.integrations.certManager $objectData.integrations.certManager.enabled }}
tls:
{{- range $idx, $h := $objectData.hosts }}
- secretName: {{ printf "%s-tls-%d" $objectData.name ($idx | int) }}
hosts:
- {{ tpl $h.host $rootCtx }}
{{- end -}}
{{/* else if a tls section is defined use the configuration from there */}}
{{- else if $objectData.tls }}
tls:
{{- range $idx, $t := $objectData.tls -}}
{{- $secretName := "" -}}
{{- if $t.secretName -}}
{{- $secretName = tpl $t.secretName $rootCtx -}}
{{- else if $t.scaleCert -}}
{{- $secretName = printf "%s-scale-tls-%d" $objectData.name ($idx | int) -}}
{{- else if $t.certificateIssuer -}}
{{- $secretName = printf "%s-tls-%d" $objectData.name ($idx | int) -}}
{{- else if $t.clusterCertificate -}}
{{/* TODO: Needs the refactor of Certificate object */}}
{{- end }}
- secretName: {{ $secretName }}
hosts:
{{- range $h := $t.hosts }}
- {{ tpl $h $rootCtx }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -22,7 +22,7 @@ apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: {{ $objectData.name }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "priorityclass") }}
namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Priority Class") }}
{{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}}
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:

View File

@@ -158,7 +158,7 @@ spec:
{{- end -}}
{{- with $preloadLibraries }}
shared_preload_libraries:
{{- range $lib := (. | uniq) }}
{{- range $lib := (. | mustUniq) }}
- {{ $lib | quote }}
{{- end -}}
{{- end -}}

View File

@@ -13,11 +13,6 @@
{{- print "monitoring.coreos.com/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for Ingress */}}
{{- define "tc.v1.common.capabilities.ingress.apiVersion" -}}
{{- print "networking.k8s.io/v1" -}}
{{- end -}}
{{/* Return the appropriate apiVersion for NetworkPolicy*/}}
{{- define "tc.v1.common.capabilities.networkpolicy.apiVersion" -}}
{{- print "networking.k8s.io/v1" -}}

View File

@@ -172,7 +172,7 @@ objectData: The object data to be used to render the container.
{{- end -}}
{{- end -}}
{{- if not (deepEqual (uniq $item) $item) -}}
{{- if not (deepEqual (mustUniq $item) $item) -}}
{{- fail (printf "Container - Expected items of [securityContext.capabilities.%s] to be unique, but got [%s]" $key (join ", " $item)) -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,85 @@
{{/* Returns the selected service or fallback to primary */}}
{{- define "tc.v1.common.lib.ingress.targetSelector" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $selectedService := (dict "name" "" "port" 0) -}}
{{- $svcData := dict -}}
{{- $portData := dict -}}
{{- $svcName := "" -}}
{{- $portName := "" -}}
{{- if $objectData.targetSelector -}}
{{/* We have validation that only 1 key is allowed */}}
{{- $svcName = ($objectData.targetSelector | keys | mustFirst) -}}
{{- $portName = (get $objectData.targetSelector $svcName) -}}
{{- $svcData = (get $rootCtx.Values.service $svcName) -}}
{{- if not $svcData -}}
{{- fail (printf "Ingress - Expected targeted service [%s] to exist" $svcName) -}}
{{- end -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $rootCtx "objectData" $svcData
"name" $svcName "caller" "Ingress"
"key" "ingress")) -}}
{{- if ne $enabled "true" -}}
{{- fail (printf "Ingress - Expected targeted service [%s] to be enabled" $svcName) -}}
{{- end -}}
{{- else -}}
{{/* Find the primary service */}}
{{- range $name, $service := $rootCtx.Values.service -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $rootCtx "objectData" $service
"name" $name "caller" "Ingress"
"key" "ingress")) -}}
{{/* Check if its enabled */}}
{{- if eq $enabled "true" -}}
{{- if $service.primary -}}
{{- $svcName = $name -}}
{{- $svcData = $service -}}
{{/* Find the primary port */}}
{{- range $name, $port := $svcData.ports -}}
{{- if $port.primary -}}
{{- $portName = $name -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $svcData -}}
{{- fail "Ingress - Expected [targetSelector] or a primary service to exist" -}}
{{- end -}}
{{- end -}}
{{- $portData = (get $svcData.ports $portName) -}}
{{- if not $portData -}}
{{- fail (printf "Ingress - Expected targeted service [%s] to have port [%s]" $svcName $portName) -}}
{{- end -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $rootCtx "objectData" $portData
"name" $portName "caller" "Ingress"
"key" "ingress")) -}}
{{- if ne $enabled "true" -}}
{{- fail (printf "Ingress - Expected targeted service port [%s] to be enabled" $portName) -}}
{{- end -}}
{{- $expandedSvcName := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}}
{{- if not $svcData.primary -}}
{{- $expandedSvcName = printf "%s-%s" $expandedSvcName $svcName -}}
{{- end -}}
{{- $selectedService = (dict "name" $expandedSvcName "port" (tpl ($portData.port | toString) $rootCtx)) -}}
{{- $selectedService | toYaml -}}
{{- end -}}

View File

@@ -1,14 +1,182 @@
{{/* Ingress Validation */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.ingress.validation" (dict "objectData" $objectData) -}}
{{ include "tc.v1.common.lib.ingress.validation" (dict "rootCtx" $ "objectData" $objectData) -}}
objectData:
rootCtx: The root context of the chart.
objectData: The ingress object.
objectData: The Ingress object.
*/}}
{{- define "tc.v1.common.lib.ingress.validation" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- if $objectData.targetSelector -}}
{{- if not (kindIs "map" $objectData.targetSelector) -}}
{{- fail (printf "Ingress - Expected [targetSelector] to be a [map], but got [%s]" (kindOf $objectData.targetSelector)) -}}
{{- end -}}
{{- $selectors := $objectData.targetSelector | keys | len -}}
{{- if (gt $selectors 1) -}}
{{ fail (printf "Ingress - Expected [targetSelector] to have exactly one key, but got [%d]" $selectors) -}}
{{- end -}}
{{- range $k, $v := $objectData.targetSelector -}}
{{- if not $v -}}
{{- fail (printf "Ingress - Expected [targetSelector.%s] to have a value" $k) -}}
{{- end -}}
{{- if not (kindIs "string" $v) -}}
{{- fail (printf "Ingress - Expected [targetSelector.%s] to be a [string], but got [%s]" $k (kindOf $v)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $objectData.hosts -}}
{{- fail "Ingress - Expected non-empty [hosts]" -}}
{{- end -}}
{{- if not (kindIs "slice" $objectData.hosts) -}}
{{- fail (printf "Ingress - Expected [hosts] to be a [slice], but got [%s]" (kindOf $objectData.hosts)) -}}
{{- end -}}
{{- range $h := $objectData.hosts -}}
{{- if not $h.host -}}
{{- fail "Ingress - Expected non-empty [hosts.host]" -}}
{{- end -}}
{{- $host := tpl $h.host $rootCtx -}}
{{- if (hasPrefix "http://" $host) -}}
{{- fail (printf "Ingress - Expected [hosts.host] to not start with [http://], but got [%s]" $host) -}}
{{- end -}}
{{- if (hasPrefix "https://" $host) -}}
{{- fail (printf "Ingress - Expected [hosts.host] to not start with [https://], but got [%s]" $host) -}}
{{- end -}}
{{- if (contains ":" $host) -}}
{{- fail (printf "Ingress - Expected [hosts.host] to not contain [:], but got [%s]" $host) -}}
{{- end -}}
{{- if not $h.paths -}}
{{- fail "Ingress - Expected non-empty [hosts.paths]" -}}
{{- end -}}
{{- if not (kindIs "slice" $h.paths) -}}
{{- fail (printf "Ingress - Expected [hosts.paths] to be a [slice], but got [%s]" (kindOf $h.paths)) -}}
{{- end -}}
{{- range $p := $h.paths -}}
{{- $pathType := "Prefix" -}}
{{- if $p.pathType -}}
{{- $pathType = tpl $p.pathType $rootCtx -}}
{{- end -}}
{{- $validPathTypes := (list "Prefix" "Exact" "ImplementationSpecific") -}}
{{- if not (mustHas $pathType $validPathTypes) -}}
{{- fail (printf "Ingress - Expected [hosts.paths.pathType] to be one of [%s], but got [%s]" (join ", " $validPathTypes) $pathType) -}}
{{- end -}}
{{- $path := tpl $p.path $rootCtx -}}
{{- $prefixSlashTypes := (list "Prefix" "Exact") -}}
{{- if (mustHas $pathType $prefixSlashTypes) -}}
{{- if not (hasPrefix "/" $path) -}}
{{- fail (printf "Ingress - Expected [hosts.paths.path] to start with [/], but got [%s]" $path) -}}
{{- end -}}
{{- end -}}
{{/* If at least one thing in overrideService is defined... */}}
{{- with $p.overrideService -}}
{{- if not .name -}}
{{- fail "Ingress - Expected non-empty [hosts.paths.overrideService.name]" -}}
{{- end -}}
{{- if not .port -}}
{{- fail "Ingress - Expected non-empty [hosts.paths.overrideService.port]" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- range $t := $objectData.tls -}}
{{- if not $t.hosts -}}
{{- fail "Ingress - Expected non-empty [tls.hosts]" -}}
{{- end -}}
{{- if not (kindIs "slice" $t.hosts) -}}
{{- fail (printf "Ingress - Expected [tls.hosts] to be a [slice], but got [%s]" (kindOf $t.hosts)) -}}
{{- end -}}
{{- range $h := $t.hosts -}}
{{- if not $h -}}
{{- fail "Ingress - Expected non-empty entry in [tls.hosts]" -}}
{{- end -}}
{{- $host := tpl $h $rootCtx -}}
{{- if (hasPrefix "http://" $host) -}}
{{- fail (printf "Ingress - Expected entry in [tls.hosts] to not start with [http://], but got [%s]" $host) -}}
{{- end -}}
{{- if (hasPrefix "https://" $host) -}}
{{- fail (printf "Ingress - Expected entry in [tls.hosts] to not start with [https://], but got [%s]" $host) -}}
{{- end -}}
{{- if (contains ":" $host) -}}
{{- fail (printf "Ingress - Expected entry in [tls.hosts] to not contain [:], but got [%s]" $host) -}}
{{- end -}}
{{- end -}}
{{/* TODO: Add the rest of the options?! */}}
{{- $certOptions := (list "scaleCert" "secretName") -}}
{{- $optsSet := list -}}
{{- range $opt := $certOptions -}}
{{- if (get $t $opt) -}}
{{- $optsSet = mustAppend $optsSet $opt -}}
{{- end -}}
{{- end -}}
{{- if gt ($optsSet | len) 1 -}}
{{- fail (printf "Ingress - Expected only one of [%s] to be set, but got [%s]" (join ", " $certOptions) (join ", " $optsSet)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Ingress Primary Validation */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.ingress.primaryValidation" $ -}}
*/}}
{{- define "tc.v1.common.lib.ingress.primaryValidation" -}}
{{/* Initialize values */}}
{{- $hasPrimary := false -}}
{{- $hasEnabled := false -}}
{{- range $name, $ingress := $.Values.ingress -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $ "objectData" $ingress
"name" $name "caller" "Ingress"
"key" "ingress")) -}}
{{/* If ingress is enabled */}}
{{- if eq $enabled "true" -}}
{{- $hasEnabled = true -}}
{{/* And ingress is primary */}}
{{- if and (hasKey $ingress "primary") ($ingress.primary) -}}
{{/* Fail if there is already a primary ingress */}}
{{- if $hasPrimary -}}
{{- fail "Ingress - Only one ingress can be primary" -}}
{{- end -}}
{{- $hasPrimary = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Require at least one primary ingress, if any enabled */}}
{{- if and $hasEnabled (not $hasPrimary) -}}
{{- fail "Ingress - At least one enabled ingress must be primary" -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,29 @@
{{- define "tc.v1.common.lib.ingress.integration.certManager" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $certManager := $objectData.integrations.certManager -}}
{{- if $certManager.enabled -}}
{{- include "tc.v1.common.lib.ingress.integration.certManager.validate" (dict "objectData" $objectData) -}}
{{- $_ := set $objectData.annotations "cert-manager.io/cluster-issuer" $certManager.certificateIssuer -}}
{{- $_ := set $objectData.annotations "cert-manager.io/private-key-rotation-policy" "Always" -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.ingress.integration.certManager.validate" -}}
{{- $objectData := .objectData -}}
{{- $certManager := $objectData.integrations.certManager -}}
{{- if not $certManager.certificateIssuer -}}
{{- fail "Ingress - Expected a non-empty [integrations.certManager.certificateIssuer]" -}}
{{- end -}}
{{- if not (kindIs "string" $certManager.certificateIssuer) -}}
{{- fail (printf "Ingress - Expected [integrations.certManager.certificateIssuer] to be a [string], but got [%s]" (kindOf $certManager.certificateIssuer)) -}}
{{- end -}}
{{- end -}}

View File

@@ -1,35 +1,75 @@
{{/* Ingress Homepage Integration */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
objectData:
rootCtx: The root context of the chart.
objectData: The ingress object.
*/}}
{{- define "tc.v1.common.lib.ingress.integration.homepage" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $homepage := $objectData.integrations.homepage -}}
{{- if and $homepage $homepage.enabled -}}
{{- if not (hasKey $homepage "widget") -}}
{{- $_ := set $objectData.integrations.homepage "widget" dict -}}
{{- end -}}
{{- include "tc.v1.common.lib.ingress.integration.homepage.validation" (dict "objectData" $objectData) -}}
{{- $name := $homepage.name | default ($rootCtx.Chart.Name | camelcase) -}}
{{- $desc := $homepage.description | default $rootCtx.Chart.Description -}}
{{- $icon := $homepage.icon | default $rootCtx.Chart.Icon -}}
{{- $type := $homepage.widget.type | default $rootCtx.Chart.Name -}}
{{- $url := $homepage.widget.url -}}
{{- if not $url -}}
{{- $fHost := $objectData.hosts | mustFirst -}}
{{- $fPath := $fHost.paths | mustFirst -}}
{{- $host := tpl $fHost.host $rootCtx -}}
{{- $path := tpl $fPath.path $rootCtx -}}
{{- $url = printf "https://%s/%s" $host ($path | trimPrefix "/") -}}
{{- end -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/enabled" "true" -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/name" (tpl $name $rootCtx) -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/description" (tpl $desc $rootCtx) -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/icon" (tpl $icon $rootCtx) -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/widget.type" (tpl $type $rootCtx) -}}
{{- with $homepage.group -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/group" (tpl . $rootCtx) -}}
{{- end -}}
{{- with $homepage.weight -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/weight" (. | toString) -}}
{{- end -}}
{{- with $url -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/widget.url" (tpl $url $rootCtx) -}}
{{- end -}}
{{- if $homepage.widget.custom -}}
{{- range $k, $v := $homepage.widget.custom -}}
{{- $_ := set $objectData.annotations (printf "gethomepage.dev/widget.%s" $k) (tpl $v $rootCtx | toString) -}}
{{- end -}}
{{- end -}}
{{- with $homepage.podSelector -}}
{{- $selector := (printf "pod.name in (%s)" (join "," .)) -}}
{{- $_ := set $objectData.annotations "gethomepage.dev/pod-selector" $selector -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.ingress.integration.homepage.validation" -}}
{{- $objectData := .objectData -}}
{{- if and $objectData.integration $objectData.integration.homepage $objectData.integration.homepage.enabled -}}
gethomepage.dev/enabled: "true"
gethomepage.dev/name: {{ $objectData.integration.homepage.name | default ( camelcase $rootCtx.Chart.Name ) }}
gethomepage.dev/description: {{ $objectData.integration.homepage.description | default $rootCtx.Chart.Description }}
gethomepage.dev/group: {{ $objectData.integration.homepage.group | default "default" }}
gethomepage.dev/icon: {{ $objectData.integration.homepage.icon | default $rootCtx.Chart.Icon }}
{{- if $objectData.integration.homepage.podSelector -}}
gethomepage.dev/pod-selector: {{ . }}
{{- else -}}
gethomepage.dev/pod-selector: ""
{{- end -}}
{{- with $objectData.integration.homepage.weight -}}
gethomepage.dev/weight: {{ . }}
{{- end -}}
gethomepage.dev/widget.type: {{ $objectData.integration.homepage.widget.type | default $rootCtx.Chart.Name }}
{{- with (index $objectData.hosts 0) -}}
gethomepage.dev/widget.url: {{ $objectData.integration.homepage.widget.url | default (printf "%v%v" .host ( .path | default "/")) }}
{{- end -}}
{{- range $objectData.integration.homepage.widget.custom -}}
gethomepage.dev/widget.{{ .name }}: {{ .value }}
{{- end -}}
{{- end -}}
{{- $homepage := $objectData.integrations.homepage -}}
{{- with $homepage.podSelector -}}
{{- if not (kindIs "slice" .) -}}
{{- fail (printf "Ingress - Expected [integrations.homepage.podSelector] to be a [slice], but got [%s]" (kindOf .)) -}}
{{- end -}}
{{- end -}}
{{- if $homepage.widget.custom -}}
{{- if not (kindIs "map" $homepage.widget.custom) -}}
{{- fail (printf "Ingress - Expected [integrations.homepage.widget.custom] to be a [map], but got [%s]" (kindOf $homepage.widget.custom)) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,115 @@
{{- define "tc.v1.common.lib.ingress.integration.traefik" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $traefik := $objectData.integrations.traefik -}}
{{- $enabled := true -}}
{{- if and $traefik (hasKey $traefik "enabled") (kindIs "bool" $traefik.enabled) -}}
{{- $enabled = $traefik.enabled -}}
{{- end -}}
{{- if $enabled -}}
{{- include "tc.v1.common.lib.ingress.integration.traefik.validate" (dict "objectData" $objectData) -}}
{{- $fixedMiddlewares := list -}}
{{- $enableFixed := false -}}
{{- if (hasKey $rootCtx.Values.global "traefik") -}}
{{- $fixedMiddlewares = $rootCtx.Values.global.traefik.fixedMiddlewares -}}
{{- $enableFixed = $rootCtx.Values.global.traefik.enableFixedMiddlewares -}}
{{- end -}}
{{/* Override global (enable)fixedMiddlewares with local */}}
{{- if $traefik.fixedMiddlewares -}}
{{- $fixedMiddlewares = $traefik.fixedMiddlewares -}}
{{- end -}}
{{/* Replace global fixed with local fixed */}}
{{- if and (hasKey $traefik "enableFixedMiddlewares") (kindIs "bool" $traefik.enableFixedMiddlewares) -}}
{{- $enableFixed = $traefik.enableFixedMiddlewares -}}
{{- end -}}
{{/* Replace global and local fixed middlewares with the opencors-chain */}}
{{- if $traefik.allowCors -}}
{{- $fixedMiddlewares = list "tc-opencors-chain" -}}
{{- end -}}
{{- $entrypoints := $traefik.entrypoints | default (list "websecure") -}}
{{- $middlewares := list -}}
{{/* Add the fixedMiddlewares */}}
{{- if and $enableFixed $fixedMiddlewares -}}
{{- $middlewares = concat $middlewares $fixedMiddlewares -}}
{{- end -}}
{{/* Add the user middlewares */}}
{{- if $traefik.middlewares -}}
{{- $middlewares = concat $middlewares $traefik.middlewares -}}
{{- end -}}
{{/* Make sure we dont have dupes */}}
{{- if $middlewares -}}
{{- if not (deepEqual (mustUniq $middlewares) $middlewares) -}}
{{- fail (printf "Ingress - Combined traefik middlewares contain duplicates [%s]" (join ", " $middlewares)) -}}
{{- end -}}
{{- end -}}
{{- if not (deepEqual (mustUniq $entrypoints) $entrypoints) -}}
{{- fail (printf "Ingress - Combined traefik entrypoints contain duplicates [%s]" (join ", " $entrypoints)) -}}
{{- end -}}
{{- $midNamespace := "tc-system" -}}
{{/* If our hook has set operator.traefik.namespace, use that */}}
{{- if (hasKey $rootCtx.Values.operator "traefik") -}}
{{- if $rootCtx.Values.operator.traefik.namespace -}}
{{- $midNamespace = $rootCtx.Values.operator.traefik.namespace -}}
{{- end -}}
{{- end -}}
{{- if $traefik.ingressClassName -}}
{{- $midNamespace = tpl $traefik.ingressClassName $rootCtx -}}
{{/* On SCALE prepend with ix- */}}
{{- if $rootCtx.Values.global.ixChartContext -}}
{{- $midNamespace = (printf "ix-%s" $midNamespace) -}}
{{- end -}}
{{- end -}}
{{/* Format middlewares */}}
{{- $formMiddlewares := list -}}
{{- range $mid := $middlewares -}}
{{- $formMiddlewares = mustAppend $formMiddlewares (printf "%s-%s@kubernetescrd" $mid $midNamespace) -}}
{{- end -}}
{{- $_ := set $objectData.annotations "traefik.ingress.kubernetes.io/router.entrypoints" (join "," $entrypoints) -}}
{{- if $formMiddlewares -}}
{{- $_ := set $objectData.annotations "traefik.ingress.kubernetes.io/router.middlewares" (join "," $formMiddlewares) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.ingress.integration.traefik.validate" -}}
{{- $objectData := .objectData -}}
{{- $traefik := $objectData.integrations.traefik -}}
{{- if $traefik.entrypoints -}}
{{- if not (kindIs "slice" $traefik.entrypoints) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.entrypoints] to be a [slice], but got [%s]" (kindOf $traefik.entrypoints)) -}}
{{- end -}}
{{- end -}}
{{- if $traefik.middlewares -}}
{{- if not (kindIs "slice" $traefik.middlewares) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.middlewares] to be a [slice], but got [%s]" (kindOf $traefik.middlewares)) -}}
{{- end -}}
{{- end -}}
{{- if $traefik.fixedMiddlewares -}}
{{- if not (kindIs "slice" $traefik.fixedMiddlewares) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.fixedMiddlewares] to be a [slice], but got [%s]" (kindOf $traefik.fixedMiddlewares)) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -18,8 +18,10 @@ annotations: The annotations variable reference, to append the MetalLB annotatio
{{- $sharedKey = tpl . $rootCtx -}}
{{- end -}}
{{- if $rootCtx.Values.global.addMetalLBAnnotations -}}
{{- $_ := set $annotations "metallb.universe.tf/allow-shared-ip" $sharedKey -}}
{{- if (hasKey $rootCtx.Values.global "metallb") -}}
{{- if $rootCtx.Values.global.metallb.addServiceAnnotations -}}
{{- $_ := set $annotations "metallb.universe.tf/allow-shared-ip" $sharedKey -}}
{{- end -}}
{{- end -}}
{{- end -}}
@@ -34,7 +36,9 @@ annotations: The annotations variable reference, to append the Traefik annotatio
{{- $rootCtx := .rootCtx -}}
{{- $annotations := .annotations -}}
{{- if $rootCtx.Values.global.addTraefikAnnotations -}}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/service.serversscheme" "https" -}}
{{- if (hasKey $rootCtx.Values.global "traefik") -}}
{{- if $rootCtx.Values.global.traefik.addServiceAnnotations -}}
{{- $_ := set $annotations "traefik.ingress.kubernetes.io/service.serversscheme" "https" -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -32,8 +32,8 @@
{{- end -}}
{{- if $result -}}
{{- $result -}}
{{- $result -}}
{{- else -}}
{{- fail "No primary and enabled service found" -}}
{{- fail "No primary and enabled service found" -}}
{{- end -}}
{{- end -}}

View File

@@ -8,7 +8,7 @@
{{- include "tc.v1.common.loader.lists" . -}}
{{/* Ensure TrueCharts chart context information is available */}}
{{- include "tc.v1.common.lib.util.chartcontext" . -}}
{{- /* include "tc.v1.common.lib.util.chartcontext" . */ -}}
{{/* Autogenerate postgresql passwords if needed */}}
{{- include "tc.v1.common.spawner.cnpg" . }}

View File

@@ -1,62 +1,95 @@
{{/* Renders the Ingress objects required by the chart */}}
{{/* Ingress Spawwner */}}
{{/* Call this template:
{{ include "tc.v1.common.spawner.ingress" $ -}}
*/}}
{{- define "tc.v1.common.spawner.ingress" -}}
{{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}}
{{/* Generate named ingresses as required */}}
{{/* Validate that only 1 primary exists */}}
{{- include "tc.v1.common.lib.ingress.primaryValidation" $ -}}
{{- range $name, $ingress := .Values.ingress -}}
{{- if $ingress.enabled -}}
{{- $ingressValues := $ingress -}}
{{- $ingressName := $fullname -}}
{{/* set defaults */}}
{{- if and (not $ingressValues.nameOverride) (ne $name (include "tc.v1.common.lib.util.ingress.primary" $)) -}}
{{- $_ := set $ingressValues "nameOverride" $name -}}
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
"rootCtx" $ "objectData" $ingress
"name" $name "caller" "Ingress"
"key" "ingress")) -}}
{{- if and (eq $enabled "false") ($ingress.required) -}}
{{- fail (printf "Ingress - Expected ingress [%s] to be enabled. This chart is designed to work only with ingress enabled." $name) -}}
{{- end -}}
{{- if eq $enabled "true" -}}
{{/* Create a copy of the ingress */}}
{{- $objectData := (mustDeepCopy $ingress) -}}
{{/* Init object name */}}
{{- $objectName := $name -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $ "objectData" $objectData
"name" $name "caller" "Ingress"
"key" "ingress")) -}}
{{- if eq $expandName "true" -}}
{{/* Expand the name of the service if expandName resolves to true */}}
{{- $objectName = $fullname -}}
{{- end -}}
{{- if $ingressValues.nameOverride -}}
{{- $ingressName = printf "%v-%v" $ingressName $ingressValues.nameOverride -}}
{{- if and (eq $expandName "true") (not $objectData.primary) -}}
{{/* If the ingress is not primary append its name to fullname */}}
{{- $objectName = (printf "%s-%s" $fullname $name) -}}
{{- end -}}
{{- $_ := set $ingressValues "name" $ingressName -}}
{{/* Perform validations */}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Ingress") -}}
{{- include "tc.v1.common.lib.ingress.validation" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}}
{{- include "tc.v1.common.class.ingress" $ -}}
{{- if and ( $ingressValues.tls ) ( not $ingressValues.clusterIssuer ) -}}
{{- range $index, $tlsValues := $ingressValues.tls -}}
{{- $tlsName := ( printf "%v-%v" "tls" $index ) -}}
{{- if $tlsValues.certificateIssuer -}}
{{- include "tc.v1.common.class.certificate" (dict "root" $ "name" ( printf "%v-%v" $ingressName $tlsName ) "certificateIssuer" $tlsValues.certificateIssuer "hosts" $tlsValues.hosts ) -}}
{{- else if and ( $tlsValues.scaleCert ) ( $.Values.global.ixChartContext ) -}}
{{/* Set the name of the ingress */}}
{{- $_ := set $objectData "name" $objectName -}}
{{- $_ := set $objectData "shortName" $name -}}
{{/* Create certificate object and use it to construct a secret */}}
{{- $objectData := dict -}}
{{- $_ := set $objectData "id" .scaleCert -}}
{{- $objectName := (printf "%s-%s" $fullname $tlsName) -}}
{{/* Perform validations */}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}}
{{- include "tc.v1.common.lib.scaleCertificate.validation" (dict "objectData" $objectData) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Certificate") -}}
{{/* Prepare data */}}
{{- $data := fromJson (include "tc.v1.common.lib.scaleCertificate.getData" (dict "rootCtx" $ "objectData" $objectData)) -}}
{{- $_ := set $objectData "data" $data -}}
{{/* Set the type to certificate */}}
{{- $_ := set $objectData "type" "certificate" -}}
{{/* Set the name of the certificate */}}
{{- $_ := set $objectData "name" $objectName -}}
{{- $_ := set $objectData "shortName" $name -}}
{{/* Call class to create the object */}}
{{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $objectData) -}}
{{/* Call class to create the object */}}
{{- include "tc.v1.common.class.ingress" (dict "rootCtx" $ "objectData" $objectData) -}}
{{/* TODO: range over TLS and do stuff */}}
{{- $hasCertIssuer := false -}}
{{- if $objectData.integrations -}}
{{- if and $objectData.integrations.certManager $objectData.integrations.certManager.enabled -}}
{{- $hasCertIssuer = true -}}
{{- end -}}
{{- end -}}
{{- if not $hasCertIssuer -}}
{{- range $idx, $tlsData := $objectData.tls -}}
{{- if $tlsData.scaleCert -}}
{{- if not $.Values.global.ixChartContext -}}
{{- fail "Ingress - [tls.scalecert] can only be used in TrueNAS SCALE" -}}
{{- end -}}
{{- $certData := (include "tc.v1.common.lib.scaleCertificate.getData" (dict "rootCtx" $ "objectData" (dict "id" $tlsData.scaleCert)) | fromJson) -}}
{{- $certName := printf "%s-scale-tls-%d" $objectData.name ($idx | int) -}}
{{- $certObjData := (dict
"id" $tlsData.scaleCert "type" "certificate"
"name" $certName "shortName" $name
"data" $certData
) -}}
{{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $certName) -}}
{{- include "tc.v1.common.lib.scaleCertificate.validation" (dict "objectData" $certObjData) -}}
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $certObjData "caller" "Ingress") -}}
{{/* Create the secret with the certData */}}
{{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $certObjData) -}}
{{- else if $tlsData.clusterCertificate -}}
{{/* TODO: Needs the refactor of Certificate object */}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- else if $ingress.required -}}
{{- fail (printf "Ingress - [ingress.%s] is set to be [required] and cannot be disabled" $name) -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -1,4 +1,4 @@
{{/* priorityclass Spawwner */}}
{{/* Priority Class Spawner */}}
{{/* Call this template:
{{ include "tc.v1.common.spawner.priorityclass" $ -}}
*/}}

View File

@@ -43,7 +43,7 @@
{{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Service") -}}
{{- include "tc.v1.common.lib.service.validation" (dict "rootCtx" $ "objectData" $objectData) -}}
{{/* Set the name of the service account */}}
{{/* Set the name of the service */}}
{{- $_ := set $objectData "name" $objectName -}}
{{- $_ := set $objectData "shortName" $name -}}

View File

@@ -7,10 +7,19 @@ global:
# -- Set a global namespace
# TODO: Currently some objects do not support this
namespace: ""
# -- Adds metalLB annotations to services
addMetalLBAnnotations: true
# -- Adds traefik annotations to services
addTraefikAnnotations: true
metallb:
# -- Adds metalLB annotations to services
addServiceAnnotations: true
traefik:
# -- Adds traefik annotations to services (when needed)
addServiceAnnotations: true
# Enables or disables the fixed middlewares on all ingresses
# Can be overruled per ingress
enableFixedMiddlewares: true
# Applies middleware to all ingresses
# Can be overruled per ingress
fixedMiddlewares:
- chain-basic
# -- Minimum nodePort value
minNodePort: 9000
# -- Enable to stop most pods and containers including cnpg
@@ -515,7 +524,6 @@ wireguardImage:
# -- Specify the WireGuard image pull policy
pullPolicy: IfNotPresent
# -- Configure the ingresses for the chart here.
# Additional ingresses can be added by adding a dictionary key similar to the 'main' ingress.
# @default -- See below
@@ -523,104 +531,81 @@ ingress:
main:
# -- Enables or disables the ingress
enabled: false
# -- Adds integrations to ingress
# integration:
# homepage:
# enabled: true
# # Default: chart name
# name: somename
# # Default: chart description
# description: some description
# group: somegroup
# # Default: chart icon
# icon: icon.png
# pod-selector: ""
# widget:
# # Default: chartname
# type: "sometype"
# # Default: host-path of first ingress
# url: "https://example.com"
# custom:
# - somesetting: some value
# -- Make this the primary ingress (used in probes, notes, etc...).
# If there is more than 1 ingress, make sure that only 1 ingress is marked as primary.
primary: true
# -- Ensure this ingress is always enabled.
required: false
# -- Override the name suffix that is used for this ingress.
nameOverride:
# -- Autolink the ingress to a service and port, both with the same name as the ingress.
autoLink: false
# -- disable to ignore any default middlwares
enableFixedMiddlewares: true
# -- set the Cert-Manager clusterissuer for this ingress
clusterIssuer: ""
# -- List of middlewares in the traefikmiddlewares k8s namespace to add automatically
# Creates an annotation with the middlewares and appends k8s and traefik namespaces to the middleware names
# Primarily used for TrueNAS SCALE to add additional (seperate) middlewares without exposing them to the end-user
fixedMiddlewares:
- chain-basic
# -- Additional List of middlewares in the traefikmiddlewares k8s namespace to add automatically
# Creates an annotation with the middlewares and appends k8s and traefik namespaces to the middleware names
middlewares: []
annotationsList: []
# - name: somename
# value: somevalue
# -- Provide additional annotations which may be required.
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
labelsList: []
# - name: somename
# value: somevalue
# -- Set labels on the deployment/statefulset/daemonset
# -- Provide additional labels which may be required.
expandObjectName: false
# -- Provide additional labels which may be required.
labels: {}
# -- Provide additional annotations which may be required.
annotations: {}
# -- Set the ingressClass that is used for this ingress.
# Requires Kubernetes >=1.19
ingressClassName: # "nginx"
# Enable or disable CORS Requests to the ingress
allowCors: false
ingressClassName: ""
# Defaults to primary service and primary port
# targetSelector:
# # service: port
# main: main
## Configure the hosts for the ingress
hosts:
- # -- Host address. Helm template can be passed.
host: chart-example.local
## Configure the paths for the host
paths:
- # -- Path. Helm template can be passed.
path: /
# -- Ignored if not kubeVersion >= 1.14-0
pathType: Prefix
service:
# -- Overrides the service name reference for this path
name:
# -- Overrides the service port reference for this path
port:
hosts: []
# - # -- Host address. Helm template can be passed.
# host: chart-example.local
# ## Configure the paths for the host
# paths:
# - # -- Path. Helm template can be passed.
# path: /
# # -- Ignored if not kubeVersion >= 1.14-0
# pathType: Prefix
# # -- Overrides the service reference for this path, by default the selector is honored
# overrideService:
# # -- Overrides the service name reference for this path
# name:
# # -- Overrides the service port reference for this path
# port:
# -- Configure TLS for the ingress. Both secretName and hosts can process a Helm template.
# Gets ignored when clusterIssuer is filled
tls: []
# - secretName: chart-example-tls
# # Cannot be combined with scaleCert
# clusterIssuer: ""
# # Cannot be combined with clusterIssuer
# certificateIssuer: ""
# # Cannot be combined with certificateIssuer
# scaleCert: ""
# hosts:
# - chart-example.local
integrations:
certManager:
enabled: false
certificateIssuer: ""
traefik:
enabled: true
# Default to websecure
entrypoints:
- websecure
enableFixedMiddlewares: true
# Drops both global and local fixedMiddlewares when enabled
allowCors: false
# fixedMiddlewares:
# - chain-basic
middlewares: []
homepage:
enabled: false
# Default: chart name
name: somename
# Default: chart description
description: some description
# Default: no group
group: somegroup
# Default: chart icon
icon: icon.png
widget:
# Default: chartname
type: "sometype"
# Default to ingress host 0
url: "https://example.com"
custom:
- somesetting: some value
# -- BETA: Configure the gateway routes for the chart here.
# Additional routes can be added by adding a dictionary key similar to the 'main' route.