feat(common): add support for pod affinity and set default affinity (#31536)
**Description** This adds preliminary (not verified or sanitized!) support for pod affinity settings Also adds a default affinity rule, that ensures workloads with the same PVCs get scheduled on the same nodes ⚒️ Fixes #27352 ⚒️ Fixes #30967 ⚒️ Fixes #31693 **⚙️ Type of change** - [x] ⚙️ Feature/App addition - [ ] 🪛 Bugfix - [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] 🔃 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:** - [ ] ⚖️ My code follows the style guidelines of this project - [ ] 👀 I have performed a self-review of my own code - [ ] #️⃣ 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 - [ ] 🧪 I have added tests to this description that prove my fix is effective or that my feature works - [ ] ⬆️ I increased versions for any altered app according to semantic versioning - [ ] I made sure the title starts with `feat(chart-name):`, `fix(chart-name):` or `chore(chart-name):` **➕ App addition** If this PR is an app addition please make sure you have done the following. - [ ] 🖼️ 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._ --------- Signed-off-by: Kjeld Schouten <info@kjeldschouten.nl> Signed-off-by: Alfred Göppel <43101280+alfi0812@users.noreply.github.com> Signed-off-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Co-authored-by: Alfred Göppel <43101280+alfi0812@users.noreply.github.com> Co-authored-by: Stavros Kois <47820033+stavros-k@users.noreply.github.com> Co-authored-by: Stavros Kois <s.kois@outlook.com>
This commit is contained in:
co-authored by
Alfred Göppel
Stavros Kois
Stavros Kois
parent
1dba5699bd
commit
51f631985c
@@ -0,0 +1,793 @@
|
|||||||
|
suite: pod affinity test
|
||||||
|
templates:
|
||||||
|
- common.yaml
|
||||||
|
release:
|
||||||
|
name: test-release-name
|
||||||
|
namespace: test-release-namespace
|
||||||
|
tests:
|
||||||
|
- it: should pass with configured affinity and default
|
||||||
|
set:
|
||||||
|
persistence:
|
||||||
|
test-pvc-1:
|
||||||
|
enabled: true
|
||||||
|
type: pvc
|
||||||
|
mountPath: /test1
|
||||||
|
test-pvc-2:
|
||||||
|
enabled: true
|
||||||
|
type: pvc
|
||||||
|
mountPath: /test2
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 0
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
asserts:
|
||||||
|
- documentIndex: &deploymentDoc 0
|
||||||
|
isKind:
|
||||||
|
of: Deployment
|
||||||
|
- documentIndex: *deploymentDoc
|
||||||
|
isSubset:
|
||||||
|
path: spec.template.metadata.labels
|
||||||
|
content:
|
||||||
|
truecharts.org/pvc: test-pvc-1_test-pvc-2
|
||||||
|
- documentIndex: *deploymentDoc
|
||||||
|
equal:
|
||||||
|
path: spec.template.spec.affinity
|
||||||
|
value:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 0
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: truecharts.org/pvc
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- test-pvc-1_test-pvc-2
|
||||||
|
|
||||||
|
- it: should pass with configured affinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
mismatchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
namespaces:
|
||||||
|
- default
|
||||||
|
- kube-system
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- frontend
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
mismatchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
namespaces:
|
||||||
|
- default
|
||||||
|
- kube-system
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- frontend
|
||||||
|
- weight: 0
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
podAntiAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- backend
|
||||||
|
- topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- documentIndex: &deploymentDoc 0
|
||||||
|
isKind:
|
||||||
|
of: Deployment
|
||||||
|
- documentIndex: *deploymentDoc
|
||||||
|
equal:
|
||||||
|
path: spec.template.spec.affinity
|
||||||
|
value:
|
||||||
|
podAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
mismatchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
namespaces:
|
||||||
|
- default
|
||||||
|
- kube-system
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- frontend
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
mismatchLabelKeys:
|
||||||
|
- app
|
||||||
|
- tier
|
||||||
|
namespaces:
|
||||||
|
- default
|
||||||
|
- kube-system
|
||||||
|
namespaceSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- frontend
|
||||||
|
- weight: 0
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
|
||||||
|
podAntiAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-app
|
||||||
|
- my-app-2
|
||||||
|
- key: tier
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- backend
|
||||||
|
|
||||||
|
- topologyKey: kubernetes.io/zone
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- my-zone-app
|
||||||
|
- my-zone-app-2
|
||||||
|
# Failures
|
||||||
|
- it: should fail without at least one key under podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
onlyInvalidKey: some-value
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected at least one of requiredDuringSchedulingIgnoredDuringExecution or preferredDuringSchedulingIgnoredDuringExecution in [affinity.podAffinity]
|
||||||
|
- it: should fail without at least one key under podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
onlyInvalidKey: some-value
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected at least one of requiredDuringSchedulingIgnoredDuringExecution or preferredDuringSchedulingIgnoredDuringExecution in [affinity.podAntiAffinity]
|
||||||
|
|
||||||
|
- it: should fail with invalid requiredDuringSchedulingIgnoredDuringExecution key in podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
some-data: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution] to be a slice but got [map]
|
||||||
|
|
||||||
|
- it: should fail with invalid requiredDuringSchedulingIgnoredDuringExecution key in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
some-data: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution] to be a slice but got [map]
|
||||||
|
|
||||||
|
- it: should fail with invalid preferredDuringSchedulingIgnoredDuringExecution key in podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
some-data: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution] to be a slice but got [map]
|
||||||
|
|
||||||
|
- it: should fail with invalid preferredDuringSchedulingIgnoredDuringExecution key in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
some-data: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution] to be a slice but got [map]
|
||||||
|
|
||||||
|
- it: should fail with invalid podAffinityTerm weight in podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: "90"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.weight] to be a number but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid podAffinityTerm weight in podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 101
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.weight] to be between 0 and 100 but got [101]
|
||||||
|
|
||||||
|
- it: should fail with invalid podAffinityTerm weight in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: "90"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.weight] to be a number but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid podAffinityTerm weight in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 101
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.weight] to be between 0 and 100 but got [101]
|
||||||
|
|
||||||
|
- it: should fail with missing podAffinityTerm in podAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm] to be defined
|
||||||
|
|
||||||
|
- it: should fail with missing podAffinityTerm in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm] to be defined
|
||||||
|
|
||||||
|
- it: should fail with missing topology key in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.topologyKey] to be a string but got [invalid]
|
||||||
|
|
||||||
|
- it: should fail with missing podAffinityTerm in podAntiAffinity
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAntiAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions: {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.topologyKey] to be a string but got [invalid]
|
||||||
|
|
||||||
|
- it: should fail with invalid matchLabelKeys in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.matchLabelKeys] to be a slice but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid matchLabelKeys value in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
matchLabelKeys:
|
||||||
|
- 123
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.matchLabelKeys.0] to be a string but got [float64]
|
||||||
|
|
||||||
|
- it: should fail with invalid mismatchLabelKeys in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
mismatchLabelKeys: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.mismatchLabelKeys] to be a slice but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid mismatchLabelKeys value in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
mismatchLabelKeys:
|
||||||
|
- 123
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.mismatchLabelKeys.0] to be a string but got [float64]
|
||||||
|
|
||||||
|
- it: should fail with invalid namespaces in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
namespaces: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.namespaces] to be a slice but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid namespaces value in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
namespaces:
|
||||||
|
- 123
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.namespaces.0] to be a string but got [float64]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector] to be a map but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector matchExpressions in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions] to be a slice but got [string]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector operator in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: "invalid"
|
||||||
|
operator: "invalid"
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.operator] to be one of [In, NotIn, Exists, DoesNotExist] but got [invalid]
|
||||||
|
- it: should fail with invalid labelSelector key in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- operator: In
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.key] to be a string but got [invalid]
|
||||||
|
- it: should fail with invalid labelSelector values in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: Exists
|
||||||
|
values: ["not-empty"]
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.values] to be empty when operator is Exists or DoesNotExist but got [[not-empty]]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector values in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.values] to be a slice but got [invalid]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector values in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values: []
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.values] to be defined when operator is In or NotIn but got [slice]
|
||||||
|
|
||||||
|
- it: should fail with invalid labelSelector values in podAffinityTerm
|
||||||
|
set:
|
||||||
|
podOptions:
|
||||||
|
affinity:
|
||||||
|
podAffinity:
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- weight: 100
|
||||||
|
podAffinityTerm:
|
||||||
|
topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: app
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- {}
|
||||||
|
workload:
|
||||||
|
workload-name1:
|
||||||
|
enabled: true
|
||||||
|
primary: true
|
||||||
|
type: Deployment
|
||||||
|
podSpec: {}
|
||||||
|
asserts:
|
||||||
|
- failedTemplate:
|
||||||
|
errorMessage: Affinity - Expected [affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution.0.podAffinityTerm.labelSelector.matchExpressions.0.values.0] to be a string but got [map]
|
||||||
@@ -48,5 +48,5 @@ sources:
|
|||||||
- https://hub.docker.com/_/
|
- https://hub.docker.com/_/
|
||||||
- https://hub.docker.com/r/mikefarah/yq
|
- https://hub.docker.com/r/mikefarah/yq
|
||||||
type: library
|
type: library
|
||||||
version: 28.9.2
|
version: 28.10.0
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ spec:
|
|||||||
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
||||||
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
|
(include "tc.v1.common.lib.metadata.volumeLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
||||||
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ spec:
|
|||||||
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
||||||
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
|
(include "tc.v1.common.lib.metadata.volumeLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
||||||
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ spec:
|
|||||||
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
||||||
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
|
(include "tc.v1.common.lib.metadata.volumeLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
||||||
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ spec:
|
|||||||
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
{{- $labels := (mustMerge ($objectData.podSpec.labels | default dict)
|
||||||
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
(include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
(include "tc.v1.common.lib.metadata.podLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
|
(include "tc.v1.common.lib.metadata.volumeLabels" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml)
|
||||||
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
(include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | fromYaml)) -}}
|
||||||
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
{{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{{/* Labels that are added to podSpec */}}
|
||||||
|
{{/* Call this template:
|
||||||
|
{{ include "tc.v1.common.lib.metadata.volumeLabels" $ }}
|
||||||
|
*/}}
|
||||||
|
{{- define "tc.v1.common.lib.metadata.volumeLabels" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $objectData := .objectData -}}
|
||||||
|
{{- $selectedVolumes := (include "tc.v1.common.lib.pod.volumes.selected" (dict "rootCtx" $rootCtx "objectData" $objectData)) | fromJson }}
|
||||||
|
|
||||||
|
{{- $names := list -}}
|
||||||
|
{{- range $volume := $selectedVolumes.pvc -}}
|
||||||
|
{{- $names = mustAppend $names $volume.shortName -}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
truecharts.org/pvc: {{ $names | join "_" | quote }}
|
||||||
|
{{- end -}}
|
||||||
@@ -0,0 +1,161 @@
|
|||||||
|
{{/* Returns pod affinity */}}
|
||||||
|
{{/* Call this template:
|
||||||
|
{{ include "tc.v1.common.lib.pod.affinity" (dict "rootCtx" $ "objectData" $objectData) }}
|
||||||
|
rootCtx: The root context of the chart.
|
||||||
|
objectData: The object data to be used to render the Pod.
|
||||||
|
*/}}
|
||||||
|
{{- define "tc.v1.common.lib.pod.affinity" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $objectData := .objectData -}}
|
||||||
|
|
||||||
|
{{- $affinity := dict -}}
|
||||||
|
|
||||||
|
{{/* Initialize from the "global" option */}}
|
||||||
|
{{- with $rootCtx.Values.podOptions.affinity -}}
|
||||||
|
{{- $affinity = . -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/* Override with pods option */}}
|
||||||
|
{{- with $objectData.podSpec.affinity -}}
|
||||||
|
{{- $affinity = . -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/* If default affinity is enabled and its one of this types, then merge it with user input */}}
|
||||||
|
{{- $validTypes := (list "Deployment" "StatefulSet") -}}
|
||||||
|
{{- if and (mustHas $objectData.type $validTypes) $rootCtx.Values.podOptions.defaultAffinity }}
|
||||||
|
{{- $defaultAffinity := (include "tc.v1.common.lib.pod.defaultAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) -}}
|
||||||
|
{{- $defaultAffinity = $defaultAffinity | default dict -}}
|
||||||
|
{{/* Merge user input overwriting the default */}}
|
||||||
|
{{- $affinity = mustMergeOverwrite $defaultAffinity $affinity -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation" (dict "rootCtx" $rootCtx "objectData" $affinity) -}}
|
||||||
|
|
||||||
|
{{- if $affinity.nodeAffinity }}
|
||||||
|
nodeAffinity:
|
||||||
|
{{- fail "TODO: not implemented" -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $affinity.podAffinity }}
|
||||||
|
podAffinity:
|
||||||
|
{{- include "tc.v1.common.lib.pod.podAffinityOrPodAntiAffinity" (dict "rootCtx" $rootCtx "data" $affinity.podAffinity) | nindent 2 -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $affinity.podAntiAffinity }}
|
||||||
|
podAntiAffinity:
|
||||||
|
{{- include "tc.v1.common.lib.pod.podAffinityOrPodAntiAffinity" (dict "rootCtx" $rootCtx "data" $affinity.podAntiAffinity) | nindent 2 -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.podAffinityOrPodAntiAffinity" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $data := .data -}}
|
||||||
|
|
||||||
|
{{- if $data -}}
|
||||||
|
{{- if $data.requiredDuringSchedulingIgnoredDuringExecution }}
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
{{- range $term := $data.requiredDuringSchedulingIgnoredDuringExecution }}
|
||||||
|
- {{ include "tc.v1.common.lib.pod.podAffinityTerm" (dict "rootCtx" $rootCtx "data" $term) | trim | nindent 6 }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.preferredDuringSchedulingIgnoredDuringExecution }}
|
||||||
|
preferredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
{{- range $term := $data.preferredDuringSchedulingIgnoredDuringExecution }}
|
||||||
|
- weight: {{ $term.weight }}
|
||||||
|
podAffinityTerm:
|
||||||
|
{{- include "tc.v1.common.lib.pod.podAffinityTerm" (dict "rootCtx" $rootCtx "data" $term.podAffinityTerm) | nindent 10 }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.podAffinityTerm" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $data := .data -}}
|
||||||
|
|
||||||
|
{{- if $data }}
|
||||||
|
topologyKey: {{ $data.topologyKey }}
|
||||||
|
|
||||||
|
{{- if $data.matchLabelKeys }}
|
||||||
|
matchLabelKeys:
|
||||||
|
{{- range $data.matchLabelKeys }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.mismatchLabelKeys }}
|
||||||
|
mismatchLabelKeys:
|
||||||
|
{{- range $data.mismatchLabelKeys }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.namespaces }}
|
||||||
|
namespaces:
|
||||||
|
{{- range $data.namespaces }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.labelSelector }}
|
||||||
|
labelSelector:
|
||||||
|
{{- include "tc.v1.common.lib.pod.labelSelector" (dict "rootCtx" $rootCtx "data" $data.labelSelector) | nindent 2 -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.namespaceSelector }}
|
||||||
|
namespaceSelector:
|
||||||
|
{{- include "tc.v1.common.lib.pod.labelSelector" (dict "rootCtx" $rootCtx "data" $data.namespaceSelector) | nindent 2 -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.labelSelector" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $data := .data }}
|
||||||
|
|
||||||
|
{{- if $data.matchExpressions -}}
|
||||||
|
matchExpressions:
|
||||||
|
{{- range $expression := $data.matchExpressions }}
|
||||||
|
- key: {{ $expression.key }}
|
||||||
|
operator: {{ $expression.operator }}
|
||||||
|
{{- if mustHas $expression.operator (list "In" "NotIn") }}
|
||||||
|
values:
|
||||||
|
{{- range $expression.values }}
|
||||||
|
- {{ . }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- if $data.matchLabels -}}
|
||||||
|
matchLabels:
|
||||||
|
{{- range $key, $value := $data.matchLabels }}
|
||||||
|
{{ $key }}: {{ $value }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.defaultAffinity" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $objectData := .objectData -}}
|
||||||
|
|
||||||
|
{{- $selectedVolumes := (include "tc.v1.common.lib.pod.volumes.selected" (dict "rootCtx" $rootCtx "objectData" $objectData)) | fromJson }}
|
||||||
|
|
||||||
|
{{- $names := list -}}
|
||||||
|
{{- range $volume := $selectedVolumes.pvc -}}
|
||||||
|
{{- $names = mustAppend $names $volume.shortName -}}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if $names }}
|
||||||
|
podAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
- topologyKey: kubernetes.io/hostname
|
||||||
|
labelSelector:
|
||||||
|
matchExpressions:
|
||||||
|
- key: truecharts.org/pvc
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- {{ $names | join "_" }}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
{{- define "tc.v1.common.lib.pod.affinity.validation" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $objectData := .objectData -}}
|
||||||
|
|
||||||
|
{{- if $objectData.podAffinity -}}
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.podAffinityOrPodAntiAffinity" (dict "rootCtx" $rootCtx "data" $objectData.podAffinity "key" "podAffinity") -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $objectData.podAntiAffinity -}}
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.podAffinityOrPodAntiAffinity" (dict "rootCtx" $rootCtx "data" $objectData.podAntiAffinity "key" "podAntiAffinity") -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.affinity.validation.podAffinityOrPodAntiAffinity" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $data := .data -}}
|
||||||
|
{{- $key := .key -}}
|
||||||
|
|
||||||
|
{{- if $data -}}
|
||||||
|
{{- if and (not $data.requiredDuringSchedulingIgnoredDuringExecution) (not $data.preferredDuringSchedulingIgnoredDuringExecution) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected at least one of requiredDuringSchedulingIgnoredDuringExecution or preferredDuringSchedulingIgnoredDuringExecution in [affinity.%s]" $key) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.requiredDuringSchedulingIgnoredDuringExecution -}}
|
||||||
|
{{- $itemData := $data.requiredDuringSchedulingIgnoredDuringExecution -}}
|
||||||
|
{{- if not (kindIs "slice" $itemData) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.requiredDuringSchedulingIgnoredDuringExecution] to be a slice but got [%s]" $key (kindOf $itemData)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $idx, $item := $itemData -}}
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.podAffinityTerm" (dict "rootCtx" $rootCtx "data" $item "key" (printf "%s.requiredDuringSchedulingIgnoredDuringExecution.%d" $key $idx)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.preferredDuringSchedulingIgnoredDuringExecution -}}
|
||||||
|
{{- $itemData := $data.preferredDuringSchedulingIgnoredDuringExecution -}}
|
||||||
|
|
||||||
|
{{- if not (kindIs "slice" $itemData) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.preferredDuringSchedulingIgnoredDuringExecution] to be a slice but got [%s]" $key (kindOf $itemData)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $idx, $item := $itemData -}}
|
||||||
|
{{- if not (mustHas (kindOf $item.weight) (list "int" "int64" "float64")) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.preferredDuringSchedulingIgnoredDuringExecution.%d.weight] to be a number but got [%s]" $key $idx (kindOf $item.weight)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if or (gt ($item.weight | int) 100) (lt ($item.weight | int) 0) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.preferredDuringSchedulingIgnoredDuringExecution.%d.weight] to be between 0 and 100 but got [%d]" $key $idx ($item.weight | int)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if not $item.podAffinityTerm -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.preferredDuringSchedulingIgnoredDuringExecution.%d.podAffinityTerm] to be defined" $key $idx) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.podAffinityTerm" (dict "rootCtx" $rootCtx "data" $item.podAffinityTerm "key" (printf "%s.preferredDuringSchedulingIgnoredDuringExecution.%d.podAffinityTerm" $key $idx)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.affinity.validation.podAffinityTerm" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $data := .data -}}
|
||||||
|
{{- $key := .key -}}
|
||||||
|
|
||||||
|
{{- if not (kindIs "string" $data.topologyKey) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.topologyKey] to be a string but got [%s]" $key (kindOf $data.topologyKey)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.matchLabelKeys -}}
|
||||||
|
{{- if not (kindIs "slice" $data.matchLabelKeys) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchLabelKeys] to be a slice but got [%s]" $key (kindOf $data.matchLabelKeys)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $idx, $value := $data.matchLabelKeys -}}
|
||||||
|
{{- if not (kindIs "string" $value) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchLabelKeys.%d] to be a string but got [%s]" $key $idx (kindOf $value)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.mismatchLabelKeys -}}
|
||||||
|
{{- if not (kindIs "slice" $data.mismatchLabelKeys) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.mismatchLabelKeys] to be a slice but got [%s]" $key (kindOf $data.mismatchLabelKeys)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $idx, $value := $data.mismatchLabelKeys -}}
|
||||||
|
{{- if not (kindIs "string" $value) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.mismatchLabelKeys.%d] to be a string but got [%s]" $key $idx (kindOf $value)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.namespaces -}}
|
||||||
|
{{- if not (kindIs "slice" $data.namespaces) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.namespaces] to be a slice but got [%s]" $key (kindOf $data.namespaces)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $idx, $value := $data.namespaces -}}
|
||||||
|
{{- if not (kindIs "string" $value) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.namespaces.%d] to be a string but got [%s]" $key $idx (kindOf $value)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.labelSelector -}}
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.labelSelector" (dict "rootCtx" $rootCtx "key" (printf "%s.labelSelector" $key) "data" $data.labelSelector) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.namespaceSelector -}}
|
||||||
|
{{- include "tc.v1.common.lib.pod.affinity.validation.labelSelector" (dict "rootCtx" $rootCtx "key" (printf "%s.namespaceSelector" $key) "data" $data.namespaceSelector) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.affinity.validation.labelSelector" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $key := .key -}}
|
||||||
|
{{- $data := .data -}}
|
||||||
|
|
||||||
|
{{- if not (kindIs "map" $data) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s] to be a map but got [%s]" $key (kindOf $data)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.matchLabels -}}
|
||||||
|
{{- if not (kindIs "map" $data.matchLabels) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchLabels] to be a map but got [%s]" $key (kindOf $data.matchLabels)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $key, $value := $data.matchLabels -}}
|
||||||
|
{{- if not (kindIs "string" $value) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchLabels.%s] to be a string but got [%s]" $key $key (kindOf $value)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if $data.matchExpressions }}
|
||||||
|
{{- if not (kindIs "slice" $data.matchExpressions) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions] to be a slice but got [%s]" $key (kindOf $data.matchExpressions)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- $validOperators := list "In" "NotIn" "Exists" "DoesNotExist" -}}
|
||||||
|
{{- range $idx, $exp := $data.matchExpressions -}}
|
||||||
|
{{- if not (kindIs "map" $exp) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected item of [affinity.%s.matchExpressions.%d] to be a map but got [%s]" $key $idx (kindOf $exp)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if not (mustHas $exp.operator $validOperators) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.operator] to be one of [%s] but got [%s]" $key $idx (join ", " $validOperators) $exp.operator) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if not (kindIs "string" $exp.key) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.key] to be a string but got [%s]" $key $idx (kindOf $exp.key)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if and (mustHas $exp.operator (list "In" "NotIn")) (not (kindIs "slice" $exp.values)) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.values] to be a slice but got [%s]" $key $idx (kindOf $exp.values)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if and (mustHas $exp.operator (list "Exists" "DoesNotExist")) $exp.values -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.values] to be empty when operator is Exists or DoesNotExist but got [%v]" $key $idx ($exp.values)) -}}
|
||||||
|
{{- else if not $exp.values -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.values] to be defined when operator is In or NotIn but got [%s]" $key $idx (kindOf $exp.values)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- range $vIdx, $value := $exp.values -}}
|
||||||
|
{{- if not (kindIs "string" $value) -}}
|
||||||
|
{{- fail (printf "Affinity - Expected [affinity.%s.matchExpressions.%d.values.%d] to be a string but got [%s]" $key $idx $vIdx (kindOf $value)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
@@ -8,76 +8,11 @@ objectData: The object data to be used to render the Pod.
|
|||||||
{{- $rootCtx := .rootCtx -}}
|
{{- $rootCtx := .rootCtx -}}
|
||||||
{{- $objectData := .objectData -}}
|
{{- $objectData := .objectData -}}
|
||||||
|
|
||||||
{{- range $name, $persistenceValues := $rootCtx.Values.persistence -}}
|
{{- $selectedVolumes := (include "tc.v1.common.lib.pod.volumes.selected" (dict "rootCtx" $rootCtx "objectData" $objectData)) | fromJson -}}
|
||||||
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
|
|
||||||
"rootCtx" $rootCtx "objectData" $persistenceValues
|
|
||||||
"name" $name "caller" "Volumes"
|
|
||||||
"key" "persistence")) -}}
|
|
||||||
{{- if (eq $enabled "true") -}}
|
|
||||||
{{- $persistence := (mustDeepCopy $persistenceValues) -}}
|
|
||||||
{{- $_ := set $persistence "shortName" $name -}}
|
|
||||||
|
|
||||||
{{- $selected := false -}}
|
|
||||||
|
|
||||||
{{/* If set to true, define volume */}}
|
|
||||||
{{- if $persistence.targetSelectAll -}}
|
|
||||||
{{- $selected = true -}}
|
|
||||||
|
|
||||||
{{/* If the pod is the autopermission */}}
|
|
||||||
{{- else if eq $objectData.shortName "autopermissions" -}}
|
|
||||||
{{- if $persistence.autoPermissions -}}
|
|
||||||
{{- if $persistence.autoPermissions.enabled -}}
|
|
||||||
{{- $selected = true -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/* If targetSelector is set, check if pod is selected */}}
|
|
||||||
{{- else if $persistence.targetSelector -}}
|
|
||||||
{{- if not (kindIs "map" $persistence.targetSelector) -}}
|
|
||||||
{{- fail (printf "Persistence - Expected [targetSelector] to be [dict], but got [%s]" (kindOf $persistence.targetSelector)) -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- if (mustHas $objectData.shortName (keys $persistence.targetSelector)) -}}
|
|
||||||
{{- $selected = true -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/* If no targetSelector is set or targetSelectAll, check if pod is primary */}}
|
|
||||||
{{- else if $objectData.primary -}}
|
|
||||||
{{- $selected = true -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/* If pod selected */}}
|
|
||||||
{{- if $selected -}}
|
|
||||||
{{/* Define the volume based on type */}}
|
|
||||||
{{- $type := ($persistence.type | default $rootCtx.Values.global.fallbackDefaults.persistenceType) -}}
|
|
||||||
|
|
||||||
{{- include "tc.v1.common.lib.pod.volumes.checkRWO" (dict
|
|
||||||
"rootCtx" $rootCtx "objectData" $objectData "persistence" $persistence
|
|
||||||
"type" $type "name" $name)
|
|
||||||
-}}
|
|
||||||
|
|
||||||
{{- if eq "pvc" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.pvc" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "hostPath" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.hostPath" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "secret" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.secret" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "configmap" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.configmap" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "emptyDir" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.emptyDir" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "nfs" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.nfs" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "iscsi" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.iscsi" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "projected" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.projected" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- else if eq "device" $type -}}
|
|
||||||
{{- include "tc.v1.common.lib.pod.volume.device" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
|
{{- range $type, $volumes := $selectedVolumes -}}
|
||||||
|
{{- range $volume := $volumes -}}
|
||||||
|
{{- include (printf "tc.v1.common.lib.pod.volume.%s" $type) (dict "rootCtx" $rootCtx "objectData" $volume) | trim | nindent 0 -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
@@ -123,3 +58,65 @@ objectData: The object data to be used to render the Pod.
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- $hasRWO -}}
|
{{- $hasRWO -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "tc.v1.common.lib.pod.volumes.selected" -}}
|
||||||
|
{{- $rootCtx := .rootCtx -}}
|
||||||
|
{{- $objectData := .objectData -}}
|
||||||
|
|
||||||
|
{{- $selectedVolumes := dict
|
||||||
|
"pvc" list
|
||||||
|
"secret" list
|
||||||
|
"configmap" list
|
||||||
|
"emptyDir" list
|
||||||
|
"hostPath" list
|
||||||
|
"nfs" list
|
||||||
|
"iscsi" list
|
||||||
|
"projected" list
|
||||||
|
"device" list
|
||||||
|
-}}
|
||||||
|
|
||||||
|
{{- range $name, $persistenceValues := $rootCtx.Values.persistence -}}
|
||||||
|
{{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict
|
||||||
|
"rootCtx" $rootCtx "objectData" $persistenceValues
|
||||||
|
"name" $name "caller" "Volumes"
|
||||||
|
"key" "persistence"))
|
||||||
|
-}}
|
||||||
|
|
||||||
|
{{- if (ne $enabled "true") -}}{{- continue -}}{{- end -}}
|
||||||
|
{{- $persistence := (mustDeepCopy $persistenceValues) -}}
|
||||||
|
{{- $_ := set $persistence "shortName" $name -}}
|
||||||
|
|
||||||
|
{{- $selected := false -}}
|
||||||
|
|
||||||
|
{{- if $persistence.targetSelectAll -}}
|
||||||
|
{{- $selected = true -}}
|
||||||
|
{{- else if eq $objectData.shortName "autopermissions" -}}
|
||||||
|
{{- if and $persistence.autoPermissions $persistence.autoPermissions.enabled -}}
|
||||||
|
{{- $selected = true -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- else if $persistence.targetSelector -}}
|
||||||
|
{{- if not (kindIs "map" $persistence.targetSelector) -}}
|
||||||
|
{{- fail (printf "Persistence - Expected [targetSelector] to be [dict], but got [%s]" (kindOf $persistence.targetSelector)) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if (mustHas $objectData.shortName (keys $persistence.targetSelector)) -}}
|
||||||
|
{{- $selected = true -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- else if $objectData.primary -}}
|
||||||
|
{{- $selected = true -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- if not $selected -}}{{- continue -}}{{- end -}}
|
||||||
|
|
||||||
|
{{- $type := ($persistence.type | default $rootCtx.Values.global.fallbackDefaults.persistenceType) -}}
|
||||||
|
{{- if eq $type "vct" -}}{{- continue -}}{{- end -}}
|
||||||
|
|
||||||
|
{{- include "tc.v1.common.lib.pod.volumes.checkRWO" (dict
|
||||||
|
"rootCtx" $rootCtx "objectData" $objectData "persistence" $persistence "type" $type "name" $name)
|
||||||
|
-}}
|
||||||
|
|
||||||
|
{{- $_ := set $selectedVolumes $type (mustAppend (index $selectedVolumes $type) $persistence) -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- $selectedVolumes | toJson -}}
|
||||||
|
{{- end -}}
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ priorityClassName: {{ . }}
|
|||||||
nodeSelector:
|
nodeSelector:
|
||||||
{{- . | nindent 2 }}
|
{{- . | nindent 2 }}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
{{- with (include "tc.v1.common.lib.pod.affinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
|
||||||
|
affinity:
|
||||||
|
{{- . | nindent 2 }}
|
||||||
|
{{- end -}}
|
||||||
{{- with (include "tc.v1.common.lib.pod.topologySpreadConstraints" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
|
{{- with (include "tc.v1.common.lib.pod.topologySpreadConstraints" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
|
||||||
topologySpreadConstraints:
|
topologySpreadConstraints:
|
||||||
{{- . | nindent 2 }}
|
{{- . | nindent 2 }}
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ podOptions:
|
|||||||
# If this key exists, takes precedence over the automated calculation
|
# If this key exists, takes precedence over the automated calculation
|
||||||
# hostUsers: false
|
# hostUsers: false
|
||||||
shareProcessNamespace: false
|
shareProcessNamespace: false
|
||||||
|
affinity: {}
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
dnsConfig:
|
dnsConfig:
|
||||||
options:
|
options:
|
||||||
@@ -153,6 +154,7 @@ podOptions:
|
|||||||
kubernetes.io/arch: "amd64"
|
kubernetes.io/arch: "amd64"
|
||||||
# -- Used to enforce a good spread for Deployments and StatefulSets by default
|
# -- Used to enforce a good spread for Deployments and StatefulSets by default
|
||||||
defaultSpread: true
|
defaultSpread: true
|
||||||
|
defaultAffinity: true
|
||||||
topologySpreadConstraints: []
|
topologySpreadConstraints: []
|
||||||
tolerations: []
|
tolerations: []
|
||||||
schedulerName: ""
|
schedulerName: ""
|
||||||
@@ -204,14 +206,14 @@ vpa:
|
|||||||
# updateMode: auto
|
# updateMode: auto
|
||||||
resourcePolicy:
|
resourcePolicy:
|
||||||
containerPolicies:
|
containerPolicies:
|
||||||
- containerName: '*'
|
- containerName: "*"
|
||||||
minAllowed:
|
minAllowed:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
memory: 50Mi
|
memory: 50Mi
|
||||||
maxAllowed:
|
maxAllowed:
|
||||||
cpu: 8000m
|
cpu: 8000m
|
||||||
memory: 20Gi
|
memory: 20Gi
|
||||||
controlledResources: ["cpu", "memory"]
|
controlledResources: ["cpu", "memory"]
|
||||||
|
|
||||||
# -- Horizontal pod autoscaler
|
# -- Horizontal pod autoscaler
|
||||||
hpa:
|
hpa:
|
||||||
@@ -250,7 +252,6 @@ hpa:
|
|||||||
# value: 4
|
# value: 4
|
||||||
# periodSeconds: 60
|
# periodSeconds: 60
|
||||||
|
|
||||||
|
|
||||||
# -- (docs/service/README.md)
|
# -- (docs/service/README.md)
|
||||||
service:
|
service:
|
||||||
main:
|
main:
|
||||||
|
|||||||
Reference in New Issue
Block a user