diff --git a/check/ahoy-hw.yaml b/check/ahoy-hw.yaml new file mode 100644 index 0000000..d2fe641 --- /dev/null +++ b/check/ahoy-hw.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ahoy + namespace: default +spec: + ingressClassName: cilium + rules: + - host: ahoy-hw.guaranteedstruggle.host + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: ahoy-hello-world + port: + name: app diff --git a/check/bgp-policy.yaml b/check/bgp-policy.yaml new file mode 100644 index 0000000..e7220d0 --- /dev/null +++ b/check/bgp-policy.yaml @@ -0,0 +1,17 @@ +apiVersion: "cilium.io/v2alpha1" +kind: CiliumBGPPeeringPolicy +metadata: + name: 01-bgp-peering-policy +spec: + nodeSelector: + matchLabels: + bgp-policy: a + virtualRouters: + - localASN: 64512 + exportPodCIDR: true + neighbors: + - peerAddress: '192.168.0.105/32' + peerASN: 64512 + serviceSelector: + matchExpressions: + - {key: somekey, operator: NotIn, values: ['never-used-value']} diff --git a/check/config-pool.yaml b/check/config-pool.yaml new file mode 100644 index 0000000..9c9358b --- /dev/null +++ b/check/config-pool.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: metallb-system + name: config +data: + config: | + address-pools: + - name: default + protocol: layer2 + addresses: + - 192.168.0.105-192.168.0.105 diff --git a/check/default-ingress.yaml b/check/default-ingress.yaml new file mode 100644 index 0000000..c920bff --- /dev/null +++ b/check/default-ingress.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: redirect + namespace: weave +spec: + ingressClassName: cilium + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: weave-scope-app + port: + name: app diff --git a/check/deployment-flask-htmx-board-dev.yaml b/check/deployment-flask-htmx-board-dev.yaml new file mode 100644 index 0000000..3822002 --- /dev/null +++ b/check/deployment-flask-htmx-board-dev.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flask-htmx-dev + namespace: vdk2ch +spec: + revisionHistoryLimit: 5 + replicas: 2 + selector: + matchLabels: + app: flask-htmx-dev + template: + metadata: + labels: + app: flask-htmx-dev + spec: + containers: + - name: flask-htmx-dev + image: harbor.guaranteedstruggle.host/library/flask-htmx-board1:dev + imagePullPolicy: Always + ports: + - containerPort: 5000 + + #### таймауты и прочее взяты с потолка + #livenessProbe: + # httpGet: + # path: /liveness + # port: 5000 + # initialDelaySeconds: 2 + # timeoutSeconds: 2 + # periodSeconds: 5 + # failureThreshold: 2 + #readinessProbe: + # httpGet: + # path: /readiness + # port: 5000 + # initialDelaySeconds: 3 + # timeoutSeconds: 3 + # periodSeconds: 10 + # failureThreshold: 3 + diff --git a/check/deployment-flask-htmx-board-master.yaml b/check/deployment-flask-htmx-board-master.yaml new file mode 100644 index 0000000..ad27eb6 --- /dev/null +++ b/check/deployment-flask-htmx-board-master.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flask-htmx-master + namespace: vdk2ch +spec: + revisionHistoryLimit: 5 + replicas: 2 + selector: + matchLabels: + app: flask-htmx-master + template: + metadata: + labels: + app: flask-htmx-master + spec: + containers: + - name: flask-htmx-master + image: harbor.guaranteedstruggle.host/library/flask-htmx-board1:master-of-slaves + imagePullPolicy: Always + ports: + - containerPort: 5000 + + #### таймауты и прочее взяты с потолка + #livenessProbe: + # httpGet: + # path: /liveness + # port: 5000 + # initialDelaySeconds: 2 + # timeoutSeconds: 2 + # periodSeconds: 5 + # failureThreshold: 2 + #readinessProbe: + # httpGet: + # path: /readiness + # port: 5000 + # initialDelaySeconds: 3 + # timeoutSeconds: 3 + # periodSeconds: 10 + # failureThreshold: 3 + diff --git a/check/deployment-flask-htmx-board-our-style.yaml b/check/deployment-flask-htmx-board-our-style.yaml new file mode 100644 index 0000000..3f0e2a0 --- /dev/null +++ b/check/deployment-flask-htmx-board-our-style.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: flask-htmx-our-style + namespace: vdk2ch +spec: + revisionHistoryLimit: 5 + replicas: 2 + selector: + matchLabels: + app: flask-htmx-our-style + template: + metadata: + labels: + app: flask-htmx-our-style + spec: + containers: + - name: flask-htmx-our-style + image: harbor.guaranteedstruggle.host/library/flask-htmx-board1:our-style + imagePullPolicy: Always + ports: + - containerPort: 5000 + + #### таймауты и прочее взяты с потолка + #livenessProbe: + # httpGet: + # path: /liveness + # port: 5000 + # initialDelaySeconds: 2 + # timeoutSeconds: 2 + # periodSeconds: 5 + # failureThreshold: 2 + #readinessProbe: + # httpGet: + # path: /readiness + # port: 5000 + # initialDelaySeconds: 3 + # timeoutSeconds: 3 + # periodSeconds: 10 + # failureThreshold: 3 + diff --git a/check/gateway-1.yaml b/check/gateway-1.yaml new file mode 100644 index 0000000..d3c1ff8 --- /dev/null +++ b/check/gateway-1.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: my-gateway + labels: + color: coral +spec: + gatewayClassName: cilium + addresses: + - value: "0.0.0.0" + - type: IPAddress + value: 192.168.0.105 + - type: IPAddress + value: 10.0.10.251 + listeners: + - protocol: HTTP + port: 80 + name: web-gw + allowedRoutes: + namespaces: + from: All diff --git a/check/httproute-ahoy.yaml b/check/httproute-ahoy.yaml new file mode 100644 index 0000000..7123a41 --- /dev/null +++ b/check/httproute-ahoy.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-ahoy + namespace: default +spec: + hostnames: + - ahoy.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: ahoy-hello-world + port: 80 diff --git a/check/httproute-artifactory.yaml b/check/httproute-artifactory.yaml new file mode 100644 index 0000000..1cb040d --- /dev/null +++ b/check/httproute-artifactory.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-artifactory + namespace: artifactory +spec: + hostnames: + - artifactory.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: artifactory-artifactory-nginx + port: 80 diff --git a/check/httproute-dashy.yaml b/check/httproute-dashy.yaml new file mode 100644 index 0000000..fe01bc4 --- /dev/null +++ b/check/httproute-dashy.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-dashy + namespace: dashy +spec: + hostnames: + - dashy.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: dashy + port: 10310 diff --git a/check/httproute-flask-htmx-board-dev.yaml b/check/httproute-flask-htmx-board-dev.yaml new file mode 100644 index 0000000..f7833f7 --- /dev/null +++ b/check/httproute-flask-htmx-board-dev.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-flask-htmx-board-dev + namespace: vdk2ch +spec: + hostnames: + #- board.guaranteedstruggle.host + - dev.board.vdk2ch.ru + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: flask-htmx-dev-service + port: 5000 diff --git a/check/httproute-flask-htmx-board-master.yaml b/check/httproute-flask-htmx-board-master.yaml new file mode 100644 index 0000000..36d09cc --- /dev/null +++ b/check/httproute-flask-htmx-board-master.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-flask-htmx-board-master + namespace: vdk2ch +spec: + hostnames: + #- board.guaranteedstruggle.host + - master.board.vdk2ch.ru + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: flask-htmx-master-service + port: 5000 diff --git a/check/httproute-flask-htmx-board-our-style.yaml b/check/httproute-flask-htmx-board-our-style.yaml new file mode 100644 index 0000000..787cf36 --- /dev/null +++ b/check/httproute-flask-htmx-board-our-style.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-flask-htmx-board-our-style + namespace: vdk2ch +spec: + hostnames: + #- board.guaranteedstruggle.host + - our-style.board.vdk2ch.ru + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: flask-htmx-our-style-service + port: 5000 diff --git a/check/httproute-harbor.yaml b/check/httproute-harbor.yaml new file mode 100644 index 0000000..3a3da97 --- /dev/null +++ b/check/httproute-harbor.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-harbor + namespace: default +spec: + hostnames: + - harbor.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: harbor + port: 80 diff --git a/check/httproute-hubble.yaml b/check/httproute-hubble.yaml new file mode 100644 index 0000000..d44305d --- /dev/null +++ b/check/httproute-hubble.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-hubble + namespace: kube-system +spec: + hostnames: + - hubble.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: hubble-ui + port: 80 diff --git a/check/httproute-longhorn.yaml b/check/httproute-longhorn.yaml new file mode 100644 index 0000000..66b644c --- /dev/null +++ b/check/httproute-longhorn.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-longhorn + namespace: longhorn-system +spec: + hostnames: + - longhorn.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: longhorn-frontend + port: 80 diff --git a/check/httproute-rancher.yaml b/check/httproute-rancher.yaml new file mode 100644 index 0000000..9d001a6 --- /dev/null +++ b/check/httproute-rancher.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-app-1 + namespace: default +spec: + hostnames: + - rancher.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + filters: + - type: RequestHeaderModifier + requestHeaderModifier: + set: + - name: X-Forwarded-Proto + value: https +# - name: Host +# value: rancher.guaranteedstruggle.host + backendRefs: + - name: myrancher + port: 80 diff --git a/check/httproute-weave.yaml b/check/httproute-weave.yaml new file mode 100644 index 0000000..7787570 --- /dev/null +++ b/check/httproute-weave.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-app-2 + namespace: weave +spec: + hostnames: + - weave.guaranteedstruggle.host + parentRefs: + - name: my-gateway + namespace: default + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: weave-scope-app + port: 80 diff --git a/check/ippool.yaml b/check/ippool.yaml new file mode 100644 index 0000000..7d6b58f --- /dev/null +++ b/check/ippool.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: "cilium.io/v2alpha1" +kind: CiliumLoadBalancerIPPool +metadata: + name: "the-pool" +spec: + cidrs: + - cidr: "192.168.0.105/30" + + serviceSelector: + matchExpressions: + - {key: color, operator: In, values: [coral]} diff --git a/check/ippool2.yaml b/check/ippool2.yaml new file mode 100644 index 0000000..c33e046 --- /dev/null +++ b/check/ippool2.yaml @@ -0,0 +1,9 @@ +apiVersion: "cilium.io/v2alpha1" +kind: CiliumLoadBalancerIPPool +metadata: + name: "lb-pool" +spec: + cidrs: + + - cidr: "10.0.10.0/24" + diff --git a/check/longhorn.yaml b/check/longhorn.yaml new file mode 100644 index 0000000..ef45b6e --- /dev/null +++ b/check/longhorn.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: longhorn + namespace: longhorn-system +spec: + ingressClassName: cilium + rules: + - host: longhorn.guaranteedstruggle.host + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: longhorn-frontend + port: + name: http diff --git a/check/network-policy-wut.yaml b/check/network-policy-wut.yaml new file mode 100644 index 0000000..1aaa192 --- /dev/null +++ b/check/network-policy-wut.yaml @@ -0,0 +1,16 @@ +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +#description: "Allow to access backends only on TCP/80" +metadata: + name: "frontend-backend" +spec: + endpointSelector: + matchLabels: + namespace: longhorn-system + ingress: + - toPorts: + - ports: + - port: '80' + protocol: TCP + - fromCIDR: + - 0.0.0.0/0 diff --git a/check/pv-pod.yaml b/check/pv-pod.yaml new file mode 100644 index 0000000..b2a9530 --- /dev/null +++ b/check/pv-pod.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: garbo + namespace: default +spec: + accessModes: + - ReadWriteOnce + storageClassName: longhorn + resources: + requests: + storage: 2Gi +--- +apiVersion: v1 +kind: Pod +metadata: + name: volume-test + namespace: default +spec: + restartPolicy: Always + containers: + - name: volume-test + image: nginx:stable-alpine + imagePullPolicy: IfNotPresent + livenessProbe: + exec: + command: + - ls + - /data/lost+found + initialDelaySeconds: 5 + periodSeconds: 5 + volumeMounts: + - name: volv + mountPath: /data + ports: + - containerPort: 80 + volumes: + - name: volv + persistentVolumeClaim: + claimName: garbo diff --git a/check/rancher.yaml b/check/rancher.yaml new file mode 100644 index 0000000..2b306fd --- /dev/null +++ b/check/rancher.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: rancher + namespace: default + annotations: + ingress.cilium.io/insecure-node-port: "80" +spec: + ingressClassName: cilium + rules: + - host: rancher.guaranteedstruggle.host + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: myrancher + port: + name: http diff --git a/check/svc-flask-htmx-board-dev.yaml b/check/svc-flask-htmx-board-dev.yaml new file mode 100644 index 0000000..56e3f8c --- /dev/null +++ b/check/svc-flask-htmx-board-dev.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: flask-htmx-dev-service + namespace: vdk2ch +spec: + selector: + app: flask-htmx-dev + ports: + - protocol: TCP + name: board + port: 5000 + targetPort: 5000 + diff --git a/check/svc-flask-htmx-board-master.yaml b/check/svc-flask-htmx-board-master.yaml new file mode 100644 index 0000000..2ad7c61 --- /dev/null +++ b/check/svc-flask-htmx-board-master.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: flask-htmx-master-service + namespace: vdk2ch +spec: + selector: + app: flask-htmx-master + ports: + - protocol: TCP + name: board + port: 5000 + targetPort: 5000 + diff --git a/check/svc-flask-htmx-board-our-style.yaml b/check/svc-flask-htmx-board-our-style.yaml new file mode 100644 index 0000000..0e71119 --- /dev/null +++ b/check/svc-flask-htmx-board-our-style.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: flask-htmx-our-style-service + namespace: vdk2ch +spec: + selector: + app: flask-htmx-our-style + ports: + - protocol: TCP + name: board + port: 5000 + targetPort: 5000 + diff --git a/check/weave.yaml b/check/weave.yaml new file mode 100644 index 0000000..35c46ea --- /dev/null +++ b/check/weave.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: weave + namespace: weave +spec: + ingressClassName: cilium + rules: + - host: weave.guaranteedstruggle.host + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: weave-scope-app + port: + name: app diff --git a/helm-charts/consul-k8s b/helm-charts/consul-k8s new file mode 160000 index 0000000..7215ec0 --- /dev/null +++ b/helm-charts/consul-k8s @@ -0,0 +1 @@ +Subproject commit 7215ec05d0f4ef093de2f4ddc80b385214522e4d diff --git a/helm-charts/dashy/.helmignore b/helm-charts/dashy/.helmignore new file mode 100644 index 0000000..77ca556 --- /dev/null +++ b/helm-charts/dashy/.helmignore @@ -0,0 +1,30 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# OWNERS file for Kubernetes +OWNERS +# helm-docs templates +*.gotmpl +# docs folder +/docs +# icon +icon.png diff --git a/helm-charts/dashy/CHANGELOG.md b/helm-charts/dashy/CHANGELOG.md new file mode 100644 index 0000000..0204bcf --- /dev/null +++ b/helm-charts/dashy/CHANGELOG.md @@ -0,0 +1,215 @@ +# Changelog + + + +## [dashy-1.0.0](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-1.0.0) (2022-11-10) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Major Change to GUI + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4349](https://github.com/truecharts/charts/issues/4349)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + ### Fix + +- change container config label + + + + +## [dashy-0.0.13](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.13) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4349](https://github.com/truecharts/charts/issues/4349)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.12](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.12) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.12](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.12) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.12](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.12) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.11](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.11) (2022-11-07) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.11](https://github.com/truecharts/charts/compare/dashy-0.0.10...dashy-0.0.11) (2022-11-06) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [dashy-0.0.10](https://github.com/truecharts/charts/compare/dashy-0.0.9...dashy-0.0.10) (2022-11-06) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4317](https://github.com/truecharts/charts/issues/4317)) + + + + +## [dashy-0.0.9](https://github.com/truecharts/charts/compare/dashy-0.0.8...dashy-0.0.9) (2022-11-05) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4308](https://github.com/truecharts/charts/issues/4308)) + + + + +## [dashy-0.0.8](https://github.com/truecharts/charts/compare/dashy-0.0.7...dashy-0.0.8) (2022-11-02) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4261](https://github.com/truecharts/charts/issues/4261)) + + + + +## [dashy-0.0.7](https://github.com/truecharts/charts/compare/dashy-0.0.6...dashy-0.0.7) (2022-10-25) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4182](https://github.com/truecharts/charts/issues/4182)) + + + + +## [dashy-0.0.6](https://github.com/truecharts/charts/compare/dashy-0.0.5...dashy-0.0.6) (2022-10-19) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4122](https://github.com/truecharts/charts/issues/4122)) + + + + +## [dashy-0.0.5](https://github.com/truecharts/charts/compare/dashy-0.0.4...dashy-0.0.5) (2022-10-12) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4071](https://github.com/truecharts/charts/issues/4071)) + + + + +## [dashy-0.0.4](https://github.com/truecharts/charts/compare/dashy-0.0.3...dashy-0.0.4) (2022-10-07) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major + + + + +## [dashy-0.0.4](https://github.com/truecharts/charts/compare/dashy-0.0.3...dashy-0.0.4) (2022-10-07) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major + + + + +## [dashy-0.0.3](https://github.com/truecharts/charts/compare/dashy-0.0.2...dashy-0.0.3) (2022-10-05) + +### Chore + +- Auto-update chart README [skip ci] + - split addons in smaller templates ([#3979](https://github.com/truecharts/charts/issues/3979)) + - update helm general non-major + + + + +## [dashy-0.0.2](https://github.com/truecharts/charts/compare/dashy-0.0.1...dashy-0.0.2) (2022-09-27) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#3918](https://github.com/truecharts/charts/issues/3918)) + + + + +## [dashy-0.0.1]dashy-0.0.1 (2022-09-25) + +### Feat + +- add dashy ([#3887](https://github.com/truecharts/charts/issues/3887)) diff --git a/helm-charts/dashy/Chart.lock b/helm-charts/dashy/Chart.lock new file mode 100644 index 0000000..e271fcc --- /dev/null +++ b/helm-charts/dashy/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://library-charts.truecharts.org + version: 14.3.5 +digest: sha256:b7cb6511c16fc5f11e4769ebf0c48524b2522a0408b8de14207cdf19109996c6 +generated: "2023-11-08T22:28:31.22683905Z" diff --git a/helm-charts/dashy/Chart.yaml b/helm-charts/dashy/Chart.yaml new file mode 100644 index 0000000..fac3f58 --- /dev/null +++ b/helm-charts/dashy/Chart.yaml @@ -0,0 +1,26 @@ +annotations: + truecharts.org/SCALE-support: "true" + truecharts.org/category: dashboard + truecharts.org/grade: U +apiVersion: v2 +appVersion: 2.1.1 +dependencies: +- name: common + repository: https://library-charts.truecharts.org + version: 14.3.5 +description: Dashy helps you organize your self-hosted services by making them accessible + from a single place +home: https://truecharts.org/charts/stable/dashy +icon: https://truecharts.org/img/hotlink-ok/chart-icons/dashy.png +keywords: +- dashboard +kubeVersion: '>=1.16.0-0' +maintainers: +- email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: dashy +sources: +- https://github.com/truecharts/charts/tree/master/charts/stable/dashy +- https://github.com/Lissy93/dashy +version: 3.0.27 diff --git a/helm-charts/dashy/README.md b/helm-charts/dashy/README.md new file mode 100644 index 0000000..e0a9b8f --- /dev/null +++ b/helm-charts/dashy/README.md @@ -0,0 +1,27 @@ +# README + +## General Info + +TrueCharts can be installed as both *normal* Helm Charts or as Apps on TrueNAS SCALE. +However only installations using the TrueNAS SCALE Apps system are supported. + +For more information about this App, please check the docs on the TrueCharts [website](https://truecharts.org/charts/stable/) + +**This chart is not maintained by the upstream project and any issues with the chart should be raised [here](https://github.com/truecharts/charts/issues/new/choose)** + + +## Support + +- Please check our [quick-start guides for TrueNAS SCALE](https://truecharts.org/manual/SCALE/guides/scale-intro). +- See the [Website](https://truecharts.org) +- Check our [Discord](https://discord.gg/tVsPTHWTtr) +- Open a [issue](https://github.com/truecharts/charts/issues/new/choose) + +--- + +## Sponsor TrueCharts + +TrueCharts can only exist due to the incredible effort of our staff. +Please consider making a [donation](https://truecharts.org/sponsor) or contributing back to the project any way you can! + +*All Rights Reserved - The TrueCharts Project* diff --git a/helm-charts/dashy/charts/common/.helmignore b/helm-charts/dashy/charts/common/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm-charts/dashy/charts/common/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm-charts/dashy/charts/common/Chart.yaml b/helm-charts/dashy/charts/common/Chart.yaml new file mode 100644 index 0000000..61cf362 --- /dev/null +++ b/helm-charts/dashy/charts/common/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +appVersion: latest +description: Function library for TrueCharts +home: https://github.com/truecharts/apps/tree/master/charts/common +icon: https://avatars.githubusercontent.com/u/76400755 +keywords: +- truecharts +- library-chart +- common +kubeVersion: '>=1.16.0-0' +maintainers: +- email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: common +type: library +version: 14.3.5 diff --git a/helm-charts/dashy/charts/common/LICENSE b/helm-charts/dashy/charts/common/LICENSE new file mode 100644 index 0000000..4ce034b --- /dev/null +++ b/helm-charts/dashy/charts/common/LICENSE @@ -0,0 +1,106 @@ +Business Source License 1.1 + +Parameters + +Licensor: The TrueCharts Project, it's owner and it's contributors +Licensed Work: The TrueCharts "Common" Helm Chart +Additional Use Grant: You may use the licensed work in production, as long + as it is directly sourced from a TrueCharts provided + official repository, catalog or source. You may also make private + modification to the directly sourced licenced work, + when used in production. + + The following cases are, due to their nature, also + defined as 'production use' and explicitly prohibited: + - Bundling, including or displaying the licensed work + with(in) another work intended for production use, + with the apparent intend of facilitating and/or + promoting production use by third parties in + violation of this license. + +Change Date: 2050-01-01 + +Change License: 3-clause BSD license + +For information about alternative licensing arrangements for the Software, +please contact: legal@truecharts.org + +Notice + +The Business Source License (this document, or the “License”) is not an Open +Source license. However, the Licensed Work will eventually be made available +under an Open Source License, as stated in this License. + +License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. +“Business Source License” is a trademark of MariaDB Corporation Ab. + +----------------------------------------------------------------------------- + +Business Source License 1.1 + +Terms + +The Licensor hereby grants you the right to copy, modify, create derivative +works, redistribute, and make non-production use of the Licensed Work. The +Licensor may make an Additional Use Grant, above, permitting limited +production use. + +Effective on the Change Date, or the fourth anniversary of the first publicly +available distribution of a specific version of the Licensed Work under this +License, whichever comes first, the Licensor hereby grants you rights under +the terms of the Change License, and the rights granted in the paragraph +above terminate. + +If your use of the Licensed Work does not comply with the requirements +currently in effect as described in this License, you must purchase a +commercial license from the Licensor, its affiliated entities, or authorized +resellers, or you must refrain from using the Licensed Work. + +All copies of the original and modified Licensed Work, and derivative works +of the Licensed Work, are subject to this License. This License applies +separately for each version of the Licensed Work and the Change Date may vary +for each version of the Licensed Work released by Licensor. + +You must conspicuously display this License on each original or modified copy +of the Licensed Work. If you receive the Licensed Work in original or +modified form from a third party, the terms and conditions set forth in this +License apply to your use of that work. + +Any use of the Licensed Work in violation of this License will automatically +terminate your rights under this License for the current and all other +versions of the Licensed Work. + +This License does not grant you any right in any trademark or logo of +Licensor or its affiliates (provided that you may use a trademark or logo of +Licensor as expressly required by this License). + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON +AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, +EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND +TITLE. + +MariaDB hereby grants you permission to use this License’s text to license +your works, and to refer to it using the trademark “Business Source License”, +as long as you comply with the Covenants of Licensor below. + +Covenants of Licensor + +In consideration of the right to use this License’s text and the “Business +Source License” name and trademark, Licensor covenants to MariaDB, and to all +other recipients of the licensed work to be provided by Licensor: + +1. To specify as the Change License the GPL Version 2.0 or any later version, + or a license that is compatible with GPL Version 2.0 or a later version, + where “compatible” means that software provided under the Change License can + be included in a program with software provided under GPL Version 2.0 or a + later version. Licensor may specify additional Change Licenses without + limitation. + +2. To either: (a) specify an additional grant of rights to use that does not + impose any additional restriction on the right granted in this License, as + the Additional Use Grant; or (b) insert the text “None”. + +3. To specify a Change Date. + +4. Not to modify this License in any other way. diff --git a/helm-charts/dashy/charts/common/README.md b/helm-charts/dashy/charts/common/README.md new file mode 100644 index 0000000..f4615d7 --- /dev/null +++ b/helm-charts/dashy/charts/common/README.md @@ -0,0 +1,24 @@ +# Common Library + +## Naming Scheme + +- ServiceAccount: + - Primary: `$FullName` + - Others: `$FullName-$ServiceAccountName` +- RBAC: + - Primary: `$FullName` + - Others: `$FullName-$RBACName` +- Service: + - Primary: `$FullName` + - Others: `$FullName-$ServiceName` +- Pods: + - Primary: `$FullName` + - Others: `$FullName-$PodName` +- Containers: `$ContainerName` +- ConfigMap: `$FullName-$ConfigMapName` +- Secret: `$FullName-$SecretName` +- Scale Certificate: `$FullName-$CertName` +- Scale External Interface: `ix-$ReleaseName-$index` + +> Full name -> `$ReleaseName-$ChartName` +> Any name that exceeds 63 characters, will throw an error diff --git a/helm-charts/dashy/charts/common/templates/addons/code-server/_codeserver.tpl b/helm-charts/dashy/charts/common/templates/addons/code-server/_codeserver.tpl new file mode 100644 index 0000000..599e862 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/code-server/_codeserver.tpl @@ -0,0 +1,53 @@ +{{/* +Template to render code-server addon +It will include / inject the required templates based on the given values. +*/}} +{{- define "tc.v1.common.addon.codeserver" -}} +{{- $targetSelector := "main" -}} +{{- if $.Values.addons.codeserver.targetSelector -}} + {{- $targetSelector = $.Values.addons.codeserver.targetSelector -}} +{{- end -}} +{{- if .Values.addons.codeserver.enabled -}} + {{/* Append the code-server container to the workloads */}} + {{- $container := include "tc.v1.common.addon.codeserver.container" . | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload $targetSelector -}} + {{- $_ := set $workload.podSpec.containers "codeserver" $container -}} + {{- end -}} + + {{- $hasPrimaryService := false -}} + {{- range $svcName, $svcValues := .Values.service -}} + {{- if $svcValues.enabled -}} + {{- if $svcValues.primary -}} + {{- $hasPrimaryService = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{/* Add the code-server service */}} + {{- if .Values.addons.codeserver.service.enabled -}} + {{- $serviceValues := .Values.addons.codeserver.service -}} + {{- $_ := set $serviceValues "targetSelector" $targetSelector -}} + {{- if not $hasPrimaryService -}} + {{- $_ := set $serviceValues "primary" true -}} + {{- end -}} + {{- $_ := set .Values.service "codeserver" $serviceValues -}} + {{- end -}} + + {{/* Add the code-server ingress */}} + {{- if .Values.addons.codeserver.ingress.enabled -}} + {{- $ingressValues := .Values.addons.codeserver.ingress -}} + {{- $_ := set $ingressValues "nameOverride" "codeserver" -}} + + {{/* Determine the target service name & port */}} + {{- $svcName := printf "%v-codeserver" (include "tc.v1.common.names.fullname" .) -}} + {{- $svcPort := .Values.addons.codeserver.service.ports.codeserver.port -}} + {{- range $_, $host := $ingressValues.hosts -}} + {{- $_ := set (index $host.paths 0) "service" (dict "name" $svcName "port" $svcPort) -}} + {{- end -}} + {{- $_ := set $ "ObjectValues" (dict "ingress" $ingressValues) -}} + {{- include "tc.v1.common.class.ingress" $ -}} + {{- $_ := unset $ "ObjectValues" -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/code-server/_container.tpl b/helm-charts/dashy/charts/common/templates/addons/code-server/_container.tpl new file mode 100644 index 0000000..a66572d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/code-server/_container.tpl @@ -0,0 +1,46 @@ +{{/* +The code-server sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.codeserver.container" -}} +enabled: true +probes: + liveness: + enabled: true + port: {{ .Values.addons.codeserver.service.ports.codeserver.port }} + path: "/" + readiness: + enabled: true + port: {{ .Values.addons.codeserver.service.ports.codeserver.port }} + path: "/" + startup: + enabled: true + port: {{ .Values.addons.codeserver.service.ports.codeserver.port }} + path: "/" +imageSelector: "codeserverImage" +imagePullPolicy: {{ .Values.codeserverImage.pullPolicy }} +securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false +env: +{{- range $envList := .Values.addons.codeserver.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else }} + {{- fail "Please specify name/value for codeserver environment variable" -}} + {{- end -}} +{{- end -}} +{{- with .Values.addons.codeserver.env -}} +{{- range $k, $v := . }} + {{ $k }}: {{ $v | quote }} +{{- end -}} +{{- end }} +args: +{{- range .Values.addons.codeserver.args }} +- {{ . | quote }} +{{- end }} +- "--port" +- "{{ .Values.addons.codeserver.service.ports.codeserver.port }}" +- {{ .Values.addons.codeserver.workingDir | default "/" }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/netshoot/_container.tpl b/helm-charts/dashy/charts/common/templates/addons/netshoot/_container.tpl new file mode 100644 index 0000000..bfc954f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/netshoot/_container.tpl @@ -0,0 +1,44 @@ +{{/* +The code-server sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.netshoot.container" -}} +enabled: true +command: + - /bin/sh + - -c + - sleep infinity +probes: + liveness: + enabled: false + readiness: + enabled: false + startup: + enabled: false +imageSelector: "netshootImage" +securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false + capabilities: + add: + - NET_ADMIN + - NET_RAW +env: +{{- range $envList := $.Values.addons.netshoot.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else }} + {{- fail "Please specify name/value for netshoot environment variable" -}} + {{- end -}} +{{- end -}} +{{- with $.Values.addons.netshoot.env -}} +{{- range $k, $v := . }} + {{ $k }}: {{ $v | quote }} +{{- end -}} +{{- end }} +args: +{{- range $.Values.addons.netshoot.args }} +- {{ . | quote }} +{{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/netshoot/_netshoot.tpl b/helm-charts/dashy/charts/common/templates/addons/netshoot/_netshoot.tpl new file mode 100644 index 0000000..fe75c80 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/netshoot/_netshoot.tpl @@ -0,0 +1,15 @@ +{{/* +Template to render code-server addon +It will include / inject the required templates based on the given values. +*/}} +{{- define "tc.v1.common.addon.netshoot" -}} +{{- $targetSelector := "main" -}} +{{- if .Values.addons.netshoot.enabled -}} + {{/* Append the code-server container to the workloads */}} + {{- $container := include "tc.v1.common.addon.netshoot.container" . | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload $targetSelector -}} + {{- $_ := set $workload.podSpec.containers "netshoot" $container -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_configmap.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_configmap.tpl new file mode 100644 index 0000000..4b417a6 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_configmap.tpl @@ -0,0 +1,16 @@ +{{/* +The VPN config and scripts to be included. +*/}} +{{- define "tc.v1.common.addon.vpn.configmap" -}} +enabled: true +data: +{{- with .Values.addons.vpn.scripts.up }} + up.sh: |- + {{- . | nindent 4 }} +{{- end -}} + +{{- with .Values.addons.vpn.scripts.down }} + down.sh: |- + {{- . | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_gluetunContainer.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_gluetunContainer.tpl new file mode 100644 index 0000000..59e3a4f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_gluetunContainer.tpl @@ -0,0 +1,64 @@ +{{/* +The gluetun sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.vpn.gluetun.container" -}} +enabled: true +imageSelector: gluetunImage +probes: +{{- if $.Values.addons.vpn.livenessProbe }} + liveness: + {{- toYaml . | nindent 2 }} +{{- else }} + liveness: + enabled: false +{{- end }} + readiness: + enabled: false + startup: + enabled: false +securityContext: + runAsUser: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false + runAsGroup: 568 + capabilities: + add: + - NET_ADMIN + - NET_RAW + - MKNOD + - SYS_MODULE + +env: + DNS_KEEP_NAMESERVER: "on" + DOT: "off" +{{- if $.Values.addons.vpn.killSwitch }} +{{- $excludednetworks := ( printf "%v,%v" $.Values.chartContext.podCIDR $.Values.chartContext.svcCIDR ) -}} +{{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}} + {{- $excludednetworks = ( printf "%v,%v" $excludednetworks . ) -}} +{{- end }} +{{- range $.Values.addons.vpn.excludedNetworks_IPv6 -}} + {{- $excludednetworksv6 = ( printf "%v,%v" $excludednetworks . ) -}} +{{- end }} + FIREWALL: "on" + FIREWALL_OUTBOUND_SUBNETS: {{ $excludednetworks | quote }} +{{- else }} + FIREWALL: "off" +{{- end }} + +{{- with $.Values.addons.vpn.env }} + {{- . | toYaml | nindent 2 }} +{{- end -}} + +{{- range $envList := $.Values.addons.vpn.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else -}} + {{- fail "Please specify name/value for VPN environment variable" -}} + {{- end -}} +{{- end -}} + +{{- with $.Values.addons.vpn.args }} +args: + {{- . | toYaml | nindent 2 }} +{{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_openvpnContainer.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_openvpnContainer.tpl new file mode 100644 index 0000000..26c881a --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_openvpnContainer.tpl @@ -0,0 +1,73 @@ +{{/* +The gluetun sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.vpn.openvpn.container" -}} +enabled: true +imageSelector: openvpnImage +probes: +{{- if $.Values.addons.vpn.livenessProbe }} + liveness: + {{- toYaml . | nindent 2 }} +{{- else }} + liveness: + enabled: false +{{- end }} + readiness: + enabled: false + startup: + enabled: false +securityContext: + runAsUser: 0 + runAsGroup: 0 + capabilities: + add: + - NET_ADMIN + - NET_RAW + - MKNOD + - SYS_MODULE + +env: +{{- with $.Values.addons.vpn.env }} + {{- . | toYaml | nindent 2 }} +{{- end }} + {{- if and $.Values.addons.vpn.openvpn.username $.Values.addons.vpn.openvpn.password }} + VPN_AUTH: {{ (printf "%v;%v" $.Values.addons.vpn.openvpn.username $.Values.addons.vpn.openvpn.password) }} + {{- end -}} +{{- if $.Values.addons.vpn.killSwitch }} +{{- $ipv4list := $.Values.addons.vpn.excludedNetworks_IPv4 }} + +{{- if $.Values.chartContext.podCIDR }} +{{- $ipv4list = append $ipv4list $.Values.chartContext.podCIDR }} +{{- end }} +{{- if $.Values.chartContext.svcCIDR }} +{{- $ipv4list = append $ipv4list $.Values.chartContext.svcCIDR }} +{{- end }} + + FIREWALL: "ON" + {{- range $index, $value := $ipv4list }} + ROUTE_{{ add $index 1 }}: {{ $value | quote }} + {{- end }} +{{- if $.Values.addons.vpn.excludedNetworks_IPv6 }} + {{- $excludednetworksv6 := "" -}} + {{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}} + {{- $excludednetworksv6 = ( printf "%v;%v" $excludednetworksv6 . ) -}} + {{- end }} + {{- range $index, $value := $.Values.addons.vpn.excludedNetworks_IPv6 }} + ROUTE6_{{ add $index 1 }}: {{ $value | quote }} + {{- end }} +{{- end }} +{{- end -}} + +{{- range $envList := $.Values.addons.vpn.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else -}} + {{- fail "Please specify name/value for VPN environment variable" -}} + {{- end -}} +{{- end -}} + +{{- with $.Values.addons.vpn.args }} +args: + {{- . | toYaml | nindent 2 }} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_secret.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_secret.tpl new file mode 100644 index 0000000..b46a5d3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_secret.tpl @@ -0,0 +1,9 @@ +{{/* +The OpenVPN config secret to be included. +*/}} +{{- define "tc.v1.common.addon.vpn.secret" -}} +enabled: true +data: + vpn.conf: |- + {{- .Values.addons.vpn.config | nindent 4 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_tailscaleContainer.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_tailscaleContainer.tpl new file mode 100644 index 0000000..50998d0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_tailscaleContainer.tpl @@ -0,0 +1,87 @@ +{{/* +The Tailscale sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.vpn.tailscale.container" -}} +enabled: true +imageSelector: "tailscaleImage" +probes: +{{- if $.Values.addons.vpn.livenessProbe }} + liveness: + {{- toYaml . | nindent 2 }} +{{- else }} + liveness: + enabled: false +{{- end }} + readiness: + enabled: false + startup: + enabled: false +command: + - /usr/local/bin/containerboot +securityContext: + {{- if $.Values.addons.vpn.tailscale.userspace }} + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: false + readOnlyRootFilesystem: true + {{- else }} + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: true + readOnlyRootFilesystem: false + {{- end }} + capabilities: + add: + - NET_ADMIN + - NET_RAW + +{{/* +Set KUBE_SECRET to empty string to force tailscale +to use the filesystem for state tracking. +With secret for state tracking you can't always +know if the app that uses this sidecard will +use a custom ServiceAccount and will lead to falure. +*/}} +env: + TS_KUBE_SECRET: "" + TS_SOCKET: /var/run/tailscale/tailscaled.sock + TS_STATE_DIR: /var/lib/tailscale/state + TS_AUTH_ONCE: {{ $.Values.addons.vpn.tailscale.auth_once | quote }} + TS_USERSPACE: {{ $.Values.addons.vpn.tailscale.userspace | quote }} + TS_ACCEPT_DNS: {{ $.Values.addons.vpn.tailscale.accept_dns | quote }} + {{- with $.Values.addons.vpn.tailscale.outbound_http_proxy_listen }} + TS_OUTBOUND_HTTP_PROXY_LISTEN: {{ . }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.routes }} + TS_ROUTES: {{ . }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.dest_ip }} + TS_DEST_IP: {{ . }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.sock5_server }} + TS_SOCKS5_SERVER: {{ . }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.extra_args }} + TS_EXTRA_ARGS: {{ . | quote }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.daemon_extra_args }} + TS_TAILSCALED_EXTRA_ARGS: {{ . | quote }} + {{- end -}} + {{- with $.Values.addons.vpn.tailscale.authkey }} + TS_AUTH_KEY: {{ . }} + {{- end }} + +{{- range $envList := $.Values.addons.vpn.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else -}} + {{- fail "Please specify name/value for VPN environment variable" -}} + {{- end -}} +{{- end -}} + +{{- with $.Values.addons.vpn.env -}} + {{- range $k, $v := . }} + {{ $k }}: {{ $v | quote }} + {{- end -}} +{{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_volume.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_volume.tpl new file mode 100644 index 0000000..b6a8f1a --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_volume.tpl @@ -0,0 +1,112 @@ +{{/* +The volume (referencing VPN scripts) to be inserted into persistence. +*/}} +{{- define "tc.v1.common.addon.vpn.volume.scripts" -}} +{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }} +enabled: true +type: configmap +objectName: vpnscripts +expandObjectName: false +defaultMode: "0777" +items: +{{- if .Values.addons.vpn.scripts.up }} +- key: up.sh + path: up.sh +{{- end -}} +{{- if .Values.addons.vpn.scripts.down }} +- key: down.sh + path: down.sh +{{- end }} +targetSelector: + {{- range .Values.addons.vpn.targetSelector }} + {{ . }}: + vpn: + mountPath: {{ $basePath }} + {{- end -}} +{{- end -}} + +{{/* +The volume (referencing VPN config) to be inserted into persistence. +*/}} +{{- define "tc.v1.common.addon.vpn.volume.config" -}} +{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }} +{{- $mountPath := $basePath }} + +enabled: true +{{- if or .Values.addons.vpn.config .Values.addons.vpn.existingSecret }} +type: secret +defaultMode: "0777" +items: + - key: vpn.conf + path: vpn.conf +{{- if .Values.addons.vpn.existingSecret }} +objectName: {{ .Values.addons.vpn.existingSecret }} +expandObjectName: false +{{- else }} +objectName: vpnconfig +expandObjectName: true +{{- end -}} +{{- else }} +{{- $mountPath = (printf "%s/vpn.conf" $basePath) }} +type: hostPath +hostPath: {{ .Values.addons.vpn.configFile | default "/vpn" }} +hostPathType: "File" +autoPermissions: + enabled: true + chown: true + user: 568 + group: 568 +{{- end }} +targetSelector: + {{- range .Values.addons.vpn.targetSelector }} + {{ . }}: + vpn: + mountPath: {{ $mountPath }} + {{- end -}} +{{- end -}} + +{{/* +The volume (referencing VPN config folder) to be inserted into persistence. +*/}} +{{- define "tc.v1.common.addon.vpn.volume.folder" -}} +{{- $basePath := (include "tc.v1.common.addon.vpn.volume.basePath" .) }} +enabled: true +type: hostPath +hostPath: {{ .Values.addons.vpn.configFolder | quote }} +autoPermissions: + enabled: true + chown: true + user: 568 + group: 568 +targetSelector: + {{- range .Values.addons.vpn.targetSelector }} + {{ . }}: + vpn: + mountPath: {{ $basePath }} + {{- end -}} +{{- end -}} + + +{{/* +The empty tailscale folder +*/}} +{{- define "tc.v1.common.addon.vpn.volume.tailscale" -}} +enabled: true +type: emptyDir +targetSelector: + {{- range .Values.addons.vpn.targetSelector }} + {{ . }}: + tailscale: + mountPath: /var/lib/tailscale + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.addon.vpn.volume.basePath" -}} + {{- $basePath := "/vpn" -}} {{/* Base Path for OVPN */}} + {{- if eq .Values.addons.vpn.type "wireguard" -}} + {{- $basePath = "/etc/wireguard" -}} {{/* Base Path for Wireguard */}} + {{- else if eq .Values.addons.vpn.type "gluetun" -}} + {{- $basePath = "/gluetun" -}} {{/* Base Path for Gluetun */}} + {{- end -}} + {{- $basePath -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_vpn.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_vpn.tpl new file mode 100644 index 0000000..62aad34 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_vpn.tpl @@ -0,0 +1,94 @@ +{{/* +Template to render VPN addon +It will include / inject the required templates based on the given values. +*/}} +{{- define "tc.v1.common.addon.vpn" -}} +{{- if ne "disabled" .Values.addons.vpn.type -}} + + {{- if .Values.addons.vpn.config -}} + {{/* Append the vpn config secret to the secrets */}} + {{- $secret := include "tc.v1.common.addon.vpn.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret "vpnconfig" $secret -}} + {{- end -}} + {{- end }} + + {{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down -}} + {{/* Append the vpn up/down scripts to the configmaps */}} + {{- $configmap := include "tc.v1.common.addon.vpn.configmap" . | fromYaml -}} + {{- if $configmap -}} + {{- $_ := set .Values.configmap "vpnscripts" $configmap -}} + {{- end -}} + {{- end }} + + {{- if or .Values.addons.vpn.configFile .Values.addons.vpn.config .Values.addons.vpn.existingSecret -}} + {{/* Append the vpn config to the persistence */}} + {{- $configper := include "tc.v1.common.addon.vpn.volume.config" . | fromYaml -}} + {{- if $configper -}} + {{- $_ := set .Values.persistence "vpnconfig" $configper -}} + {{- end -}} + {{- end -}} + + {{- if or .Values.addons.vpn.scripts.up .Values.addons.vpn.scripts.down -}} + {{/* Append the vpn scripts to the persistence */}} + {{- $scriptsper := include "tc.v1.common.addon.vpn.volume.scripts" . | fromYaml -}} + {{- if $scriptsper -}} + {{- $_ := set .Values.persistence "vpnscripts" $scriptsper -}} + {{- end -}} + {{- end -}} + + {{- if .Values.addons.vpn.configFolder -}} + {{/* Append the vpn folder to the persistence */}} + {{- $folderper := include "tc.v1.common.addon.vpn.volume.folder" . | fromYaml -}} + {{- if $folderper -}} + {{- $_ := set .Values.persistence "vpnfolder" $folderper -}} + {{- end -}} + {{- end -}} + + {{/* Ensure target Selector defaults to main pod even if unset */}} + {{- $targetSelector := list "main" -}} + {{- if $.Values.addons.codeserver.targetSelector -}} + {{- $targetSelector = $.Values.addons.codeserver.targetSelector -}} + {{- end -}} + + {{/* Append the vpn container to the containers */}} + {{- range $targetSelector -}} + {{- if eq "gluetun" $.Values.addons.vpn.type -}} + {{- $container := include "tc.v1.common.addon.vpn.gluetun.container" $ | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload . -}} + {{- $_ := set $workload.podSpec.containers "vpn" $container -}} + {{- end -}} + {{- else if eq "tailscale" $.Values.addons.vpn.type -}} + {{/* FIXME: https://github.com/tailscale/tailscale/issues/8188 */}} + {{- $_ := set $.Values.podOptions "automountServiceAccountToken" true -}} + {{- $container := include "tc.v1.common.addon.vpn.tailscale.container" $ | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload . -}} + {{- $_ := set $workload.podSpec.containers "tailscale" $container -}} + {{- end -}} + {{- else if eq "openvpn" $.Values.addons.vpn.type -}} + {{- $container := include "tc.v1.common.addon.vpn.openvpn.container" $ | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload . -}} + {{- $_ := set $workload.podSpec.containers "vpn" $container -}} + {{- end -}} + {{- else if eq "wireguard" $.Values.addons.vpn.type -}} + {{- $container := include "tc.v1.common.addon.vpn.wireguard.container" $ | fromYaml -}} + {{- if $container -}} + {{- $workload := get $.Values.workload . -}} + {{- $_ := set $workload.podSpec.containers "vpn" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if eq "tailscale" $.Values.addons.vpn.type -}} + {{/* Append the empty tailscale folder to the persistence */}} + {{- $tailscaledir := include "tc.v1.common.addon.vpn.volume.tailscale" . | fromYaml -}} + {{- if $tailscaledir -}} + {{- $_ := set .Values.persistence "tailscalestate" $tailscaledir -}} + {{- end -}} + {{- end -}} + +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/addons/vpn/_wireguardContainer.tpl b/helm-charts/dashy/charts/common/templates/addons/vpn/_wireguardContainer.tpl new file mode 100644 index 0000000..3fd7eb7 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/addons/vpn/_wireguardContainer.tpl @@ -0,0 +1,66 @@ +{{/* +The gluetun sidecar container to be inserted. +*/}} +{{- define "tc.v1.common.addon.vpn.wireguard.container" -}} +enabled: true +imageSelector: wireguardImage +probes: +{{- if $.Values.addons.vpn.livenessProbe }} + liveness: + {{- toYaml . | nindent 2 }} +{{- else }} + liveness: + enabled: false +{{- end }} + readiness: + enabled: false + startup: + enabled: false +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: false + allowPrivilegeEscalation: true + capabilities: + add: + - AUDIT_WRITE + - NET_ADMIN + - SETUID + - SETGID + - SYS_MODULE + +env: +{{- with $.Values.addons.vpn.env }} + {{- . | toYaml | nindent 2 }} +{{- end }} + SEPARATOR: ";" + IPTABLES_BACKEND: "nft" +{{- if $.Values.addons.vpn.killSwitch }} + KILLSWITCH: "true" + {{- $excludednetworksv4 := ( printf "%v;%v" $.Values.chartContext.podCIDR $.Values.chartContext.svcCIDR ) -}} + {{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}} + {{- $excludednetworksv4 = ( printf "%v;%v" $excludednetworksv4 . ) -}} + {{- end }} + KILLSWITCH_EXCLUDEDNETWORKS_IPV4: {{ $excludednetworksv4 | quote }} +{{- if $.Values.addons.vpn.excludedNetworks_IPv6 -}} + {{- $excludednetworksv6 := "" -}} + {{- range $.Values.addons.vpn.excludedNetworks_IPv4 -}} + {{- $excludednetworksv6 = ( printf "%v;%v" $excludednetworksv6 . ) -}} + {{- end }} + KILLSWITCH_EXCLUDEDNETWORKS_IPV6: {{ $.Values.addons.vpn.excludedNetworks_IPv6 | quote }} +{{- end -}} +{{- end -}} + +{{- range $envList := $.Values.addons.vpn.envList -}} + {{- if and $envList.name $envList.value }} + {{ $envList.name }}: {{ $envList.value | quote }} + {{- else -}} + {{- fail "Please specify name/value for VPN environment variable" -}} + {{- end -}} +{{- end -}} + +{{- with $.Values.addons.vpn.args }} +args: + {{- . | toYaml | nindent 2 }} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_certificate.tpl b/helm-charts/dashy/charts/common/templates/class/_certificate.tpl new file mode 100644 index 0000000..5178dc2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_certificate.tpl @@ -0,0 +1,45 @@ +{{/* +This template serves as a blueprint for all Cert-Manager Certificate objects that are created +within the common library. +*/}} +{{- define "tc.v1.common.class.certificate" -}} +{{- $root := .root -}} +{{- $name := .name -}} +{{- $hosts := .hosts -}} +{{- $certificateIssuer := .certificateIssuer -}} +{{- $certificateSecretTemplate := .secretTemplate }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.cert-manager.certificate.apiVersion" $ }} +kind: Certificate +metadata: + name: {{ $name }} + namespace: {{ $root.Values.namespace | default $root.Values.global.namespace | default $root.Release.Namespace }} +spec: + secretName: {{ $name }} + dnsNames: + {{- range $hosts }} + - {{ tpl . $root | quote }} + {{- end }} + privateKey: + algorithm: ECDSA + size: 256 + rotationPolicy: Always + issuerRef: + name: {{ tpl $certificateIssuer $root | quote }} + kind: ClusterIssuer + group: cert-manager.io + {{- if $certificateSecretTemplate }} + secretTemplate: + {{- $labels := (mustMerge ($certificateSecretTemplate.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $root | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $root "labels" $labels) | trim) }} + labels: + {{- . | nindent 6 }} + {{- end -}} + {{- $annotations := (mustMerge ($certificateSecretTemplate.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $root | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $root "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 6 }} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_cnpgCluster.tpl b/helm-charts/dashy/charts/common/templates/class/_cnpgCluster.tpl new file mode 100644 index 0000000..59b65f3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_cnpgCluster.tpl @@ -0,0 +1,83 @@ +{{- define "tc.v1.common.class.cnpg.cluster" -}} + {{- $values := .Values.cnpg -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.cnpg -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $cnpgClusterName := $values.name -}} + {{- $cnpgClusterLabels := $values.labels -}} + {{- $cnpgClusterAnnotations := $values.annotations -}} + {{- $hibernation := "off" -}} + {{- if or $values.hibernate (include "tc.v1.common.lib.util.stopAll" $) -}} + {{- $hibernation = "on" -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.cnpg.cluster.apiVersion" $ }} +kind: Cluster +metadata: + name: {{ $cnpgClusterName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($cnpgClusterLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) }} + labels: + cnpg.io/reload: "on" + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + {{- . | nindent 4 }} + {{- end }} + {{- $annotations := (mustMerge ($cnpgClusterAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) }} + annotations: + cnpg.io/hibernation: {{ $hibernation | quote }} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + {{- . | nindent 4 }} + {{- end }} +spec: + instances: {{ $values.instances | default 2 }} + + bootstrap: + initdb: + database: {{ $values.database | default "app" }} + owner: {{ $values.user | default "app" }} + secret: + name: {{ $cnpgClusterName }}-user + + primaryUpdateStrategy: {{ $values.primaryUpdateStrategy | default "unsupervised" }} + + storage: + pvcTemplate: + {{- with (include "tc.v1.common.lib.storage.storageClassName" ( dict "rootCtx" $ "objectData" $values.storage )) | trim }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ tpl ($values.storage.walsize | default $.Values.fallbackDefaults.vctSize) $ | quote }} + + walStorage: + pvcTemplate: + {{- with (include "tc.v1.common.lib.storage.storageClassName" ( dict "rootCtx" $ "objectData" $values.storage )) | trim }} + storageClassName: {{ . }} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ tpl ($values.storage.walsize | default $.Values.fallbackDefaults.vctSize) $ | quote }} + + monitoring: + enablePodMonitor: {{ $values.monitoring.enablePodMonitor | default true }} + + nodeMaintenanceWindow: + inProgress: false + reusePVC: true + + {{- with (include "tc.v1.common.lib.container.resources" (dict "rootCtx" $ "objectData" $values) | trim) }} + resources: + {{- . | nindent 4 }} + {{- end }} + + postgresql: + {{- tpl ( $values.postgresql | toYaml ) $ | nindent 4 }} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_cnpgPooler.tpl b/helm-charts/dashy/charts/common/templates/class/_cnpgPooler.tpl new file mode 100644 index 0000000..8a7e766 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_cnpgPooler.tpl @@ -0,0 +1,35 @@ +{{- define "tc.v1.common.class.cnpg.pooler" -}} + {{- $values := .Values.cnpg -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.cnpg -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $cnpgClusterName := $values.name -}} + {{- $cnpgName := $values.cnpgName -}} + {{- $cnpgPoolerName := $values.poolerName -}} + {{- $cnpgClusterLabels := $values.labels -}} + {{- $cnpgClusterAnnotations := $values.annotations -}} + {{- $instances := $values.pooler.instances | default 2 -}} + {{- if or $values.hibernate (include "tc.v1.common.lib.util.stopAll" $) -}} + {{- $instances = 0 -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.cnpg.pooler.apiVersion" $ }} +kind: Pooler +metadata: + name: {{ printf "%v-%v" $cnpgClusterName $values.pooler.type }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} +spec: + cluster: + name: {{ $cnpgClusterName }} + instances: {{ $instances }} + type: {{ $values.pooler.type }} + pgbouncer: + poolMode: session + parameters: + max_client_conn: "1000" + default_pool_size: "10" + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_configmap.tpl b/helm-charts/dashy/charts/common/templates/class/_configmap.tpl new file mode 100644 index 0000000..0d40e1d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_configmap.tpl @@ -0,0 +1,37 @@ +{{/* Configmap Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.configmap" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the configmap. + labels: The labels of the configmap. + annotations: The annotations of the configmap. + data: The data of the configmap. + namespace: The namespace of the configmap. (Optional) +*/}} + +{{- define "tc.v1.common.class.configmap" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Configmap") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +data: + {{- tpl (toYaml $objectData.data) $rootCtx | nindent 2 }} + {{/* This comment is here to add a new line */}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_cronjob.tpl b/helm-charts/dashy/charts/common/templates/class/_cronjob.tpl new file mode 100644 index 0000000..3efcc58 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_cronjob.tpl @@ -0,0 +1,52 @@ +{{/* CronJob Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.cronjob" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The object data to be used to render the CronJob. +*/}} + +{{- define "tc.v1.common.class.cronjob" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- include "tc.v1.common.lib.workload.cronjobValidation" (dict "objectData" $objectData) }} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "CronJob") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- include "tc.v1.common.lib.workload.cronjobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }} + template: + metadata: + {{- $labels := (mustMerge ($objectData.podSpec.labels | default dict) + (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.podLabels" $rootCtx | 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) }} + labels: + {{- . | nindent 12 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict) + (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) + (include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 12 }} + {{- end }} + spec: + {{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 10 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_daemonset.tpl b/helm-charts/dashy/charts/common/templates/class/_daemonset.tpl new file mode 100644 index 0000000..4bfd2af --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_daemonset.tpl @@ -0,0 +1,55 @@ +{{/* DaemonSet Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The object data to be used to render the DaemonSet. +*/}} + +{{- define "tc.v1.common.class.daemonset" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- include "tc.v1.common.lib.workload.daemonsetValidation" (dict "objectData" $objectData) }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "DaemonSet") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- include "tc.v1.common.lib.workload.daemonsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }} + selector: + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }} + template: + metadata: + {{- $labels := (mustMerge ($objectData.podSpec.labels | default dict) + (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.podLabels" $rootCtx | 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) }} + labels: + {{- . | nindent 8 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict) + (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) + (include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 8 }} + {{- end }} + spec: + {{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_deployment.tpl b/helm-charts/dashy/charts/common/templates/class/_deployment.tpl new file mode 100644 index 0000000..3238a5c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_deployment.tpl @@ -0,0 +1,55 @@ +{{/* Deployment Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The object data to be used to render the Deployment. +*/}} + +{{- define "tc.v1.common.class.deployment" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- include "tc.v1.common.lib.workload.deploymentValidation" (dict "objectData" $objectData) }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Deployment") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- include "tc.v1.common.lib.workload.deploymentSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }} + selector: + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }} + template: + metadata: + {{- $labels := (mustMerge ($objectData.podSpec.labels | default dict) + (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.podLabels" $rootCtx | 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) }} + labels: + {{- . | nindent 8 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict) + (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) + (include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 8 }} + {{- end }} + spec: + {{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_endpoint.tpl b/helm-charts/dashy/charts/common/templates/class/_endpoint.tpl new file mode 100644 index 0000000..29862e9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_endpoint.tpl @@ -0,0 +1,33 @@ +{{/* Endpoint Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.endpoint" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The service data, that will be used to render the Service object. +*/}} + +{{- define "tc.v1.common.class.endpoint" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: v1 +kind: Endpoints +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Endpoint") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +subsets: + - addresses: + {{- include "tc.v1.common.lib.endpoint.addresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} + ports: + {{- include "tc.v1.common.lib.endpoint.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_endpointSlice.tpl b/helm-charts/dashy/charts/common/templates/class/_endpointSlice.tpl new file mode 100644 index 0000000..0a29dce --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_endpointSlice.tpl @@ -0,0 +1,41 @@ +{{/* EndpointSlice Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.endpointSlice" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The service data, that will be used to render the Service object. +*/}} + +{{- define "tc.v1.common.class.endpointSlice" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $addressType := $objectData.addressType | default "IPv4" -}} + {{- if $objectData.addressType -}} + {{- $addressType = tpl $addressType $rootCtx -}} + {{- end }} + +--- +apiVersion: discovery.k8s.io/v1 +kind: EndpointSlice +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Endpoint Slice") }} + {{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml)) -}} + {{- $_ := set $labels "kubernetes.io/service-name" $objectData.name -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $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: + {{- . | nindent 4 }} + {{- end }} +addressType: {{ $addressType }} +ports: +{{- include "tc.v1.common.lib.endpointslice.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} +endpoints: +{{- include "tc.v1.common.lib.endpointslice.endpoints" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_horizontalPodAutoscaler.tpl b/helm-charts/dashy/charts/common/templates/class/_horizontalPodAutoscaler.tpl new file mode 100644 index 0000000..92abf3f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_horizontalPodAutoscaler.tpl @@ -0,0 +1,58 @@ +{{/* +This template serves as a blueprint for horizontal pod autoscaler objects that are created +using the common library. +*/}} +{{- define "tc.v1.common.class.hpa" -}} + {{- $targetName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $hpaName := $fullName -}} + {{- $values := .Values.hpa -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.hpa -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $hpaLabels := $values.labels -}} + {{- $hpaAnnotations := $values.annotations -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $hpaName = printf "%v-%v" $hpaName $values.nameOverride -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.hpa.apiVersion" $ }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ $hpaName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($hpaLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (mustMerge ($hpaAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end -}} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ $values.targetKind | default ( include "tc.v1.common.names.controllerType" . ) }} + name: {{ $values.target | default $targetName }} + minReplicas: {{ $values.minReplicas | default 1 }} + maxReplicas: {{ $values.maxReplicas | default 3 }} + metrics: + {{- if $values.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ $values.targetCPUUtilizationPercentage }} + {{- end -}} + {{- if $values.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ $values.targetMemoryUtilizationPercentage }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_ingress.tpl b/helm-charts/dashy/charts/common/templates/class/_ingress.tpl new file mode 100644 index 0000000..e5f16b9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_ingress.tpl @@ -0,0 +1,157 @@ +{{/* +This template serves as a blueprint for all Ingress objects that are created +within the common library. +*/}} +{{- 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 -}} + {{- 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 -}} + {{- 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 }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.ingress.apiVersion" $ }} +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) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (mustMerge ($ingressAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) }} + 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 -}} + {{- end }} + rules: + {{- range $values.hosts }} + - host: {{ tpl .host $ | quote }} + http: + paths: + {{- range .paths -}} + {{- $service := $defaultServiceName -}} + {{- $port := $defaultServicePort.port -}} + {{- if .service -}} + {{- $service = default $service .service.name -}} + {{- $port = default $port .service.port -}} + {{- end }} + - path: {{ tpl .path $ | quote }} + pathType: {{ default "Prefix" .pathType }} + backend: + service: + name: {{ $service }} + port: + number: {{ $port }} + {{- end -}} + {{- end -}} + + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_job.tpl b/helm-charts/dashy/charts/common/templates/class/_job.tpl new file mode 100644 index 0000000..e6630cf --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_job.tpl @@ -0,0 +1,52 @@ +{{/* Job Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.job" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The object data to be used to render the Job. +*/}} + +{{- define "tc.v1.common.class.job" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- include "tc.v1.common.lib.workload.jobValidation" (dict "objectData" $objectData) }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Job") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- include "tc.v1.common.lib.workload.jobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }} + template: + metadata: + {{- $labels := (mustMerge ($objectData.podSpec.labels | default dict) + (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.podLabels" $rootCtx | 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) }} + labels: + {{- . | nindent 8 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict) + (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) + (include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 8 }} + {{- end }} + spec: + {{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_mutatingWebhookConfiguration.tpl b/helm-charts/dashy/charts/common/templates/class/_mutatingWebhookConfiguration.tpl new file mode 100644 index 0000000..2bcd6b9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_mutatingWebhookConfiguration.tpl @@ -0,0 +1,38 @@ +{{/* MutatingWebhookConfiguration Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.mutatingWebhookConfiguration" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the MutatingWebhookConfiguration. + labels: The labels of the MutatingWebhookConfiguration. + annotations: The annotations of the MutatingWebhookConfiguration. + data: The data of the MutatingWebhookConfiguration. + namespace: The namespace of the MutatingWebhookConfiguration. (Optional) +*/}} + +{{- define "tc.v1.common.class.mutatingWebhookConfiguration" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Webhook") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +webhooks: + {{- range $webhook := $objectData.webhooks -}} + {{- include "tc.v1.common.lib.webhook" (dict "webhook" $webhook "rootCtx" $rootCtx) | trim | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_networkAttachmentDefinition.tpl b/helm-charts/dashy/charts/common/templates/class/_networkAttachmentDefinition.tpl new file mode 100644 index 0000000..1c0364d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_networkAttachmentDefinition.tpl @@ -0,0 +1,35 @@ +{{/* Network Attachment Definition Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.networkAttachmentDefinition" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the Network Attachment Definition. + labels: The labels of the Network Attachment Definition. + annotations: The annotations of the Network Attachment Definition. + config: The config of the interface +*/}} + +{{- define "tc.v1.common.class.networkAttachmentDefinition" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Network Attachment Definition") }} + {{- $labels := (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) | default dict -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) | default dict -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + config: {{ $objectData.config | squote }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_networkPolicy.tpl b/helm-charts/dashy/charts/common/templates/class/_networkPolicy.tpl new file mode 100644 index 0000000..735ea2b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_networkPolicy.tpl @@ -0,0 +1,185 @@ +{{/* +Blueprint for the NetworkPolicy object +*/}} +{{- define "tc.v1.common.class.networkpolicy" -}} + {{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $networkPolicyName := $fullName -}} + {{- $values := .Values.networkPolicy -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.networkPolicy -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $networkpolicyLabels := $values.labels -}} + {{- $networkpolicyAnnotations := $values.annotations -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $networkPolicyName = printf "%v-%v" $networkPolicyName $values.nameOverride -}} + {{- end }} +--- +kind: NetworkPolicy +apiVersion: {{ include "tc.v1.common.capabilities.networkpolicy.apiVersion" $ }} +metadata: + name: {{ $networkPolicyName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($networkpolicyLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (mustMerge ($networkpolicyAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + podSelector: + {{- if $values.podSelector }} + {{- tpl (toYaml $values.podSelector) $ | nindent 4 }} + {{- else if $values.targetSelector }} + {{- $objectData := dict "targetSelector" $values.targetSelector }} + {{- $selectedPod := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $ "objectData" $objectData)) }} + {{- $selectedPodName := $selectedPod.shortName }} + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "pod" "objectName" $selectedPodName) | indent 8 }} + {{- else }} + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "" "objectName" "") | indent 8 }} + {{- end }} + + {{- if $values.policyType }} + {{- if eq $values.policyType "ingress" }} + policyTypes: ["Ingress"] + {{- else if eq $values.policyType "egress" }} + policyTypes: ["Egress"] + + {{- else if eq $values.policyType "ingress-egress" }} + policyTypes: ["Ingress", "Egress"] + {{- end -}} + {{- end -}} + + {{- if $values.egress }} + egress: + {{- range $values.egress }} + - to: + {{- range .to -}} + {{- $nss := false -}} + {{- $ipb := false -}} + {{- if .ipBlock -}} + {{- if .ipBlock.cidr -}} + {{- $ipb = true }} + - ipBlock: + cidr: {{ .ipBlock.cidr }} + {{- if .ipBlock.except }} + except: + {{- range .ipBlock.except }} + - {{ . }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if and ( .namespaceSelector ) ( not $ipb ) -}} + {{- if or ( .namespaceSelector.matchLabels ) ( .namespaceSelector.matchExpressions ) -}} + {{- $nss = true }} + - namespaceSelector: + {{- if .namespaceSelector.matchLabels }} + matchLabels: + {{- .namespaceSelector.matchLabels | toYaml | nindent 12 }} + {{- end -}} + {{- if .namespaceSelector.matchExpressions }} + matchExpressions: + {{- .namespaceSelector.matchExpressions | toYaml | nindent 12 }} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if and ( .podSelector ) ( not $ipb ) -}} + {{- if or ( .podSelector.matchLabels ) ( .podSelector.matchExpressions ) -}} + {{- if $nss }} + podSelector: + {{- else }} + - podSelector: + {{- end -}} + {{- if .podSelector.matchLabels }} + matchLabels: + {{- .podSelector.matchLabels | toYaml | nindent 12 }} + {{- end -}} + {{- if .podSelector.matchExpressions }} + matchExpressions: + {{- .podSelector.matchExpressions | toYaml | nindent 12 }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- with .ports }} + ports: + {{- . | toYaml | nindent 6 }} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if $values.ingress }} + ingress: + {{- range $values.ingress }} + - from: + {{- range .from -}} + {{- $nss := false -}} + {{- $ipb := false -}} + {{- if .ipBlock -}} + {{- if .ipBlock.cidr -}} + {{- $ipb = true }} + - ipBlock: + cidr: {{ .ipBlock.cidr }} + {{- if .ipBlock.except }} + except: + {{- range .ipBlock.except }} + - {{ . }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if and ( .namespaceSelector ) ( not $ipb ) -}} + {{- if or ( .namespaceSelector.matchLabels ) ( .namespaceSelector.matchExpressions ) -}} + {{- $nss = true }} + - namespaceSelector: + {{- if .namespaceSelector.matchLabels }} + matchLabels: + {{- .namespaceSelector.matchLabels | toYaml | nindent 12 }} + {{- end -}} + {{- if .namespaceSelector.matchExpressions }} + matchExpressions: + {{- .namespaceSelector.matchExpressions | toYaml | nindent 12 }} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if and ( .podSelector ) ( not $ipb ) -}} + {{- if or ( .podSelector.matchLabels ) ( .podSelector.matchExpressions ) -}} + {{- if $nss }} + podSelector: + {{- else }} + - podSelector: + {{- end }} + {{- if .podSelector.matchLabels }} + matchLabels: + {{- .podSelector.matchLabels | toYaml | nindent 12 }} + {{- end -}} + {{- if .podSelector.matchExpressions }} + matchExpressions: + {{- .podSelector.matchExpressions | toYaml | nindent 12 }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- with .ports }} + ports: + {{- . | toYaml | nindent 6 }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_podDisruptionBudget.tpl b/helm-charts/dashy/charts/common/templates/class/_podDisruptionBudget.tpl new file mode 100644 index 0000000..ae48bc5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_podDisruptionBudget.tpl @@ -0,0 +1,54 @@ +{{/* poddisruptionbudget Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.podDisruptionBudget" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the podDisruptionBudget. + labels: The labels of the podDisruptionBudget. + annotations: The annotations of the podDisruptionBudget. + data: The data of the podDisruptionBudget. + namespace: The namespace of the podDisruptionBudget. (Optional) +*/}} + +{{- define "tc.v1.common.class.podDisruptionBudget" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Pod Disruption Budget") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +data: + selector: + matchLabels: + {{- if $objectData.customLabels -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $objectData.customLabels) | trim) }} + {{- . | nindent 6 }} + {{- end -}} + {{- else -}} + {{- $selectedPod := fromJson (include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Pod Disruption Budget")) }} + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $selectedPod.shortName) | nindent 6 }} + {{- end -}} + {{- if hasKey $objectData "minAvailable" }} + minAvailable: {{ tpl (toString $objectData.minAvailable) $rootCtx }} + {{- end -}} + {{- if hasKey $objectData "maxUnavailable" }} + maxUnavailable: {{ tpl (toString $objectData.maxUnavailable) $rootCtx }} + {{- end -}} + {{- with $objectData.unhealthyPodEvictionPolicy }} + unhealthyPodEvictionPolicy: {{ tpl . $rootCtx }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_podMonitor.tpl b/helm-charts/dashy/charts/common/templates/class/_podMonitor.tpl new file mode 100644 index 0000000..907bb3b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_podMonitor.tpl @@ -0,0 +1,47 @@ +{{- define "tc.v1.common.class.podmonitor" -}} + {{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $podmonitorName := $fullName -}} + {{- $values := .Values.podmonitor -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.metrics -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $podmonitorLabels := $values.labels -}} + {{- $podmonitorAnnotations := $values.annotations -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $podmonitorName = printf "%v-%v" $podmonitorName $values.nameOverride -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.podmonitor.apiVersion" $ }} +kind: PodMonitor +metadata: + name: {{ $podmonitorName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($podmonitorLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end }} + {{- $annotations := (mustMerge ($podmonitorAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + jobLabel: app.kubernetes.io/name + selector: + {{- if $values.selector }} + {{- tpl (toYaml $values.selector) $ | nindent 4 }} + {{- else }} + {{- $objectData := dict "targetSelector" $values.targetSelector }} + {{- $selectedPod := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $ "objectData" $objectData)) }} + {{- $selectedPodName := $selectedPod.shortName }} + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "pod" "objectName" $selectedPodName) | indent 6 }} + {{- end }} + podMetricsEndpoints: + {{- tpl (toYaml $values.endpoints) $ | nindent 4 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_prometheusRule.tpl b/helm-charts/dashy/charts/common/templates/class/_prometheusRule.tpl new file mode 100644 index 0000000..34b0b47 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_prometheusRule.tpl @@ -0,0 +1,55 @@ +{{- define "tc.v1.common.class.prometheusrule" -}} + {{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $prometheusruleName := $fullName -}} + {{- $values := .Values.prometheusrule -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.metrics -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $prometheusruleLabels := $values.labels -}} + {{- $prometheusruleAnnotations := $values.annotations -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $prometheusruleName = printf "%v-%v" $prometheusruleName $values.nameOverride -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.prometheusrule.apiVersion" $ }} +kind: PrometheusRule +metadata: + name: {{ $prometheusruleName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($prometheusruleLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end }} + {{- $annotations := (mustMerge ($prometheusruleAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + groups: + {{- range $name, $groupValues := .groups }} + - name: {{ $prometheusruleName }}-{{ $name }} + rules: + {{- with $groupValues.rules }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $groupValues.additionalrules }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- range $id, $groupValues := .additionalgroups }} + - name: {{ $prometheusruleName }}-{{ if $groupValues.name }}{{ $groupValues.name }}{{ else }}{{ $id }}{{ end }} + rules: + {{- with $groupValues.rules }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with $groupValues.additionalrules }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_pvc.tpl b/helm-charts/dashy/charts/common/templates/class/_pvc.tpl new file mode 100644 index 0000000..b145101 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_pvc.tpl @@ -0,0 +1,57 @@ +{{/* PVC Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.pvc" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the PVC. + labels: The labels of the PVC. + annotations: The annotations of the PVC. +*/}} + +{{- define "tc.v1.common.class.pvc" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $pvcRetain := $rootCtx.Values.fallbackDefaults.pvcRetain -}} + {{- if (kindIs "bool" $objectData.retain) -}} + {{- $pvcRetain = $objectData.retain -}} + {{- end -}} + + {{- $pvcSize := $rootCtx.Values.fallbackDefaults.pvcSize -}} + {{- with $objectData.size -}} + {{- $pvcSize = tpl . $rootCtx -}} + {{- end }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Persistent Volume Claim") }} + {{- $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 ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}} + {{- if $pvcRetain -}} + {{- $_ := set $annotations "\"helm.sh/resource-policy\"" "keep" -}} + {{- end -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + accessModes: + {{- include "tc.v1.common.lib.pvc.accessModes" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "PVC") | trim | nindent 4 }} + resources: + requests: + storage: {{ $pvcSize }} + {{- with $objectData.volumeName }} + volumeName: {{ tpl . $rootCtx }} + {{- end -}} + {{- with (include "tc.v1.common.lib.storage.storageClassName" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "PVC") | trim) }} + storageClassName: {{ . }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_rbac.tpl b/helm-charts/dashy/charts/common/templates/class/_rbac.tpl new file mode 100644 index 0000000..d5f94a7 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_rbac.tpl @@ -0,0 +1,64 @@ +{{/* RBAC Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.rbac" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the rbac. + labels: The labels of the rbac. + annotations: The annotations of the rbac. + clusterWide: Whether the rbac is cluster wide or not. + rules: The rules of the rbac. + subjects: The subjects of the rbac. +*/}} + +{{- define "tc.v1.common.class.rbac" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }} +metadata: + name: {{ $objectData.name }} + {{- if not $objectData.clusterWide }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "RBAC") }} + {{- end }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +rules: + {{- include "tc.v1.common.lib.rbac.rules" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ ternary "ClusterRoleBinding" "RoleBinding" $objectData.clusterWide }} +metadata: + name: {{ $objectData.name }} + {{- if not $objectData.clusterWide }} + namespace: {{ $rootCtx.Release.Namespace }} + {{- end }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: {{ ternary "ClusterRole" "Role" $objectData.clusterWide }} + name: {{ $objectData.name }} +subjects: + {{- include "tc.v1.common.lib.rbac.serviceAccount" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} + {{- include "tc.v1.common.lib.rbac.subjects" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_route.tpl b/helm-charts/dashy/charts/common/templates/class/_route.tpl new file mode 100644 index 0000000..e9ef7e0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_route.tpl @@ -0,0 +1,87 @@ +{{/* +This template serves as a blueprint for all Route objects that are created +within the common library. +*/}} +{{- define "tc.v1.common.class.route" -}} +{{- $values := .Values.route -}} +{{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.route -}} + {{- $values = . -}} + {{- end -}} +{{- end -}} + + {{- $routeLabels := $values.labels -}} + {{- $routeAnnotations := $values.annotations -}} + +{{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} +{{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $fullName = printf "%v-%v" $fullName $values.nameOverride -}} +{{- end -}} +{{- $routeKind := $values.kind | default "HTTPRoute" -}} + +{{/* 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 )) }} + +--- +apiVersion: gateway.networking.k8s.io/v1alpha2 +{{- if and (ne $routeKind "GRPCRoute") (ne $routeKind "HTTPRoute") (ne $routeKind "TCPRoute") (ne $routeKind "TLSRoute") (ne $routeKind "UDPRoute") -}} + {{- fail (printf "Not a valid route kind (%s)" $routeKind) -}} +{{- end }} +kind: {{ $routeKind }} +metadata: + name: {{ $fullName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($routeLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (mustMerge ($routeAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) }} + annotations: + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + {{- . | nindent 4 }} + {{- end }} +spec: + parentRefs: + {{- range $values.parentRefs }} + - group: {{ default "gateway.networking.k8s.io" .group }} + kind: {{ default "Gateway" .kind }} + name: {{ required (printf "parentRef name is required for %v %v" $routeKind $fullName) .name }} + namespace: {{ required (printf "parentRef namespace is required for %v %v" $routeKind $fullName) .namespace }} + {{- if .sectionName }} + sectionName: {{ .sectionName | quote }} + {{- end }} + {{- end }} + {{- if and (ne $routeKind "TCPRoute") (ne $routeKind "UDPRoute") $values.hostnames }} + hostnames: + {{- with $values.hostnames }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} + rules: + {{- range $values.rules }} + - backendRefs: + {{- range .backendRefs }} + - group: {{ default "" .group | quote}} + kind: {{ default "Service" .kind }} + name: {{ default $defaultServiceName .name }} + namespace: {{ default $.Release.Namespace .namespace }} + port: {{ default $defaultServicePort.port .port }} + weight: {{ default 1 .weight }} + {{- end }} + {{- if (eq $routeKind "HTTPRoute") }} + {{- with .matches }} + matches: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm-charts/dashy/charts/common/templates/class/_secret.tpl b/helm-charts/dashy/charts/common/templates/class/_secret.tpl new file mode 100644 index 0000000..14b2f2a --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_secret.tpl @@ -0,0 +1,58 @@ +{{/* Secret Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the secret. + labels: The labels of the secret. + annotations: The annotations of the secret. + type: The type of the secret. + data: The data of the secret. + namespace: The namespace of the secret. (Optional) +*/}} + +{{- define "tc.v1.common.class.secret" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $secretType := "Opaque" -}} + + {{- if eq $objectData.type "certificate" -}} + {{- $secretType = "kubernetes.io/tls" -}} + {{- else if eq $objectData.type "imagePullSecret" -}} + {{- $secretType = "kubernetes.io/dockerconfigjson" -}} + {{- else if $objectData.type -}} + {{- $secretType = $objectData.type -}} + {{- end }} +--- +apiVersion: v1 +kind: Secret +type: {{ $secretType }} +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Secret") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end -}} + {{- if (mustHas $objectData.type (list "certificate" "imagePullSecret")) }} +data: + {{- if eq $objectData.type "certificate" }} + tls.crt: {{ $objectData.data.certificate | trim | b64enc }} + tls.key: {{ $objectData.data.privatekey | trim | b64enc }} + {{- else if eq $objectData.type "imagePullSecret" }} + .dockerconfigjson: {{ $objectData.data | trim | b64enc }} + {{- end -}} + {{- else }} +stringData: + {{- tpl (toYaml $objectData.data) $rootCtx | nindent 2 }} + {{/* This comment is here to add a new line */}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_service.tpl b/helm-charts/dashy/charts/common/templates/class/_service.tpl new file mode 100644 index 0000000..e1fd3d4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_service.tpl @@ -0,0 +1,115 @@ +{{/* Service Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.service" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The service data, that will be used to render the Service object. +*/}} + +{{- define "tc.v1.common.class.service" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $svcType := $objectData.type | default $rootCtx.Values.fallbackDefaults.serviceType -}} + + {{/* Init variables */}} + {{- $hasHTTPSPort := false -}} + {{- $hasHostPort := false -}} + {{- $hostNetwork := false -}} + {{- $podValues := dict -}} + + {{- range $portName, $port := $objectData.ports -}} + {{- if $port.enabled -}} + {{- if eq (tpl ($port.protocol | default "") $rootCtx) "https" -}} + {{- $hasHTTPSPort = true -}} + {{- end -}} + + {{- if and (hasKey $port "hostPort") $port.hostPort -}} + {{- $hasHostPort = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $specialTypes := (list "ExternalName" "ExternalIP") -}} + {{/* External Name / External IP does not rely on any pod values */}} + {{- if not (mustHas $svcType $specialTypes) -}} + {{/* Get Pod Values based on the selector (or the absence of it) */}} + {{- $podValues = fromJson (include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service")) -}} + + {{- if $podValues -}} + {{/* Get Pod hostNetwork configuration */}} + {{- $hostNetwork = include "tc.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $podValues) -}} + {{/* When hostNetwork is set on the pod, force ClusterIP, so services wont try to bind the same ports on the host */}} + {{- if or (and (kindIs "bool" $hostNetwork) $hostNetwork) (and (kindIs "string" $hostNetwork) (eq $hostNetwork "true")) -}} + {{- $svcType = "ClusterIP" -}} + {{- end -}} + {{- end -}} + + {{/* When hostPort is defined, force ClusterIP aswell */}} + {{- if $hasHostPort -}} + {{- $svcType = "ClusterIP" -}} + {{- end -}} + {{- end -}} + {{- $_ := set $objectData "type" $svcType }} + +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service") }} + {{- $labels := (mustMerge ($objectData.labels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "service" "objectName" $objectData.shortName) | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.annotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml)) -}} + {{- if eq $objectData.type "LoadBalancer" -}} + {{- include "tc.v1.common.lib.service.metalLBAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData "annotations" $annotations) -}} + {{- end -}} + {{- if $hasHTTPSPort -}} + {{- include "tc.v1.common.lib.service.traefikAnnotations" (dict "rootCtx" $rootCtx "annotations" $annotations) -}} + {{- end -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- if eq $objectData.type "ClusterIP" -}} + {{- include "tc.v1.common.lib.service.spec.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- else if eq $objectData.type "LoadBalancer" -}} + {{- include "tc.v1.common.lib.service.spec.loadBalancer" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- else if eq $objectData.type "NodePort" -}} + {{- include "tc.v1.common.lib.service.spec.nodePort" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- else if eq $objectData.type "ExternalName" -}} + {{- include "tc.v1.common.lib.service.spec.externalName" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- else if eq $objectData.type "ExternalIP" -}} + {{- include "tc.v1.common.lib.service.spec.externalIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- end -}} + {{- with (include "tc.v1.common.lib.service.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + ports: + {{- . | nindent 4 }} + {{- end -}} + {{- if not (mustHas $objectData.type $specialTypes) }} + selector: + {{- if $objectData.selectorLabels }} + {{- tpl ( toYaml $objectData.selectorLabels) $rootCtx | nindent 4 }} + {{- else }} + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $podValues.shortName) | trim | nindent 4 -}} + {{- end }} + {{- end -}} + {{- if eq $objectData.type "ExternalIP" -}} + {{- $useSlice := true -}} + {{- if kindIs "bool" $objectData.useSlice -}} + {{- $useSlice = $objectData.useSlice -}} + {{- end -}} + + {{- if $useSlice -}} + {{- include "tc.v1.common.class.endpointSlice" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- else -}} + {{- include "tc.v1.common.class.endpoint" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_serviceAccount.tpl b/helm-charts/dashy/charts/common/templates/class/_serviceAccount.tpl new file mode 100644 index 0000000..209bf0b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_serviceAccount.tpl @@ -0,0 +1,34 @@ +{{/* Service Account Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the serviceAccount. + labels: The labels of the serviceAccount. + annotations: The annotations of the serviceAccount. + autoMountToken: Whether to mount the ServiceAccount token or not. +*/}} + +{{- define "tc.v1.common.class.serviceAccount" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Service Account") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ $objectData.automountServiceAccountToken | default false }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_serviceMonitor.tpl b/helm-charts/dashy/charts/common/templates/class/_serviceMonitor.tpl new file mode 100644 index 0000000..17c2020 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_serviceMonitor.tpl @@ -0,0 +1,47 @@ +{{- define "tc.v1.common.class.servicemonitor" -}} + {{- $fullName := include "tc.v1.common.lib.chart.names.fullname" . -}} + {{- $servicemonitorName := $fullName -}} + {{- $values := .Values.servicemonitor -}} + + {{- if hasKey . "ObjectValues" -}} + {{- with .ObjectValues.metrics -}} + {{- $values = . -}} + {{- end -}} + {{- end -}} + {{- $servicemonitorLabels := $values.labels -}} + {{- $servicemonitorAnnotations := $values.annotations -}} + + {{- if and (hasKey $values "nameOverride") $values.nameOverride -}} + {{- $servicemonitorName = printf "%v-%v" $servicemonitorName $values.nameOverride -}} + {{- end }} +--- +apiVersion: {{ include "tc.v1.common.capabilities.servicemonitor.apiVersion" $ }} +kind: ServiceMonitor +metadata: + name: {{ $servicemonitorName }} + namespace: {{ $.Values.namespace | default $.Values.global.namespace | default $.Release.Namespace }} + {{- $labels := (mustMerge ($servicemonitorLabels | default dict) (include "tc.v1.common.lib.metadata.allLabels" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) | trim) }} + labels: + {{- . | nindent 4 }} + {{- end }} + {{- $annotations := (mustMerge ($servicemonitorAnnotations | default dict) (include "tc.v1.common.lib.metadata.allAnnotations" $ | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 4 }} + {{- end }} +spec: + jobLabel: app.kubernetes.io/name + selector: + {{- if $values.selector }} + {{- tpl (toYaml $values.selector) $ | nindent 4 }} + {{- else }} + {{- $objectData := dict "targetSelector" $values.targetSelector }} + {{- $selectedService := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $ "objectData" $objectData)) }} + {{- $selectedServiceName := $selectedService.shortName }} + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $ "objectType" "service" "objectName" $selectedServiceName) | indent 6 }} + {{- end }} + endpoints: + {{- tpl (toYaml $values.endpoints) $ | nindent 4 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_statefulset.tpl b/helm-charts/dashy/charts/common/templates/class/_statefulset.tpl new file mode 100644 index 0000000..289ba82 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_statefulset.tpl @@ -0,0 +1,59 @@ +{{/* StatefulSet Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: The object data to be used to render the StatefulSet. +*/}} + +{{- define "tc.v1.common.class.statefulset" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- include "tc.v1.common.lib.workload.statefulsetValidation" (dict "objectData" $objectData) }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "StatefulSet") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +spec: + {{- include "tc.v1.common.lib.workload.statefulsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 2 }} + selector: + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.shortName) | trim | nindent 6 }} + template: + metadata: + {{- $labels := (mustMerge ($objectData.podSpec.labels | default dict) + (include "tc.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.podLabels" $rootCtx | 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) }} + labels: + {{- . | nindent 8 }} + {{- end -}} + {{- $annotations := (mustMerge ($objectData.podSpec.annotations | default dict) + (include "tc.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) + (include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData) | fromYaml) + (include "tc.v1.common.lib.metadata.podAnnotations" $rootCtx | fromYaml)) -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 8 }} + {{- end }} + spec: + {{- include "tc.v1.common.lib.workload.pod" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 6 }} + {{- with (include "tc.v1.common.lib.storage.volumeClaimTemplates" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + volumeClaimTemplates: + {{- . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/class/_validatingWebhookConfiguration.tpl b/helm-charts/dashy/charts/common/templates/class/_validatingWebhookConfiguration.tpl new file mode 100644 index 0000000..f9f05d4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/class/_validatingWebhookConfiguration.tpl @@ -0,0 +1,38 @@ +{{/* ValidatingWebhookconfiguration Class */}} +{{/* Call this template: +{{ include "tc.v1.common.class.validatingWebhookconfiguration" (dict "rootCtx" $ "objectData" $objectData) }} + +rootCtx: The root context of the chart. +objectData: + name: The name of the validatingWebhookconfiguration. + labels: The labels of the validatingWebhookconfiguration. + annotations: The annotations of the validatingWebhookconfiguration. + data: The data of the validatingWebhookconfiguration. + namespace: The namespace of the validatingWebhookconfiguration. (Optional) +*/}} + +{{- define "tc.v1.common.class.validatingWebhookconfiguration" -}} + + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: {{ $objectData.name }} + namespace: {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Webhook") }} + {{- $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 ($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: + {{- . | nindent 4 }} + {{- end }} +webhooks: + {{- range $webhook := $objectData.webhooks -}} + {{- include "tc.v1.common.lib.webhook" (dict "webhook" $webhook "rootCtx" $rootCtx) | trim | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/helpers/_envDupeCheck.tpl b/helm-charts/dashy/charts/common/templates/helpers/_envDupeCheck.tpl new file mode 100644 index 0000000..da27c96 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/helpers/_envDupeCheck.tpl @@ -0,0 +1,23 @@ +{{/* Check Env for Duplicates */}} +{{/* Call this template: +{{ include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $ "objectData" $objectData "source" $source "key" $key) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.helper.container.envDupeCheck" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $source := .source -}} + {{- $type := .type -}} + {{- $key := .key -}} + + {{- $dupeEnv := (get $objectData.envDupe $key) -}} + + {{- if $dupeEnv -}} + {{- fail (printf "Container - Environment Variable [%s] in [%s] tried to override the Environment Variable that is already defined in [%s]" $key $source $dupeEnv.source) -}} + {{- end -}} + + {{- $_ := set $objectData.envDupe $key (dict "source" $source) -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/helpers/_getPortRange.tpl b/helm-charts/dashy/charts/common/templates/helpers/_getPortRange.tpl new file mode 100644 index 0000000..8127fc5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/helpers/_getPortRange.tpl @@ -0,0 +1,59 @@ +{{/* Returns Lowest and Highest ports assigned to the any container in the pod */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.helpers.securityContext.getPortRange" (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.helpers.securityContext.getPortRange" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{ $portRange := (dict "high" 0 "low" 0) }} + + {{- range $name, $service := $rootCtx.Values.service -}} + {{- $selected := false -}} + {{/* If service is enabled... */}} + {{- if $service.enabled -}} + + {{/* If there is a selector */}} + {{- if $service.targetSelector -}} + + {{/* And pod is selected */}} + {{- if eq $service.targetSelector $objectData.shortName -}} + {{- $selected = true -}} + {{- end -}} + + {{- else -}} + {{/* If no selector is defined but pod is primary */}} + {{- if $objectData.primary -}} + {{- $selected = true -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{- if $selected -}} + {{- range $name, $portValues := $service.ports -}} + {{- if $portValues.enabled -}} + + {{- $portToCheck := ($portValues.targetPort | default $portValues.port) -}} + {{- if kindIs "string" $portToCheck -}} + {{- $portToCheck = (tpl $portToCheck $rootCtx) | int -}} + {{- end -}} + + {{- if or (not $portRange.low) (lt ($portToCheck | int) ($portRange.low | int)) -}} + {{- $_ := set $portRange "low" $portToCheck -}} + {{- end -}} + + {{- if or (not $portRange.high) (gt ($portToCheck | int) ($portRange.high | int)) -}} + {{- $_ := set $portRange "high" $portToCheck -}} + {{- end -}} + + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} + + {{- $portRange | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/helpers/_getSelectedPod.tpl b/helm-charts/dashy/charts/common/templates/helpers/_getSelectedPod.tpl new file mode 100644 index 0000000..c2d7cf9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/helpers/_getSelectedPod.tpl @@ -0,0 +1,47 @@ +{{/* Service - Get Selected Pod */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.helpers.getSelectedPodValues" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +objectData: The object data of the service +rootCtx: The root context of the chart. +*/}} + +{{- define "tc.v1.common.lib.helpers.getSelectedPodValues" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- $podValues := dict -}} + {{- with $objectData.targetSelector -}} + {{- $podValues = mustDeepCopy (get $rootCtx.Values.workload .) -}} + + {{- if not $podValues -}} + {{- fail (printf "%s - Selected pod [%s] is not defined" $caller .) -}} + {{- end -}} + + {{- if not $podValues.enabled -}} + {{- fail (printf "%s - Selected pod [%s] is not enabled" $caller .) -}} + {{- end -}} + + {{/* While we know the shortName from targetSelector, let's set it explicitly + So service can reference this directly, to match the behaviour of a service + without targetSelector defined (assumes "use primary") */}} + {{- $_ := set $podValues "shortName" . -}} + {{- else -}} + + {{/* If no targetSelector is defined, we assume the service is using the primary pod */}} + {{/* Also no need to check for multiple primaries here, it's already done on the workload validation */}} + {{- range $podName, $pod := $rootCtx.Values.workload -}} + {{- if $pod.enabled -}} + {{- if $pod.primary -}} + {{- $podValues = mustDeepCopy $pod -}} + {{/* Set the shortName so service can use this on selector */}} + {{- $_ := set $podValues "shortName" $podName -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} + + {{/* Return values in Json, to preserve types */}} + {{ $podValues | toJson }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/helpers/_getSelectedService.tpl b/helm-charts/dashy/charts/common/templates/helpers/_getSelectedService.tpl new file mode 100644 index 0000000..d874222 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/helpers/_getSelectedService.tpl @@ -0,0 +1,47 @@ +{{/* Service - Get Selected Service */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +objectData: The object data of the service +rootCtx: The root context of the chart. +*/}} + +{{- define "tc.v1.common.lib.helpers.getSelectedServiceValues" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- $serviceValues := dict -}} + {{- with $objectData.targetSelector -}} + {{- $serviceValues = mustDeepCopy (get $rootCtx.Values.service .) -}} + + {{- if not $serviceValues -}} + {{- fail (printf "%s - Selected service [%s] is not defined" $caller .) -}} + {{- end -}} + + {{- if not $serviceValues.enabled -}} + {{- fail (printf "%s - Selected service [%s] is not enabled" $caller .) -}} + {{- end -}} + + {{/* While we know the shortName from targetSelector, let's set it explicitly + So service can reference this directly, to match the behaviour of a service + without targetSelector defined (assumes "use primary") */}} + {{- $_ := set $serviceValues "shortName" . -}} + {{- else -}} + + {{/* If no targetSelector is defined, we assume the service is using the primary service */}} + {{/* Also no need to check for multiple primaries here, it's already done on the service validation */}} + {{- range $serviceName, $service := $rootCtx.Values.service -}} + {{- if $service.enabled -}} + {{- if $service.primary -}} + {{- $serviceValues = mustDeepCopy $service -}} + {{/* Set the shortName so service can use this on selector */}} + {{- $_ := set $serviceValues "shortName" $serviceName -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} + + {{/* Return values in Json, to preserve types */}} + {{ $serviceValues | toJson }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/helpers/_makeIntOrNoop.tpl b/helm-charts/dashy/charts/common/templates/helpers/_makeIntOrNoop.tpl new file mode 100644 index 0000000..aec1ddf --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/helpers/_makeIntOrNoop.tpl @@ -0,0 +1,21 @@ +{{- define "tc.v1.common.helper.makeIntOrNoop" -}} + {{- $value := . -}} + + {{/* + - Ints in Helm can be either int, int64 or float64. + - Values that start with zero should not be converted + to int again as this will strip leading zeros. + - Numbers converted to E notation by Helm will + always contain the "e" character. So we only + convert those. + */}} + {{- if and + (mustHas (kindOf $value) (list "int" "int64" "float64")) + (not (hasPrefix "0" ($value | toString))) + (contains "e" ($value | toString | lower)) + -}} + {{- $value | int -}} + {{- else -}} + {{- $value -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/_tc_capabilities.tpl b/helm-charts/dashy/charts/common/templates/lib/_tc_capabilities.tpl new file mode 100644 index 0000000..62602c5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/_tc_capabilities.tpl @@ -0,0 +1,44 @@ +{{/* Return the appropriate apiVersion for PodMonitor */}} +{{- define "tc.v1.common.capabilities.podmonitor.apiVersion" -}} + {{- print "monitoring.coreos.com/v1" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for ServiceMonitor */}} +{{- define "tc.v1.common.capabilities.servicemonitor.apiVersion" -}} + {{- print "monitoring.coreos.com/v1" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for PrometheusRule */}} +{{- define "tc.v1.common.capabilities.prometheusrule.apiVersion" -}} + {{- 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" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for HorizontalPodAutoscaler aka HPA*/}} +{{- define "tc.v1.common.capabilities.hpa.apiVersion" -}} + {{- print "autoscaling/v2" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for Cert-Manager certificates */}} +{{- define "tc.v1.common.capabilities.cert-manager.certificate.apiVersion" -}} + {{- print "cert-manager.io/v1" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for Cert-Manager certificates */}} +{{- define "tc.v1.common.capabilities.cnpg.cluster.apiVersion" -}} + {{- print "postgresql.cnpg.io/v1" -}} +{{- end -}} + +{{/* Return the appropriate apiVersion for Cert-Manager certificates */}} +{{- define "tc.v1.common.capabilities.cnpg.pooler.apiVersion" -}} + {{- print "postgresql.cnpg.io/v1" -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/chart/_names.tpl b/helm-charts/dashy/charts/common/templates/lib/chart/_names.tpl new file mode 100644 index 0000000..9f62422 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/chart/_names.tpl @@ -0,0 +1,52 @@ +{{/* Contains functions for generating names */}} + +{{/* Returns the name of the Chart */}} +{{- define "tc.v1.common.lib.chart.names.name" -}} + + {{- .Chart.Name | lower | trunc 63 | trimSuffix "-" -}} + +{{- end -}} + +{{/* Returns the fullname of the Chart */}} +{{- define "tc.v1.common.lib.chart.names.fullname" -}} + + {{- $name := include "tc.v1.common.lib.chart.names.name" . -}} + + {{- if contains $name .Release.Name -}} + {{- $name = .Release.Name -}} + {{- else -}} + {{- $name = printf "%s-%s" .Release.Name $name -}} + {{- end -}} + + {{- $name | lower | trunc 63 | trimSuffix "-" -}} + +{{- end -}} + +{{/* Returns the fqdn of the Chart */}} +{{- define "tc.v1.common.lib.chart.names.fqdn" -}} + + {{- printf "%s.%s" (include "tc.v1.common.lib.chart.names.name" .) .Release.Namespace | replace "+" "_" | trunc 63 | trimSuffix "-" -}} + +{{- end -}} + +{{/* Validates names */}} +{{- define "tc.v1.common.lib.chart.names.validation" -}} + + {{- $name := .name -}} + {{- $length := .length -}} + {{- if not $length -}} + {{- $length = 63 -}} + {{- end -}} + + {{- if not (and (mustRegexMatch "^[a-z0-9]((-?[a-z0-9]-?)*[a-z0-9])?$" $name) (le (len $name) $length)) -}} + {{- fail (printf "Name [%s] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most %v characters." $name $length) -}} + {{- end -}} + +{{- end -}} + +{{/* Create chart name and version as used by the chart label */}} +{{- define "tc.v1.common.lib.chart.names.chart" -}} + + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/chart/_notes.tpl b/helm-charts/dashy/charts/common/templates/lib/chart/_notes.tpl new file mode 100644 index 0000000..b6924de --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/chart/_notes.tpl @@ -0,0 +1,21 @@ +{{- define "tc.v1.common.lib.chart.notes" -}} + + {{- include "tc.v1.common.lib.chart.header" . -}} + + {{- include "tc.v1.common.lib.chart.custom" . -}} + + {{- include "tc.v1.common.lib.chart.footer" . -}} + +{{- end -}} + +{{- define "tc.v1.common.lib.chart.header" -}} + {{- tpl $.Values.notes.header $ | nindent 0 }} +{{- end -}} + +{{- define "tc.v1.common.lib.chart.custom" -}} + {{- tpl $.Values.notes.custom $ | nindent 0 }} +{{- end -}} + +{{- define "tc.v1.common.lib.chart.footer" -}} + {{- tpl $.Values.notes.footer $ | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/cnpg/_poolerMetrics.tpl b/helm-charts/dashy/charts/common/templates/lib/cnpg/_poolerMetrics.tpl new file mode 100644 index 0000000..f1b7152 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/cnpg/_poolerMetrics.tpl @@ -0,0 +1,9 @@ +{{- define "tc.v1.common.lib.cnpg.metrics.pooler" -}} +enabled: true +type: "podmonitor" +selector: + matchLabels: + cnpg.io/poolerName: {{ .poolerName }} +endpoints: +- port: metrics +{{- end }} diff --git a/helm-charts/dashy/charts/common/templates/lib/cnpg/_urlsSecret.tpl b/helm-charts/dashy/charts/common/templates/lib/cnpg/_urlsSecret.tpl new file mode 100644 index 0000000..2b83fe0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/cnpg/_urlsSecret.tpl @@ -0,0 +1,14 @@ +{{- define "tc.v1.common.lib.cnpg.secret.urls" -}} +{{- $std := .std }} +{{- $nossl := .nossl }} +{{- $porthost := .porthost }} +{{- $host := .host }} +{{- $jdbc := .jdbc }} +enabled: true +data: + std: {{ $std }} + nossl: {{ $nossl }} + porthost: {{ $porthost }} + host: {{ $host }} + jdbc: {{ $jdbc }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/cnpg/_userSecret.tpl b/helm-charts/dashy/charts/common/templates/lib/cnpg/_userSecret.tpl new file mode 100644 index 0000000..b4bb53c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/cnpg/_userSecret.tpl @@ -0,0 +1,9 @@ +{{- define "tc.v1.common.lib.cnpg.secret.user" -}} +{{- $dbPass := .dbPass }} +{{- $values := .values -}} +enabled: true +type: kubernetes.io/basic-auth +data: + username: {{ $values.user }} + password: {{ $dbPass }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/configmap/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/configmap/_validation.tpl new file mode 100644 index 0000000..6f2a252 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/configmap/_validation.tpl @@ -0,0 +1,21 @@ +{{/* Configmap Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.configmap.validation" (dict "objectData" $objectData) -}} +objectData: + labels: The labels of the configmap. + annotations: The annotations of the configmap. + data: The data of the configmap. +*/}} + +{{- define "tc.v1.common.lib.configmap.validation" -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.data -}} + {{- fail "ConfigMap - Expected non-empty " -}} + {{- end -}} + + {{- if not (kindIs "map" $objectData.data) -}} + {{- fail (printf "ConfigMap - Expected to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_args.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_args.tpl new file mode 100644 index 0000000..afe3825 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_args.tpl @@ -0,0 +1,22 @@ +{{/* Returns args list */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.args" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.args" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $key := (list "args" "extraArgs") -}} + {{- with (get $objectData $key) -}} + {{- if kindIs "string" . }} +- {{ tpl . $rootCtx | quote }} + {{- else if kindIs "slice" . -}} + {{- range $arg := . }} +- {{ tpl $arg $rootCtx | quote }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_command.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_command.tpl new file mode 100644 index 0000000..1a83eb8 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_command.tpl @@ -0,0 +1,18 @@ +{{/* Returns command list */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.command" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.command" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if kindIs "string" $objectData.command }} +- {{ tpl $objectData.command $rootCtx | quote }} + {{- else if kindIs "slice" $objectData.command -}} + {{- range $objectData.command }} +- {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_env.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_env.tpl new file mode 100644 index 0000000..08b779f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_env.tpl @@ -0,0 +1,108 @@ +{{/* Returns Env */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.env" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.env" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $k, $v := $objectData.env -}} + {{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "env" "key" $k) }} +- name: {{ $k | quote }} + {{- if not (kindIs "map" $v) -}} + {{- $value := "" -}} + {{- if not (kindIs "invalid" $v) -}} {{/* Only tpl non-empty values */}} + {{- $value = $v -}} + {{- if kindIs "string" $v -}} + {{- $value = tpl $v $rootCtx -}} + {{- end -}} + {{- end }} + value: {{ include "tc.v1.common.helper.makeIntOrNoop" $value | quote }} + {{- else if kindIs "map" $v }} + valueFrom: + {{- $refs := (list "configMapKeyRef" "secretKeyRef" "fieldRef") -}} + {{- if or (ne (len ($v | keys)) 1) (not (mustHas ($v | keys | first) $refs)) -}} + {{- fail (printf "Container - Expected with a ref to have one of [%s], but got [%s]" (join ", " $refs) (join ", " ($v | keys | sortAlpha))) -}} + {{- end -}} + + {{- $name := "" -}} + + + {{- range $key := (list "configMapKeyRef" "secretKeyRef") -}} + {{- if hasKey $v $key }} + {{ $key }}: + {{- $obj := get $v $key -}} + {{- if not $obj.name -}} + {{- fail (printf "Container - Expected non-empty " $key) -}} + {{- end -}} + + {{- if not $obj.key -}} + {{- fail (printf "Container - Expected non-empty " $key) -}} + {{- end }} + key: {{ $obj.key | quote }} + + {{- $name = tpl $obj.name $rootCtx -}} + + {{- $expandName := true -}} + {{- if (hasKey $obj "expandObjectName") -}} + {{- if not (kindIs "invalid" $obj.expandObjectName) -}} + {{- $expandName = $obj.expandObjectName -}} + {{- else -}} + {{- fail (printf "Container - Expected the defined key [expandObjectName] in to not be empty" $k) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $expandName -}} + {{- $expandName = tpl $expandName $rootCtx -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $expandName "true" -}} + {{- $expandName = true -}} + {{- else if eq $expandName "false" -}} + {{- $expandName = false -}} + {{- end -}} + {{- end -}} + + {{- if $expandName -}} + {{- $item := ($key | trimSuffix "KeyRef" | lower) -}} + + {{- $data := (get $rootCtx.Values $item) -}} + {{- $data = (get $data $name) -}} + + {{- if not $data -}} + {{- fail (printf "Container - Expected in the referenced %s [%s] to be defined" (camelcase $item) $name) -}} + {{- end -}} + + {{- $found := false -}} + {{- range $k, $v := $data.data -}} + {{- if eq $k $obj.key -}} + {{- $found = true -}} + {{- end -}} + {{- end -}} + + {{- if not $found -}} + {{- fail (printf "Container - Expected in the referenced key [%s] in %s [%s] to be defined" $obj.key (camelcase $item) $name) -}} + {{- end -}} + + {{- $name = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}} + {{- end }} + name: {{ $name | quote }} + {{- end -}} + {{- end -}} + + {{- if hasKey $v "fieldRef" }} + fieldRef: + {{- if not $v.fieldRef.fieldPath -}} + {{- fail "Container - Expected non-empty " -}} + {{- end }} + fieldPath: {{ $v.fieldRef.fieldPath | quote }} + {{- if $v.fieldRef.apiVersion }} + apiVersion: {{ $v.fieldRef.apiVersion | quote }} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_envFrom.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_envFrom.tpl new file mode 100644 index 0000000..d8876fc --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_envFrom.tpl @@ -0,0 +1,74 @@ +{{/* Returns Env From */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.envFrom" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.envFrom" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $refs := (list "configMapRef" "secretRef") -}} + {{- range $envFrom := $objectData.envFrom -}} + {{- if and (not $envFrom.secretRef) (not $envFrom.configMapRef) -}} + {{- fail (printf "Container - Expected entry to have one of [%s]" (join ", " $refs)) -}} + {{- end -}} + + {{- if and $envFrom.secretRef $envFrom.configMapRef -}} + {{- fail (printf "Container - Expected entry to have only one of [%s], but got both" (join ", " $refs)) -}} + {{- end -}} + + {{- range $ref := $refs -}} + {{- with (get $envFrom $ref) -}} + {{- if not .name -}} + {{- fail (printf "Container - Expected non-empty " $ref) -}} + {{- end -}} + + {{- $objectName := tpl .name $rootCtx -}} + + {{- $expandName := true -}} + {{- if (hasKey . "expandObjectName") -}} + {{- if not (kindIs "invalid" .expandObjectName) -}} + {{- $expandName = .expandObjectName -}} + {{- else -}} + {{- fail (printf "Container - Expected the defined key [expandObjectName] in to not be empty" $ref) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $expandName -}} + {{- $expandName = tpl $expandName $rootCtx -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $expandName "true" -}} + {{- $expandName = true -}} + {{- else if eq $expandName "false" -}} + {{- $expandName = false -}} + {{- end -}} + {{- end -}} + + {{- if $expandName -}} + {{- $object := dict -}} + {{- $source := "" -}} + {{- if eq $ref "configMapRef" -}} + {{- $object = (get $rootCtx.Values.configmap $objectName) -}} + {{- $source = "ConfigMap" -}} + {{- else if eq $ref "secretRef" -}} + {{- $object = (get $rootCtx.Values.secret $objectName) -}} + {{- $source = "Secret" -}} + {{- end -}} + + {{- if not $object -}} + {{- fail (printf "Container - Expected %s [%s] defined in to exist" $source $objectName) -}} + {{- end -}} + {{- range $k, $v := $object.data -}} + {{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s - %s" $source $objectName) "key" $k) -}} + {{- end -}} + + {{- $objectName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectName) -}} + {{- end }} +- {{ $ref }}: + name: {{ $objectName | quote }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_envList.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_envList.tpl new file mode 100644 index 0000000..a257e67 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_envList.tpl @@ -0,0 +1,23 @@ +{{/* Returns Env List */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.envList" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.envList" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $env := $objectData.envList -}} + {{- if not $env.name -}} + {{- fail "Container - Expected non-empty " -}} + {{- end -}} {{/* Empty value is valid */}} + {{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "envList" "key" $env.name) -}} + {{- $value := $env.value -}} + {{- if kindIs "string" $env.value -}} + {{- $value = tpl $env.value $rootCtx -}} + {{- end }} +- name: {{ $env.name | quote }} + value: {{ include "tc.v1.common.helper.makeIntOrNoop" $value | quote }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_fixedEnv.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_fixedEnv.tpl new file mode 100644 index 0000000..aac6941 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_fixedEnv.tpl @@ -0,0 +1,75 @@ +{{/* Returns Fixed Env */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.fixedEnv" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.fixedEnv" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{/* Avoid nil pointers */}} + {{- if not (hasKey $objectData "fixedEnv") -}} + {{- $_ := set $objectData "fixedEnv" dict -}} + {{- end -}} + + {{- $nvidiaCaps := $rootCtx.Values.containerOptions.NVIDIA_CAPS -}} + + {{- if $objectData.fixedEnv.NVIDIA_CAPS -}} + {{- $nvidiaCaps = $objectData.fixedEnv.NVIDIA_CAPS -}} + {{- end -}} + + {{- if not (deepEqual $nvidiaCaps (mustUniq $nvidiaCaps)) -}} + {{- fail (printf "Container - Expected to have only unique values, but got [%s]" (join ", " $nvidiaCaps)) -}} + {{- end -}} + + {{- $caps := (list "all" "compute" "utility" "graphics" "video") -}} + {{- range $cap := $nvidiaCaps -}} + {{- if not (mustHas $cap $caps) -}} + {{- fail (printf "Container - Expected entry to be one of [%s], but got [%s]" (join ", " $caps) $cap) -}} + {{- end -}} + {{- end -}} + + {{- $secContext := fromJson (include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $rootCtx "objectData" $objectData)) -}} + + {{- $fixed := list -}} + {{- $TZ := $objectData.fixedEnv.TZ | default $rootCtx.Values.TZ -}} + {{- $UMASK := $objectData.fixedEnv.UMASK | default $rootCtx.Values.securityContext.container.UMASK -}} + {{- $PUID := $objectData.fixedEnv.PUID | default $rootCtx.Values.securityContext.container.PUID -}} + {{- if and (not (kindIs "invalid" $objectData.fixedEnv.PUID)) (eq (int $objectData.fixedEnv.PUID) 0) -}} + {{- $PUID = $objectData.fixedEnv.PUID -}} + {{- end -}} + {{/* calculatedFSGroup is passed from the pod */}} + {{- $PGID := $objectData.calculatedFSGroup -}} + + {{- $fixed = mustAppend $fixed (dict "k" "TZ" "v" $TZ) -}} + {{- $fixed = mustAppend $fixed (dict "k" "UMASK" "v" $UMASK) -}} + {{- $fixed = mustAppend $fixed (dict "k" "UMASK_SET" "v" $UMASK) -}} + {{/* TODO: Offer gpu section in resources for native helm and adjust this include, then we can remove the "if inside ixChartContext" */}} + {{- if eq (include "tc.v1.common.lib.container.resources.gpu" (dict "rootCtx" $rootCtx "objectData" $objectData "returnBool" true)) "true" -}} + {{- $fixed = mustAppend $fixed (dict "k" "NVIDIA_DRIVER_CAPABILITIES" "v" (join "," $nvidiaCaps)) -}} + {{- else -}} {{/* Only when in SCALE */}} + {{- if hasKey $rootCtx.Values.global "ixChartContext" -}} + {{- $fixed = mustAppend $fixed (dict "k" "NVIDIA_VISIBLE_DEVICES" "v" "void") -}} + {{- end -}} + {{- end -}} + {{/* If running as root and PUID is set (0 or greater), set related envs */}} + {{- if and (or (eq (int $secContext.runAsUser) 0) (eq (int $secContext.runAsGroup) 0)) (ge (int $PUID) 0) -}} + {{- $fixed = mustAppend $fixed (dict "k" "PUID" "v" $PUID) -}} + {{- $fixed = mustAppend $fixed (dict "k" "USER_ID" "v" $PUID) -}} + {{- $fixed = mustAppend $fixed (dict "k" "UID" "v" $PUID) -}} + {{- $fixed = mustAppend $fixed (dict "k" "PGID" "v" $PGID) -}} + {{- $fixed = mustAppend $fixed (dict "k" "GROUP_ID" "v" $PGID) -}} + {{- $fixed = mustAppend $fixed (dict "k" "GID" "v" $PGID) -}} + {{- end -}} + {{/* If rootFS is readOnly OR does not as root, let s6 containers to know that fs is readonly */}} + {{- if or $secContext.readOnlyRootFilesystem $secContext.runAsNonRoot -}} + {{- $fixed = mustAppend $fixed (dict "k" "S6_READ_ONLY_ROOT" "v" "1") -}} + {{- end -}} + + {{- range $env := $fixed -}} + {{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "fixedEnv" "key" $env.k) }} +- name: {{ $env.k | quote }} + value: {{ (include "tc.v1.common.helper.makeIntOrNoop" $env.v) | quote }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_imageSelector.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_imageSelector.tpl new file mode 100644 index 0000000..ea7b548 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_imageSelector.tpl @@ -0,0 +1,42 @@ +{{/* Returns the image dictionary */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.imageSelector" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.imageSelector" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $imageObj := dict -}} + + {{- $selector := "image" -}} + {{- with $objectData.imageSelector -}} + {{- $selector = tpl . $rootCtx -}} + {{- end -}} + + {{- if hasKey $rootCtx.Values $selector -}} + {{- $imageObj = get $rootCtx.Values $selector -}} + {{- else -}} + {{- fail (printf "Container - Expected <.Values.%s> to exist" $selector) -}} + {{- end -}} + + {{- if not $imageObj.repository -}} + {{- fail (printf "Container - Expected non-empty <.Values.%s.repository>" $selector) -}} + {{- end -}} + + {{- if not $imageObj.tag -}} + {{- fail (printf "Container - Expected non-empty <.Values.%s.tag>" $selector) -}} + {{- end -}} + + {{- if not $imageObj.pullPolicy -}} + {{- $_ := set $imageObj "pullPolicy" "IfNotPresent" -}} + {{- end -}} + + {{- $policies := (list "IfNotPresent" "Always" "Never") -}} + {{- if not (mustHas $imageObj.pullPolicy $policies) -}} + {{- fail (printf "Container - Expected <.Values.%s.pullPolicy> to be one of [%s], but got [%s]" $selector (join ", " $policies) $imageObj.pullPolicy) -}} + {{- end -}} + + {{- $imageObj | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_lifecycle.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_lifecycle.tpl new file mode 100644 index 0000000..bc4743d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_lifecycle.tpl @@ -0,0 +1,37 @@ +{{/* Returns lifecycle */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.lifecycle" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.lifecycle" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hooks := (list "preStop" "postStart") -}} + {{- $types := (list "exec" "http" "https") -}} + {{- with $objectData.lifecycle -}} + {{- range $hook, $hookValues := . -}} + {{- if not (mustHas $hook $hooks) -}} + {{- fail (printf "Container - Expected to be one of [%s], but got [%s]" (join ", " $hooks) $hook) -}} + {{- end -}} + + {{- if not $hookValues.type -}} + {{- fail "Container - Expected non-empty " -}} + {{- end -}} + + {{- if not (mustHas $hookValues.type $types) -}} + {{- fail (printf "Container - Expected to be one of [%s], but got [%s]" (join ", " $types) $hookValues.type) -}} + {{- end }} +{{ $hook }}: + {{- if eq $hookValues.type "exec" -}} + {{- include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $rootCtx "objectData" $hookValues "caller" "lifecycle") | trim | nindent 2 -}} + {{- else if mustHas $hookValues.type (list "http" "https") -}} + {{- include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $rootCtx "objectData" $hookValues "caller" "lifecycle") | trim | nindent 2 -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_ports.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_ports.tpl new file mode 100644 index 0000000..e243d8f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_ports.tpl @@ -0,0 +1,87 @@ +{{/* Returns ports list */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.ports" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.ports" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $serviceName, $serviceValues := $rootCtx.Values.service -}} + {{- $podSelected := false -}} + {{/* If service is enabled... */}} + {{- if $serviceValues.enabled -}} + + {{/* If there is a selector */}} + {{- if $serviceValues.targetSelector -}} + + {{/* And pod is selected */}} + {{- if eq $serviceValues.targetSelector $objectData.podShortName -}} + {{- $podSelected = true -}} + {{- end -}} + + {{- else -}} + {{/* If no selector is defined but pod is primary */}} + {{- if $objectData.podPrimary -}} + {{- $podSelected = true -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{- if $podSelected -}} + {{- range $portName, $portValues := $serviceValues.ports -}} + {{- $containerSelected := false -}} + + {{/* If service is enabled... */}} + {{- if $portValues.enabled -}} + {{/* If there is a selector */}} + {{- if $portValues.targetSelector -}} + + {{/* And container is selected */}} + {{- if eq $portValues.targetSelector $objectData.shortName -}} + {{- $containerSelected = true -}} + {{- end -}} + + {{- else -}} + {{/* If no selector is defined but container is primary */}} + {{- if $objectData.primary -}} + {{- $containerSelected = true -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{/* If the container is selected render port */}} + {{- if $containerSelected -}} + {{- $containerPort := $portValues.targetPort | default $portValues.port -}} + {{- if kindIs "string" $containerPort -}} + {{- $containerPort = (tpl $containerPort $rootCtx) -}} + {{- end -}} + + {{- $tcpProtocols := (list "tcp" "http" "https") -}} + {{- $protocol := tpl ($portValues.protocol | default $rootCtx.Values.fallbackDefaults.serviceProtocol) $rootCtx -}} + {{- if mustHas $protocol $tcpProtocols -}} + {{- $protocol = "tcp" -}} + {{- end }} +- name: {{ $portName }} + containerPort: {{ $containerPort }} + protocol: {{ $protocol | upper }} + {{- with $portValues.hostPort }} + hostPort: {{ . }} + {{- else }} + hostPort: null + {{- end -}} + {{- end -}} + + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} +{{/* Turning hostNetwork on, it creates hostPort automatically and turning it back off does not remove them. Setting hostPort explicitly to null will remove them. + There are still cases that hostPort is not removed, for example, if you have a TCP and UDP port with the same number. Only the TCPs hostPort will be removed. + Also note that setting hostPort to null always, it will NOT affect hostNetwork, as it will still create the hostPorts. + It only helps to remove them when hostNetwork is turned off. +*/}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_primaryValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_primaryValidation.tpl new file mode 100644 index 0000000..6928a78 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_primaryValidation.tpl @@ -0,0 +1,40 @@ +{{/* Containers Basic Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.primaryValidation" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +*/}} +{{- define "tc.v1.common.lib.container.primaryValidation" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{/* Go over the contaienrs */}} + {{- range $name, $container := $objectData.podSpec.containers -}} + + {{/* If container is enabled */}} + {{- if $container.enabled -}} + {{- $hasEnabled = true -}} + + {{/* And container is primary */}} + {{- if and (hasKey $container "primary") ($container.primary) -}} + + {{/* Fail if there is already a primary container */}} + {{- if $hasPrimary -}} + {{- fail "Container - Only one container can be primary per workload" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- end -}} + {{- end -}} + + {{- end -}} + + {{/* Require at least one primary container, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "Container - At least one enabled container must be primary per workload" -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_probes.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_probes.tpl new file mode 100644 index 0000000..a7d56e5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_probes.tpl @@ -0,0 +1,98 @@ +{{/* Returns Probes */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.probes" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.probes" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $probeNames := (list "liveness" "readiness" "startup") -}} + {{- $probeTypes := (list "http" "https" "tcp" "grpc" "exec") -}} + + {{- if not $objectData.probes -}} + {{- fail "Container - Expected non-empty " -}} + {{- end -}} + + {{- range $key := $probeNames -}} + {{- if not (get $objectData.probes $key) -}} + {{- fail (printf "Container - Expected to be defined" $key) -}} + {{- end -}} + {{- end -}} + + {{- range $probeName, $probe := $objectData.probes -}} + + {{- if not (mustHas $probeName $probeNames) -}} + {{- fail (printf "Container - Expected probe to be one of [%s], but got [%s]" (join ", " $probeNames) $probeName) -}} + {{- end -}} + + {{- $isEnabled := true -}} + {{- if kindIs "bool" $probe.enabled -}} + {{- $isEnabled = $probe.enabled -}} + {{- end -}} + + {{- if $isEnabled -}} + + {{- $probeType := $rootCtx.Values.fallbackDefaults.probeType -}} + + {{- with $probe.type -}} + {{- $probeType = tpl . $rootCtx -}} + {{- end -}} + + {{- if not (mustHas $probeType $probeTypes) -}} + {{- fail (printf "Container - Expected probe type to be one of [%s], but got [%s]" (join ", " $probeTypes) $probeType) -}} + {{- end }} +{{ $probeName }}Probe: + {{- if (mustHas $probeType (list "http" "https")) -}} + {{- include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}} + {{- else if eq $probeType "tcp" -}} + {{- include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}} + {{- else if eq $probeType "grpc" -}} + {{- include "tc.v1.common.lib.container.actions.grpc" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}} + {{- else if eq $probeType "exec" -}} + {{- include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $rootCtx "objectData" $probe "caller" "probes") | trim | nindent 2 -}} + {{- end -}} + + {{- include "tc.v1.common.lib.container.probeTimeouts" (dict "rootCtx" $rootCtx "objectData" $probe "probeName" $probeName) | trim | nindent 2 -}} + + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* Returns Probe Timeouts */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.probeTimeouts" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.probeTimeouts" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $probeName := .probeName -}} + + {{- $timeouts := mustDeepCopy (get $rootCtx.Values.fallbackDefaults.probeTimeouts $probeName) -}} + + {{- if $objectData.spec -}} {{/* Overwrite with defined timeouts */}} + {{- $timeouts = mustMergeOverwrite $timeouts $objectData.spec -}} + {{- end -}} + + {{- $keys := (list "initialDelaySeconds" "failureThreshold" "successThreshold" "timeoutSeconds" "periodSeconds") -}} + {{- range $key := $keys -}} + {{- $number := get $timeouts $key -}} + {{- if not (mustHas (kindOf $number) (list "float64" "int" "int64")) -}} + {{- fail (printf "Container - Expected <%s> to be a number, but got [%v]" $key $number) -}} + {{- end -}} + {{- end -}} + + {{- if mustHas $probeName (list "liveness" "startup") -}} + {{- if ne (int $timeouts.successThreshold) 1 -}} + {{- fail (printf "Container - Expected to be 1 on [%s] probe" $probeName) -}} + {{- end -}} + {{- end }} +initialDelaySeconds: {{ $timeouts.initialDelaySeconds }} +failureThreshold: {{ $timeouts.failureThreshold }} +successThreshold: {{ $timeouts.successThreshold }} +timeoutSeconds: {{ $timeouts.timeoutSeconds }} +periodSeconds: {{ $timeouts.periodSeconds }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_resources.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_resources.tpl new file mode 100644 index 0000000..7e3c0f7 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_resources.tpl @@ -0,0 +1,140 @@ +{{/* Returns Resources */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.resources" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.resources" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $resources := mustDeepCopy $rootCtx.Values.resources -}} + + {{- if $objectData.resources -}} + {{- $resources = mustMergeOverwrite $resources $objectData.resources -}} + {{- end -}} + + {{- include "tc.v1.common.lib.container.resources.validation" (dict "resources" $resources) -}} + +requests: + cpu: {{ $resources.requests.cpu }} + memory: {{ $resources.requests.memory }} + {{- if $resources.limits }} +limits: + {{- with $resources.limits.cpu }} {{/* Passing 0, will not render it, meaning unlimited */}} + cpu: {{ . }} + {{- end -}} + {{- with $resources.limits.memory }} {{/* Passing 0, will not render it, meaning unlimited */}} + memory: {{ . }} + {{- end -}} + {{- include "tc.v1.common.lib.container.resources.gpu" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- end -}} +{{- end -}} + +{{/* Returns GPU resource */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.resources.gpu" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.resources.gpu" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $returnBool := .returnBool -}} + + {{- $gpuResource := list -}} + + {{- range $GPUValues := $rootCtx.Values.scaleGPU -}} + {{- if not $GPUValues.gpu -}} + {{- fail "Container - Expected non-empty " -}} + {{- end -}} + + {{- $selected := false -}} + + {{/* Parse selector if defined */}} + {{- if $GPUValues.targetSelector -}} + {{- range $podName, $containers := $GPUValues.targetSelector -}} + {{- if not $containers -}} + {{- fail "Container - Expected non-empty list under pod in " -}} + {{- end -}} + + {{- if and (eq $podName $objectData.podShortName) (mustHas $objectData.shortName $containers) -}} + {{- $selected = true -}} + {{- end -}} + {{- end -}} + {{/* If no selector, select primary pod/container */}} + {{- else if and $objectData.podPrimary $objectData.primary -}} + {{- $selected = true -}} + {{- end -}} + + {{- if $selected -}} + {{- $gpuResource = mustAppend $gpuResource $GPUValues.gpu -}} + {{- end -}} + {{- end -}} + + {{- if not $returnBool -}} + {{- range $gpu := $gpuResource -}} + {{- range $k, $v := $gpu -}} + {{- if or (kindIs "invalid" $v) (eq (toString $v) "") -}} + {{- fail "Container - Expected non-empty " -}} + {{- end -}} {{/* Don't try to schedule 0 GPUs */}} + {{- if gt (int $v) 0 }} +{{ $k }}: {{ $v | quote }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- else -}} + {{- if $gpuResource -}} + {{- "true" -}} + {{- end -}} + {{- end -}} + +{{- end -}} + +{{/* Validates resources to match a pattern */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.resources.validation" (dict "resources" $resources) }} +rootCtx: The root context of the chart. +resources: The resources object +*/}} +{{- define "tc.v1.common.lib.container.resources.validation" -}} + {{- $resources := .resources -}} + {{/* CPU: https://regex101.com/r/D4HouI/1 */}} + {{/* MEM: https://regex101.com/r/NNPV2D/1 */}} + {{- $regex := (dict + "cpu" "^(0\\.[1-9]|[1-9][0-9]*)(\\.[0-9]|m?)$" + "memory" "^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$") -}} + {{- $errorMsg := (dict + "cpu" "(Plain Integer - eg. 1), (Float - eg. 0.5), (Milicpu - eg. 500m)" + "memory" "(Suffixed with E/P/T/G/M/K - eg. 1G), (Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi), (Plain Integer in bytes - eg. 1024), (Exponent - eg. 134e6)") -}} + + {{- $resourceTypes := (list "cpu" "memory") -}} + + {{- range $category := (list "requests") -}} {{/* We can also add "limits" here if we want to require them */}} + {{- if not (get $resources $category) -}} + {{- fail (printf "Container - Expected non-empty " $category) -}} + {{- end -}} + + {{- range $type := $resourceTypes -}} + {{- if not (get (get $resources $category) $type) -}} + {{- fail (printf "Container - Expected non-empty " $category $type) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- range $key := (list "requests" "limits") -}} + {{- $resourceCategory := (get $resources $key) -}} + {{- if $resourceCategory -}} + + {{- range $type := $resourceTypes -}} + {{- $resourceValue := (get $resourceCategory $type) -}} + {{- if $resourceValue -}} {{/* Only try to match defined values */}} + {{- if not (mustRegexMatch (get $regex $type) (toString $resourceValue)) -}} + {{- fail (printf "Container - Expected to have one of the following formats [%s], but got [%s]" $key $type (get $errorMsg $type) $resourceValue) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_securityContext.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_securityContext.tpl new file mode 100644 index 0000000..f72d401 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_securityContext.tpl @@ -0,0 +1,181 @@ +{{/* Returns Container Security Context */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.securityContext" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.securityContext" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{/* Initialize from the "global" options */}} + {{- $secContext := fromJson (include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +runAsNonRoot: {{ $secContext.runAsNonRoot }} +runAsUser: {{ $secContext.runAsUser }} +runAsGroup: {{ $secContext.runAsGroup }} +readOnlyRootFilesystem: {{ $secContext.readOnlyRootFilesystem }} +allowPrivilegeEscalation: {{ $secContext.allowPrivilegeEscalation }} +privileged: {{ $secContext.privileged }} +seccompProfile: + type: {{ $secContext.seccompProfile.type }} + {{- if eq $secContext.seccompProfile.type "Localhost" }} + localhostProfile: {{ $secContext.seccompProfile.profile }} + {{- end }} +capabilities: + {{- if $secContext.capabilities.add }} + add: + {{- range $secContext.capabilities.add }} + - {{ . }} + {{- end -}} + {{- else }} + add: [] + {{- end -}} + {{- if $secContext.capabilities.drop }} + drop: + {{- range $secContext.capabilities.drop }} + - {{ . }} + {{- end -}} + {{- else }} + drop: [] + {{- end -}} +{{- end -}} + +{{/* Calculates Container Security Context */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.securityContext.calculate" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $mustPrivileged := false -}} + {{- range $persistenceName, $persistenceValues := $rootCtx.Values.persistence -}} + {{- if $persistenceValues.enabled -}} + {{- if eq $persistenceValues.type "device" -}} + {{- $volume := (fromJson (include "tc.v1.common.lib.container.volumeMount.isSelected" (dict "persistenceName" $persistenceName "persistenceValues" $persistenceValues "objectData" $objectData "key" "persistence"))) -}} + {{- if $volume -}} {{/* If a volume is returned, it means that the container has an assigned device */}} + {{- $mustPrivileged = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $rootCtx.Values.securityContext.container -}} + {{- fail "Container - Expected non-empty <.Values.securityContext.container>" -}} + {{- end -}} + + {{/* Initialize from the "global" options */}} + {{- $secContext := mustDeepCopy $rootCtx.Values.securityContext.container -}} + + {{/* Override with containers options */}} + {{- with $objectData.securityContext -}} + {{- $secContext = mustMergeOverwrite $secContext . -}} + {{- end -}} + + {{/* Validations, as we might endup with null values after merge */}} + {{- range $key := (list "runAsUser" "runAsGroup") -}} + {{- $value := (get $secContext $key) -}} + {{- if not (mustHas (kindOf $value) (list "float64" "int" "int64")) -}} + {{- fail (printf "Container - Expected to be [int], but got [%v] of type [%s]" $key $value (kindOf $value)) -}} + {{- end -}} + {{- end -}} + + {{- if or (eq (int $secContext.runAsUser) 0) (eq (int $secContext.runAsGroup) 0) -}} + {{- $_ := set $secContext "runAsNonRoot" false -}} + {{- else -}} + {{- $_ := set $secContext "runAsNonRoot" true -}} + {{- end -}} + + {{- if $secContext.privileged -}} {{/* When privileged is true, allowPrivilegeEscalation is required */}} + {{- $_ := set $secContext "allowPrivilegeEscalation" true -}} + {{- end -}} + + {{- if $mustPrivileged -}} + {{- $_ := set $secContext "privileged" true -}} + {{- $_ := set $secContext "allowPrivilegeEscalation" true -}} + {{- $_ := set $secContext "runAsNonRoot" false -}} + {{- $_ := set $secContext "runAsUser" 0 -}} + {{- $_ := set $secContext "runAsGroup" 0 -}} + {{- end -}} + + {{- range $key := (list "privileged" "allowPrivilegeEscalation" "runAsNonRoot" "readOnlyRootFilesystem") -}} + {{- $value := (get $secContext $key) -}} + {{- if not (kindIs "bool" $value) -}} + {{- fail (printf "Container - Expected to be [bool], but got [%s] of type [%s]" $key $value (kindOf $value)) -}} + {{- end -}} + {{- end -}} + + {{- if not $secContext.seccompProfile -}} + {{- fail "Container - Expected to be defined" -}} + {{- end -}} + + {{- $profiles := (list "RuntimeDefault" "Localhost" "Unconfined") -}} + {{- if not (mustHas $secContext.seccompProfile.type $profiles) -}} + {{- fail (printf "Container - Expected to be one of [%s], but got [%s]" (join ", " $profiles) $secContext.seccompProfile.type) -}} + {{- end -}} + + {{- if eq $secContext.seccompProfile.type "Localhost" -}} + {{- if not $secContext.seccompProfile.profile -}} + {{- fail "Container - Expected to be defined on type [Localhost]" -}} + {{- end -}} + {{- end -}} + + {{- if not $secContext.capabilities -}} + {{- fail "Container - Expected to be defined" -}} + {{- end -}} + + {{- $tempObjectData := (dict "shortName" $objectData.podShortName "primary" $objectData.podPrimary) -}} + {{- $portRange := fromJson (include "tc.v1.common.lib.helpers.securityContext.getPortRange" (dict "rootCtx" $rootCtx "objectData" $tempObjectData)) -}} + {{- if and $portRange.low (le (int $portRange.low) 1024) -}} {{/* If a container wants to bind a port <= 1024 add NET_BIND_SERVICE */}} + {{- $addCap := $secContext.capabilities.add -}} + {{- if not (mustHas "NET_BIND_SERIVCE" $addCap) -}} + {{- $addCap = mustAppend $addCap "NET_BIND_SERVICE" -}} + {{- end -}} + {{- $_ := set $secContext.capabilities "add" $addCap -}} + {{- end -}} + + {{/* + Most containers that run as root, is because it has to chown + files before switching to another user. + Lets add automatically the CHOWN cap. + */}} + {{- if eq (int $secContext.runAsUser) 0 -}} + + {{- if not (kindIs "bool" $secContext.capabilities.disableS6Caps) -}} + {{- fail (printf "Container - Expected to be [bool], but got [%s] of type [%s]" $secContext.capabilities.disableS6Caps (kindOf $secContext.capabilities.disableS6Caps)) -}} + {{- end -}} + + {{- $addCap := $secContext.capabilities.add -}} + + {{- if not $secContext.capabilities.disableS6Caps -}} + {{- $addCap = mustAppend $addCap "CHOWN" -}} + {{- $addCap = mustAppend $addCap "SETUID" -}} + {{- $addCap = mustAppend $addCap "SETGID" -}} + {{- $addCap = mustAppend $addCap "FOWNER" -}} + {{- $addCap = mustAppend $addCap "DAC_OVERRIDE" -}} + {{- end -}} + + {{- $_ := set $secContext.capabilities "add" $addCap -}} + {{- end -}} + + {{- range $key := (list "add" "drop") -}} + {{- $item := (get $secContext.capabilities $key) -}} + {{- if not (kindIs "slice" $item) -}} + {{- fail (printf "Container - Expected to be [list], but got [%s]" $key (kindOf $item)) -}} + {{- end -}} + + {{- range $item -}} + {{- if not (kindIs "string" .) -}} + {{- fail (printf "Container - Expected items of to be [string], but got [%s]" $key (kindOf .)) -}} + {{- end -}} + {{- end -}} + + {{- if not (deepEqual (uniq $item) $item) -}} + {{- fail (printf "Container - Expected items of to be unique, but got [%s]" $key (join ", " $item)) -}} + {{- end -}} + {{- end -}} + + {{- $secContext | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_termination.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_termination.tpl new file mode 100644 index 0000000..5d04a8f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_termination.tpl @@ -0,0 +1,33 @@ +{{/* Returns termination */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.termination" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.termination" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $termination := (dict "messagePath" "" "messagePolicy" "") -}} + + {{- with $objectData.termination -}} + {{- with .messagePath -}} + {{- $_ := set $termination "messagePath" (tpl . $rootCtx) -}} + {{- end -}} + + {{- with .messagePolicy -}} + + {{- $policy := (tpl . $rootCtx) -}} + + {{- $policies := (list "File" "FallbackToLogsOnError") -}} + {{- if not (mustHas $policy $policies) -}} + {{- fail (printf "Container - Expected to be one of [%s], but got [%s]" (join ", " $policies) $policy) -}} + {{- end -}} + + {{- $_ := set $termination "messagePolicy" $policy -}} + {{- end -}} + + {{- end -}} + + {{- $termination | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/_volumeMounts.tpl b/helm-charts/dashy/charts/common/templates/lib/container/_volumeMounts.tpl new file mode 100644 index 0000000..027cdc4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/_volumeMounts.tpl @@ -0,0 +1,147 @@ +{{/* Returns volumeMount list */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.volumeMount" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.volumeMount" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $volMounts := list -}} + + {{- $codeServerIgnoredTypes := (list "configmap" "secret") -}} + {{- $keys := (list "persistence") -}} + {{- if eq $objectData.podType "StatefulSet" -}} + {{- $keys = mustAppend $keys "volumeClaimTemplates" -}} + {{- end -}} + + {{- range $key := $keys -}} + {{- range $persistenceName, $persistenceValues := (get $rootCtx.Values $key) -}} + {{- if $persistenceValues.enabled -}} + {{/* Dont try to mount configmap/sercet to codeserver */}} + {{- if not (and (eq $objectData.shortName "codeserver") (mustHas $persistenceValues.type $codeServerIgnoredTypes)) -}} + {{- $volMount := (fromJson (include "tc.v1.common.lib.container.volumeMount.isSelected" (dict "persistenceName" $persistenceName "persistenceValues" $persistenceValues "objectData" $objectData "key" $key))) -}} + {{- if $volMount -}} + {{- $volMounts = mustAppend $volMounts $volMount -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- range $volMount := $volMounts -}} + {{/* Expand values */}} + {{- $_ := set $volMount "mountPath" (tpl $volMount.mountPath $rootCtx) -}} + {{- $_ := set $volMount "subPath" (tpl $volMount.subPath $rootCtx) -}} + {{- $_ := set $volMount "mountPropagation" (tpl $volMount.mountPropagation $rootCtx) -}} + + {{- if not $volMount.mountPath -}} + {{- fail (printf "%s - Expected non-empty " (camelcase $volMount.key)) -}} + {{- end -}} + + {{- if not (hasPrefix "/" $volMount.mountPath) -}} + {{- fail (printf "%s - Expected to start with a forward slash [/]" (camelcase $volMount.key)) -}} + {{- end -}} + + {{- $propagationTypes := (list "None" "HostToContainer" "Bidirectional") -}} + {{- if and $volMount.mountPropagation (not (mustHas $volMount.mountPropagation $propagationTypes)) -}} + {{- fail (printf "%s - Expected to be one of [%s], but got [%s]" (camelcase $volMount.key) (join ", " $propagationTypes) $volMount.mountPropagation) -}} + {{- end -}} + + {{- if not (kindIs "bool" $volMount.readOnly) -}} + {{- fail (printf "%s - Expected to be [boolean], but got [%s]" (camelcase $volMount.key) (kindOf $volMount.readOnly)) -}} + {{- end }} +- name: {{ $volMount.name }} + mountPath: {{ $volMount.mountPath }} + readOnly: {{ $volMount.readOnly }} + {{- with $volMount.subPath }} + subPath: {{ . }} + {{- end -}} + {{- with $volMount.mountPropagation }} + mountPropagation: {{ . }} + {{- end -}} + {{- end -}} + +{{- end -}} + +{{- define "tc.v1.common.lib.container.volumeMount.isSelected" -}} + {{- $persistenceName := .persistenceName -}} + {{- $persistenceValues := .persistenceValues -}} + {{- $objectData := .objectData -}} + {{- $key := .key -}} + + {{/* Initialize from the default values */}} + {{- $volMount := dict -}} + {{- $_ := set $volMount "name" $persistenceName -}} + {{- $_ := set $volMount "key" $key -}} + {{- if eq $persistenceValues.type "device" -}} {{/* On devices use the hostPath as default if mountpath is not defined */}} + {{- $_ := set $volMount "mountPath" ($persistenceValues.mountPath | default $persistenceValues.hostPath | default "") -}} + {{- else -}} + {{- $_ := set $volMount "mountPath" ($persistenceValues.mountPath | default "") -}} + {{- end -}} + {{- $_ := set $volMount "subPath" ($persistenceValues.subPath | default "") -}} + {{- $_ := set $volMount "readOnly" ($persistenceValues.readOnly | default false) -}} + {{- $_ := set $volMount "mountPropagation" ($persistenceValues.mountPropagation | default "") -}} + + {{- $return := false -}} + {{/* If targetSelectAll is set, means all pods/containers */}} {{/* targetSelectAll does not make sense for vct */}} + {{- if and $persistenceValues.targetSelectAll (ne $key "volumeClaimTemplates") -}} + {{- $return = true -}} + {{/* Set custom path on autopermissions container */}} + {{- if and (eq $objectData.shortName "autopermissions") $persistenceValues.autoPermissions -}} + {{- if $persistenceValues.autoPermissions.enabled -}} + {{- $return = true -}} + {{- $_ := set $volMount "mountPath" (printf "/mounts/%v" $persistenceName) -}} + {{- end -}} + {{- end -}} + + {{/* If the container is the autopermission */}} + {{- else if (eq $objectData.shortName "autopermissions") -}} + {{- if $persistenceValues.autoPermissions -}} + {{- if $persistenceValues.autoPermissions.enabled -}} + {{- $return = true -}} + {{- $_ := set $volMount "mountPath" (printf "/mounts/%v" $persistenceName) -}} + {{- end -}} + {{- end -}} + + {{/* Else if selector is defined */}} + {{- else if $persistenceValues.targetSelector -}} + {{/* If pod is selected */}} + {{- if mustHas $objectData.podShortName ($persistenceValues.targetSelector | keys) -}} + {{- $selectorValues := (get $persistenceValues.targetSelector $objectData.podShortName) -}} + {{- if not (kindIs "map" $selectorValues) -}} + {{- fail (printf "%s - Expected to be a [dict], but got [%s]" (camelcase $key) $objectData.podShortName (kindOf $selectorValues)) -}} + {{- end -}} + + {{- if not $selectorValues -}} + {{- fail (printf "%s - Expected non-empty " (camelcase $key) $objectData.podShortName) -}} + {{- end -}} + + {{/* If container is selected */}} + {{- if or (mustHas $objectData.shortName ($selectorValues | keys)) (eq $objectData.shortName "codeserver") -}} + {{/* Merge with values that might be set for the specific container */}} + {{- $fetchedSelectorValues := (get $selectorValues $objectData.shortName) -}} + {{- if and (eq $objectData.shortName "codeserver") (not $fetchedSelectorValues) -}} + {{- $fetchedSelectorValues = (get $selectorValues ($selectorValues | keys | first)) -}} + {{- end -}} + {{- $volMount = mustMergeOverwrite $volMount $fetchedSelectorValues -}} + {{- $return = true -}} + {{- end -}} + {{- end -}} + + {{/* if its the codeserver */}} + {{- else if (eq $objectData.shortName "codeserver") -}} + {{- $return = true -}} + + {{/* Else if not selector, but pod and container is primary */}} + {{- else if and $objectData.podPrimary $objectData.primary -}} + {{- $return = true -}} + {{- end -}} + + {{- if $return -}} {{/* If it's selected, return the volumeMount */}} + {{- $volMount | toJson -}} + {{- else -}} {{/* Else return an empty dict */}} + {{- dict | toJson -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_exec.tpl b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_exec.tpl new file mode 100644 index 0000000..505a90b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_exec.tpl @@ -0,0 +1,18 @@ +{{/* Returns exec action */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.actions.exec" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.actions.exec" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- if not $objectData.command -}} + {{- fail (printf "Container - Expected non-empty <%s> on [exec] type" $caller) -}} + {{- end }} +exec: + command: + {{- include "tc.v1.common.lib.container.command" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_grpc.tpl b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_grpc.tpl new file mode 100644 index 0000000..29660ad --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_grpc.tpl @@ -0,0 +1,23 @@ +{{/* Returns grpc action */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.actions.grpc" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- if not $objectData.port -}} + {{- fail (printf "Container - Expected non-empty <%s> on [grpc] type" $caller) -}} + {{- end -}} + + {{- $port := $objectData.port -}} + + {{- if kindIs "string" $port -}} + {{- $port = tpl $port $rootCtx -}} + {{- end }} +grpc: + port: {{ $port }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_httpGet.tpl b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_httpGet.tpl new file mode 100644 index 0000000..029ab50 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_httpGet.tpl @@ -0,0 +1,53 @@ +{{/* Returns httpGet action */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.actions.httpGet" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.actions.httpGet" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- if not $objectData.port -}} + {{- fail (printf "Container - Expected non-empty <%s> on [http] type" $caller) -}} + {{- end -}} + + {{- $port := $objectData.port -}} + {{- $path := "/" -}} + {{- $scheme := "http" -}} + + {{- if kindIs "string" $port -}} + {{- $port = tpl $port $rootCtx -}} + {{- end -}} + + {{- with $objectData.path -}} + {{- $path = tpl . $rootCtx -}} + {{- end -}} + + {{- if not (hasPrefix "/" $path) -}} + {{- fail (printf "Container - Expected <%s> to start with a forward slash [/] on type" $caller) -}} + {{- end -}} + + {{- with $objectData.type -}} + {{- $scheme = tpl . $rootCtx -}} + {{- end }} +httpGet: + {{- with $objectData.host }} + host: {{ tpl . $rootCtx }} + {{- end }} + port: {{ $port }} + path: {{ $path }} + scheme: {{ $scheme | upper }} + {{- with $objectData.httpHeaders }} + httpHeaders: + {{- range $name, $value := . }} + {{- if not $value -}} + {{- fail "Container - Expected non-empty on " -}} + {{- end }} + - name: {{ $name }} + value: {{ tpl (toString $value) $rootCtx | quote }} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_tcpSocket.tpl b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_tcpSocket.tpl new file mode 100644 index 0000000..2425fd3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/container/probe-lifecycle-actions/_tcpSocket.tpl @@ -0,0 +1,23 @@ +{{/* Returns tcpSocket action */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.container.actions.tcpSocket" (dict "rootCtx" $ "objectData" $objectData "caller" $caller) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the container. +*/}} +{{- define "tc.v1.common.lib.container.actions.tcpSocket" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- if not $objectData.port -}} + {{- fail (printf "Container - Expected non-empty <%s> on [tcp] type" $caller) -}} + {{- end -}} + + {{- $port := $objectData.port -}} + + {{- if kindIs "string" $port -}} + {{- $port = tpl $port $rootCtx -}} + {{- end }} +tcpSocket: + port: {{ $port }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_clickhouseInjector.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_clickhouseInjector.tpl new file mode 100644 index 0000000..6a4c0b0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_clickhouseInjector.tpl @@ -0,0 +1,55 @@ +{{/* + This template generates a random password and ensures it persists across updates/edits to the chart +*/}} +{{- define "tc.v1.common.dependencies.clickhouse.secret" -}} + +{{- if .Values.clickhouse.enabled -}} + {{/* Initialize variables */}} + {{- $fetchname := printf "%s-clickhousecreds" .Release.Name -}} + {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace $fetchname -}} + {{- $dbpreviousold := lookup "v1" "Secret" .Release.Namespace "clickhousecreds" -}} + {{- $dbPass := randAlphaNum 50 -}} + + {{/* If there are previous secrets, fetch values and decrypt them */}} + {{- if $dbprevious -}} + {{- $dbPass = (index $dbprevious.data "clickhouse-password") | b64dec -}} + {{- else if $dbpreviousold -}} + {{- $dbPass = (index $dbpreviousold.data "clickhouse-password") | b64dec -}} + {{- end -}} + + {{/* Prepare data */}} + {{- $dbHost := printf "%v-%v" .Release.Name "clickhouse" -}} + {{- $portHost := printf "%v:8123" $dbHost -}} + {{- $ping := printf "http://%v/ping" $portHost -}} + {{- $url := printf "http://%v:%v@%v/%v" .Values.clickhouse.clickhouseUsername $dbPass $portHost .Values.clickhouse.clickhouseDatabase -}} + {{- $jdbc := printf "jdbc:ch://%v/%v" $portHost -}} + + {{/* Append some values to clickhouse.creds, so apps using the dep, can use them */}} + {{- $_ := set .Values.clickhouse.creds "plain" ($dbHost | quote) -}} + {{- $_ := set .Values.clickhouse.creds "plainhost" ($dbHost | quote) -}} + {{- $_ := set .Values.clickhouse.creds "clickhousePassword" ($dbPass | quote) -}} + {{- $_ := set .Values.clickhouse.creds "plainport" ($portHost | quote) -}} + {{- $_ := set .Values.clickhouse.creds "plainporthost" ($portHost | quote) -}} + {{- $_ := set .Values.clickhouse.creds "ping" ($ping | quote) -}} + {{- $_ := set .Values.clickhouse.creds "complete" ($url | quote) -}} + {{- $_ := set .Values.clickhouse.creds "jdbc" ($jdbc | quote) -}} + +{{/* Create the secret (Comment also plays a role on correct formatting) */}} +enabled: true +expandObjectName: false +data: + clickhouse-password: {{ $dbPass }} + plainhost: {{ $dbHost }} + plainporthost: {{ $portHost }} + ping: {{ $ping }} + url: {{ $url }} + jdbc: {{ $jdbc }} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.clickhouse.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.clickhouse.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret ( printf "%s-%s" .Release.Name "clickhousecreds" ) $secret -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_dbWait.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_dbWait.tpl new file mode 100644 index 0000000..0dcd4e9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_dbWait.tpl @@ -0,0 +1,387 @@ +{{- define "tc.v1.common.lib.deps.wait" -}} + {{- if .Values.redis.enabled -}} + {{- $container := include "tc.v1.common.lib.deps.wait.redis" $ | fromYaml -}} + {{- if $container -}} + {{- range .Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "redis-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if .Values.mariadb.enabled -}} + {{- $container := include "tc.v1.common.lib.deps.wait.mariadb" $ | fromYaml -}} + {{- if $container -}} + {{- range .Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "mariadb-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if .Values.mongodb.enabled -}} + {{- $container := include "tc.v1.common.lib.deps.wait.mongodb" $ | fromYaml -}} + {{- if $container -}} + {{- range .Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "mongodb-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if .Values.clickhouse.enabled -}} + {{- $container := include "tc.v1.common.lib.deps.wait.clickhouse" $ | fromYaml -}} + {{- if $container -}} + {{- range .Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "clickhouse-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if .Values.solr.enabled -}} + {{- $container := include "tc.v1.common.lib.deps.wait.solr" $ | fromYaml -}} + {{- if $container -}} + {{- range .Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "solr-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $result := false -}} + {{- range .Values.cnpg -}} + {{- if .enabled -}} + {{- $result = true -}} + {{- end -}} + {{- end -}} + + {{- if $result -}} + {{- $container := include "tc.v1.common.lib.deps.wait.cnpg" $ | fromYaml -}} + {{- if $container -}} + {{- range $.Values.workload -}} + {{- if not (hasKey .podSpec "initContainers") -}} + {{- $_ := set .podSpec "initContainers" dict -}} + {{- end -}} + {{- $_ := set .podSpec.initContainers "cnpg-wait" $container -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.redis" -}} +enabled: true +type: system +imageSelector: redisClientImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +env: + REDIS_HOST: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "rediscreds" }}' + key: plainhost + REDIS_PASSWORD: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "rediscreds" }}' + key: redis-password + REDIS_PORT: "6379" +command: + - "/bin/sh" + - "-c" + - | + /bin/bash <<'EOF' + echo "Executing DB waits..." + [[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"; + export LIVE=false; + until "$LIVE"; + do + response=$( + timeout -s 3 2 \ + redis-cli \ + -h "$REDIS_HOST" \ + -p "$REDIS_PORT" \ + ping + ) + if [ "$response" == "PONG" ] || [ "$response" == "LOADING Redis is loading the dataset in memory" ]; then + LIVE=true + echo "$response" + echo "Redis Responded, ending initcontainer and starting main container(s)..." + else + echo "$response" + echo "Redis not responding... Sleeping for 10 sec..." + sleep 10 + fi; + done + EOF +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.mariadb" -}} +enabled: true +type: system +imageSelector: mariadbClientImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi +env: + MARIADB_HOST: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "mariadbcreds" }}' + key: plainhost + MARIADB_ROOT_PASSWORD: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "mariadbcreds" }}' + key: mariadb-root-password +command: + - "/bin/sh" + - "-c" + - | + /bin/bash <<'EOF' + echo "Executing DB waits..." + until + mysqladmin -uroot -h"${MARIADB_HOST}" -p"${MARIADB_ROOT_PASSWORD}" ping \ + && mysqladmin -uroot -h"${MARIADB_HOST}" -p"${MARIADB_ROOT_PASSWORD}" status; + do sleep 2; + done + EOF +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.mongodb" -}} +enabled: true +type: system +imageSelector: mongodbClientImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi +env: + MONGODB_HOST: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "mongodbcreds" }}' + key: plainhost + MONGODB_DATABASE: "{{ .Values.mongodb.mongodbDatabase }}" +command: + - "/bin/sh" + - "-c" + - | + /bin/bash <<'EOF' + echo "Executing DB waits..." + until + HOME=/config && echo "db.runCommand(\"ping\")" | mongosh --host ${MONGODB_HOST} --port 27017 ${MONGODB_DATABASE} --quiet; + do sleep 2; + done + EOF +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.clickhouse" -}} +enabled: true +type: system +imageSelector: wgetImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi +env: + CLICKHOUSE_PING: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "clickhousecreds" }}' + key: ping +command: + - "/bin/sh" +args: + - "-c" + - | + echo "Executing DB waits..." + until wget --quiet --tries=1 --spider "${CLICKHOUSE_PING}"; do + echo "ClickHouse - no response. Sleeping 2 seconds..." + sleep 2 + done + echo "ClickHouse - accepting connections" +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.solr" -}} +enabled: true +type: system +imageSelector: wgetImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi +env: + SOLR_HOST: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "solrcreds" }}' + key: plainhost + SOLR_CORES: "{{ .Values.solr.solrCores }}" + SOLR_ENABLE_AUTHENTICATION: "{{ .Values.solr.solrEnableAuthentication }}" + SOLR_ADMIN_USERNAME: "{{ .Values.solr.solrUsername }}" + SOLR_ADMIN_PASSWORD: + secretKeyRef: + expandObjectName: false + name: '{{ printf "%s-%s" .Release.Name "solrcreds" }}' + key: solr-password + +command: + - "/bin/sh" +args: + - "-c" + - | + echo "Executing DB waits..." + if [ "$SOLR_ENABLE_AUTHENTICATION" == "yes" ]; then + until curl --fail --user "${SOLR_ADMIN_USERNAME}":"${SOLR_ADMIN_PASSWORD}" "${SOLR_HOST}":8983/solr/"${SOLR_CORES}"/admin/ping; do + echo "Solr is not responding... Sleeping 2 seconds..." + sleep 2 + done + else + until curl --fail "${SOLR_HOST}":8983/solr/"${SOLR_CORES}"/admin/ping; do + echo "Solr is not responding... Sleeping 2 seconds..." + sleep 2 + done + fi +{{- end -}} + +{{- define "tc.v1.common.lib.deps.wait.cnpg" -}} +enabled: true +type: system +imageSelector: postgresClientImage +securityContext: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL +resources: + requests: + cpu: 10m + memory: 50Mi + limits: + cpu: 4000m + memory: 8Gi +command: + - "/bin/sh" + - "-c" + - | + /bin/sh <<'EOF' + {{ range $name, $cnpg := .Values.cnpg }} + {{ if $cnpg.enabled }} + echo "Executing DB waits..." + {{ $cnpgName := include "tc.v1.common.lib.chart.names.fullname" $ }} + {{ $cnpgName = printf "%v-cnpg-%v" $cnpgName $name }} + echo "Detected RW pooler, testing RW pooler availability..." + until + echo "Testing database on url: {{ $cnpgName }}-rw" + pg_isready -U {{ .user }} -d {{ .database }} -h {{ $cnpgName }}-rw + do sleep 5 + done + {{ if $cnpg.acceptRO }} + echo "Detected RO pooler, testing RO pooler availability..." + until + echo "Testing database on url: {{ $cnpgName }}-ro" + pg_isready -U {{ .user }} -d {{ .database }} -h {{ $cnpgName }}-ro + do sleep 5 + done + {{ end }} + {{ end }} + {{ end }} + sleep 5 + EOF +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_mariadbInjector.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_mariadbInjector.tpl new file mode 100644 index 0000000..59565f7 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_mariadbInjector.tpl @@ -0,0 +1,66 @@ +{{/* +This template generates a random password and ensures it persists across updates/edits to the chart +*/}} +{{- define "tc.v1.common.dependencies.mariadb.secret" -}} + +{{- if .Values.mariadb.enabled -}} + {{/* Initialize variables */}} + {{- $fetchname := printf "%s-mariadbcreds" .Release.Name -}} + {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace $fetchname -}} + {{- $dbpreviousold := lookup "v1" "Secret" .Release.Namespace "mariadbcreds" -}} + {{- $dbPass := randAlphaNum 50 -}} + {{- $rootPass := randAlphaNum 50 -}} + + {{/* If there are previous secrets, fetch values and decrypt them */}} + {{- if $dbprevious -}} + {{- $dbPass = (index $dbprevious.data "mariadb-password") | b64dec -}} + {{- $rootPass = (index $dbprevious.data "mariadb-root-password") | b64dec -}} + {{- else if $dbpreviousold -}} + {{- $dbPass = (index $dbpreviousold.data "mariadb-password") | b64dec -}} + {{- $rootPass = (index $dbpreviousold.data "mariadb-root-password") | b64dec -}} + {{- end -}} + + {{/* Prepare data */}} + {{- $dbhost := printf "%v-%v" .Release.Name "mariadb" -}} + {{- $portHost := printf "%v:3306" $dbhost -}} + {{- $complete := printf "sql://%v:%v@%v/%v" .Values.mariadb.mariadbUsername $dbPass $portHost .Values.mariadb.mariadbDatabase -}} + {{- $urlnossl := printf "sql://%v:%v@%v/%v?sslmode=disable" .Values.mariadb.mariadbUsername $dbPass $portHost .Values.mariadb.mariadbDatabase -}} + {{- $jdbc := printf "jdbc:sqlserver://%v/%v" $portHost .Values.mariadb.mariadbDatabase -}} + {{- $jdbcMySQL := printf "jdbc:mysql://%v/%v" $portHost .Values.mariadb.mariadbDatabase -}} + {{- $jdbcMariaDB := printf "jdbc:mariadb://%v/%v" $portHost .Values.mariadb.mariadbDatabase -}} + + {{/* Append some values to mariadb.creds, so apps using the dep, can use them */}} + {{- $_ := set .Values.mariadb.creds "mariadbPassword" ($dbPass | quote) -}} + {{- $_ := set .Values.mariadb.creds "mariadbRootPassword" ($rootPass | quote) -}} + {{- $_ := set .Values.mariadb.creds "plain" ($dbhost | quote) -}} + {{- $_ := set .Values.mariadb.creds "plainhost" ($dbhost | quote) -}} + {{- $_ := set .Values.mariadb.creds "plainport" ($portHost | quote) -}} + {{- $_ := set .Values.mariadb.creds "plainporthost" ($portHost | quote) -}} + {{- $_ := set .Values.mariadb.creds "complete" ($complete | quote) -}} + {{- $_ := set .Values.mariadb.creds "urlnossl" ($urlnossl | quote) -}} + {{- $_ := set .Values.mariadb.creds "jdbc" ($jdbc | quote) -}} + {{- $_ := set .Values.mariadb.creds "jdbcmysql" ($jdbcMySQL | quote) -}} + {{- $_ := set .Values.mariadb.creds "jdbcmariadb" ($jdbcMariaDB | quote) -}} + +{{/* Create the secret (Comment also plays a role on correct formatting) */}} +enabled: true +expandObjectName: false +data: + mariadb-password: {{ $dbPass }} + mariadb-root-password: {{ $rootPass }} + url: {{ $complete }} + urlnossl: {{ $urlnossl }} + plainporthost: {{ $portHost }} + plainhost: {{ $dbhost }} + jdbc: {{ $jdbc }} + jdbc-mysql: {{ $jdbcMySQL }} + jdbc-mariadb: {{ $jdbcMariaDB }} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.mariadb.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.mariadb.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "mariadbcreds") $secret -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_mongodbInjector.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_mongodbInjector.tpl new file mode 100644 index 0000000..12f0ff6 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_mongodbInjector.tpl @@ -0,0 +1,63 @@ +{{/* +This template generates a random password and ensures it persists across updates/edits to the chart +*/}} +{{- define "tc.v1.common.dependencies.mongodb.secret" -}} + +{{- if .Values.mongodb.enabled -}} + {{/* Initialize variables */}} + {{- $fetchname := printf "%s-mongodbcreds" .Release.Name -}} + {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace $fetchname -}} + {{- $dbpreviousold := lookup "v1" "Secret" .Release.Namespace "mongodbcreds" -}} + {{- $dbPass := randAlphaNum 50 -}} + {{- $rootPass := randAlphaNum 50 -}} + + {{/* If there are previous secrets, fetch values and decrypt them */}} + {{- if $dbprevious -}} + {{- $dbPass = (index $dbprevious.data "mongodb-password") | b64dec -}} + {{- $rootPass = (index $dbprevious.data "mongodb-root-password") | b64dec -}} + {{- else if $dbpreviousold -}} + {{- $dbPass = (index $dbpreviousold.data "mongodb-password") | b64dec -}} + {{- $rootPass = (index $dbpreviousold.data "mongodb-root-password") | b64dec -}} + {{- end -}} + + {{/* Prepare data */}} + {{- $dbhost := printf "%v-%v" .Release.Name "mongodb" -}} + {{- $portHost := printf "%v:27017" $dbhost -}} + {{- $jdbc := printf "jdbc:mongodb://%v/%v" $portHost .Values.mongodb.mongodbDatabase -}} + {{- $url := printf "mongodb://%v:%v@%v/%v" .Values.mongodb.mongodbUsername $dbPass $portHost .Values.mongodb.mongodbDatabase -}} + {{- $urlssl := printf "%v?ssl=true" $url -}} + {{- $urltls := printf "%v?tls=true" $url -}} + + {{/* Append some values to mongodb.creds, so apps using the dep, can use them */}} + {{- $_ := set .Values.mongodb.creds "mongodbPassword" ($dbPass | quote) -}} + {{- $_ := set .Values.mongodb.creds "mongodbRootPassword" ($rootPass | quote) -}} + {{- $_ := set .Values.mongodb.creds "plain" ($dbhost | quote) -}} + {{- $_ := set .Values.mongodb.creds "plainhost" ($dbhost | quote) -}} + {{- $_ := set .Values.mongodb.creds "plainport" ($portHost | quote) -}} + {{- $_ := set .Values.mongodb.creds "plainporthost" ($portHost | quote) -}} + {{- $_ := set .Values.mongodb.creds "complete" ($url | quote) -}} + {{- $_ := set .Values.mongodb.creds "urlssl" ($urlssl | quote) -}} + {{- $_ := set .Values.mongodb.creds "urltls" ($urltls | quote) -}} + {{- $_ := set .Values.mongodb.creds "jdbc" ($jdbc | quote) -}} + +{{/* Create the secret (Comment also plays a role on correct formatting) */}} +enabled: true +expandObjectName: false +data: + mongodb-password: {{ $dbPass }} + mongodb-root-password: {{ $rootPass }} + url: {{ $url }} + urlssl: {{ $urlssl }} + urltls: {{ $urltls }} + jdbc: {{ $jdbc }} + plainhost: {{ $dbhost }} + plainporthost: {{ $portHost }} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.mongodb.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.mongodb.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "mongodbcreds") $secret -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_redisInjector.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_redisInjector.tpl new file mode 100644 index 0000000..e4a6dbe --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_redisInjector.tpl @@ -0,0 +1,55 @@ +{{/* +This template generates a random password and ensures it persists across updates/edits to the chart +*/}} +{{- define "tc.v1.common.dependencies.redis.secret" -}} + +{{- if .Values.redis.enabled -}} + {{/* Initialize variables */}} + {{- $fetchname := printf "%s-rediscreds" .Release.Name -}} + {{- $dbprevious := lookup "v1" "Secret" .Release.Namespace $fetchname -}} + {{- $dbPass := randAlphaNum 50 -}} + {{- $dbIndex := .Values.redis.redisDatabase | default "0" -}} + + {{/* If there are previous secrets, fetch values and decrypt them */}} + {{- if $dbprevious -}} + {{- $dbPass = (index $dbprevious.data "redis-password") | b64dec -}} + {{- end -}} + + {{- $redisUser := .Values.redis.redisUsername -}} + {{- if not $redisUser -}}{{/* If you try to print a nil value it will print as */}} + {{- $redisUser = "" -}} + {{- end -}} + {{/* Prepare data */}} + {{- $dbHost := printf "%v-%v" .Release.Name "redis" -}} + {{- $portHost := printf "%v:6379" $dbHost -}} + {{- $url := printf "redis://%v:%v@%v/%v" $redisUser $dbPass $portHost $dbIndex -}} + {{- $hostPass := printf "%v:%v@%v" $redisUser $dbPass $dbHost -}} + + {{/* Append some values to redis.creds, so apps using the dep, can use them */}} + {{- $_ := set .Values.redis.creds "redisPassword" ($dbPass | quote) -}} + {{- $_ := set .Values.redis.creds "plain" ($dbHost | quote) -}} + {{- $_ := set .Values.redis.creds "plainhost" ($dbHost | quote) -}} + {{- $_ := set .Values.redis.creds "plainport" ($portHost | quote) -}} + {{- $_ := set .Values.redis.creds "plainporthost" ($portHost | quote) -}} + {{- $_ := set .Values.redis.creds "plainhostpass" ($hostPass | quote) -}} + {{- $_ := set .Values.redis.creds "url" ($url | quote) -}} + +{{/* Create the secret (Comment also plays a role on correct formatting) */}} +enabled: true +expandObjectName: false +data: + redis-password: {{ $dbPass }} + plain: {{ $dbHost }} + url: {{ $url }} + plainhostpass: {{ $hostPass }} + plainporthost: {{ $portHost }} + plainhost: {{ $dbHost }} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.redis.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.redis.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "rediscreds") $secret -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/dependencies/_solrInjector.tpl b/helm-charts/dashy/charts/common/templates/lib/dependencies/_solrInjector.tpl new file mode 100644 index 0000000..32d33f2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/dependencies/_solrInjector.tpl @@ -0,0 +1,47 @@ +{{/* +This template generates a random password and ensures it persists across updates/edits to the chart +*/}} +{{- define "tc.v1.common.dependencies.solr.secret" -}} + +{{- if .Values.solr.enabled -}} + {{/* Initialize variables */}} + {{- $fetchname := printf "%s-solrcreds" .Release.Name -}} + {{- $solrprevious := lookup "v1" "Secret" .Release.Namespace $fetchname -}} + {{- $solrpreviousold := lookup "v1" "Secret" .Release.Namespace "solrcreds" -}} + {{- $solrPass := randAlphaNum 50 -}} + + {{/* If there are previous secrets, fetch values and decrypt them */}} + {{- if $solrprevious -}} + {{- $solrPass = (index $solrprevious.data "solr-password") | b64dec -}} + {{- else if $solrpreviousold -}} + {{- $solrPass = (index $solrpreviousold.data "solr-password") | b64dec -}} + {{- end -}} + + {{/* Prepare data */}} + {{- $dbHost := printf "%v-%v" .Release.Name "solr" -}} + {{- $portHost := printf "%v:8983" $dbHost -}} + {{- $url := printf "http://%v:%v@%v/url/%v" .Values.solr.solrUsername $solrPass $portHost .Values.solr.solrCores -}} + + {{/* Append some values to solr.creds, so apps using the dep, can use them */}} + {{- $_ := set .Values.solr.creds "solrPassword" ($solrPass | quote) -}} + {{- $_ := set .Values.solr.creds "plain" ($dbHost | quote) -}} + {{- $_ := set .Values.solr.creds "plainhost" ($dbHost | quote) -}} + {{- $_ := set .Values.solr.creds "portHost" ($portHost | quote) -}} + {{- $_ := set .Values.solr.creds "url" ($url | quote) -}} + +{{/* Create the secret (Comment also plays a role on correct formatting) */}} +enabled: true +expandObjectName: false +data: + solr-password: {{ $solrPass }} + url: {{ $url }} + plainhost: {{ $dbHost }} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.dependencies.solr.injector" -}} + {{- $secret := include "tc.v1.common.dependencies.solr.secret" . | fromYaml -}} + {{- if $secret -}} + {{- $_ := set .Values.secret (printf "%s-%s" .Release.Name "solrcreds") $secret -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/endpoint/_addresses.tpl b/helm-charts/dashy/charts/common/templates/lib/endpoint/_addresses.tpl new file mode 100644 index 0000000..381bb1f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/endpoint/_addresses.tpl @@ -0,0 +1,20 @@ +{{/* Endpoint - addresses */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.endpoint.addresses" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +*/}} + +{{- define "tc.v1.common.lib.endpoint.addresses" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.externalIP -}} + {{- fail "EndpointSlice - Expected non-empty " -}} + {{- end -}} + + {{- if not (kindIs "string" $objectData.externalIP) -}} {{/* Only single IP is supported currently on this lib */}} + {{- fail (printf "EndpointSlice - Expected to be a [string], but got [%s]" (kindOf $objectData.externalIP)) -}} + {{- end }} + - ip: {{ tpl $objectData.externalIP $rootCtx }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/endpoint/_ports.tpl b/helm-charts/dashy/charts/common/templates/lib/endpoint/_ports.tpl new file mode 100644 index 0000000..f0f9b93 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/endpoint/_ports.tpl @@ -0,0 +1,40 @@ +{{/* Endpoint - Ports */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.endpoint.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +*/}} + +{{- define "tc.v1.common.lib.endpoint.ports" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $tcpProtocols := (list "tcp" "http" "https") -}} + {{- range $name, $portValues := $objectData.ports -}} + {{- if $portValues.enabled -}} + {{- $protocol := $rootCtx.Values.fallbackDefaults.serviceProtocol -}} {{/* Default to fallback protocol, if no protocol is defined */}} + {{- $port := $portValues.targetPort | default $portValues.port -}} + + {{/* Expand targetPort */}} + {{- if (kindIs "string" $port) -}} + {{- $port = (tpl $port $rootCtx) -}} + {{- end -}} + {{- $port = int $port -}} + + {{- with $portValues.protocol -}} + {{- $protocol = tpl . $rootCtx -}} + + {{- if mustHas $protocol $tcpProtocols -}} + {{- $protocol = "tcp" -}} + {{- end -}} + {{- end }} +- name: {{ $name }} + port: {{ $port }} + protocol: {{ $protocol | upper }} + {{- with $portValues.appProtocol }} + appProtocol: {{ tpl . $rootCtx | lower }} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_endpoints.tpl b/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_endpoints.tpl new file mode 100644 index 0000000..a030fe5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_endpoints.tpl @@ -0,0 +1,21 @@ +{{/* EndpointSlice - endpoints */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.endpointslice.endpoints" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +*/}} + +{{- define "tc.v1.common.lib.endpointslice.endpoints" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.externalIP -}} + {{- fail "EndpointSlice - Expected non-empty " -}} + {{- end -}} + + {{- if not (kindIs "string" $objectData.externalIP) -}} {{/* Only single IP is supported currently on this lib */}} + {{- fail (printf "EndpointSlice - Expected to be a [string], but got [%s]" (kindOf $objectData.externalIP)) -}} + {{- end }} +- addresses: + - {{ tpl $objectData.externalIP $rootCtx }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_ports.tpl b/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_ports.tpl new file mode 100644 index 0000000..a323fb8 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/endpointSlice/_ports.tpl @@ -0,0 +1,40 @@ +{{/* EndpointSlice - Ports */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.endpointslice.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +*/}} + +{{- define "tc.v1.common.lib.endpointslice.ports" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $tcpProtocols := (list "tcp" "http" "https") -}} + {{- range $name, $portValues := $objectData.ports -}} + {{- if $portValues.enabled -}} + {{- $protocol := $rootCtx.Values.fallbackDefaults.serviceProtocol -}} {{/* Default to fallback protocol, if no protocol is defined */}} + {{- $port := $portValues.targetPort | default $portValues.port -}} + + {{/* Expand targetPort */}} + {{- if (kindIs "string" $port) -}} + {{- $port = (tpl $port $rootCtx) -}} + {{- end -}} + {{- $port = int $port -}} + + {{- with $portValues.protocol -}} + {{- $protocol = tpl . $rootCtx -}} + + {{- if mustHas $protocol $tcpProtocols -}} + {{- $protocol = "tcp" -}} + {{- end -}} + {{- end }} +- name: {{ $name }} + port: {{ $port }} + protocol: {{ $protocol | upper }} + {{- with $portValues.appProtocol }} + appProtocol: {{ tpl . $rootCtx | lower }} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/externalInterface/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/externalInterface/_validation.tpl new file mode 100644 index 0000000..c1eb478 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/externalInterface/_validation.tpl @@ -0,0 +1,53 @@ +{{/* External Interface Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.externalInterface.validation" (dict "objectData" $objectData) -}} +objectData: The object data to validate that contains the external interface configuratioon. +*/}} + +{{- define "tc.v1.common.lib.externalInterface.validation" -}} + {{- $objectData := .objectData -}} + + {{- if and $objectData.targetSelector (not (kindIs "slice" $objectData.targetSelector)) -}} + {{- fail (printf "External Interface - Expected to be a [list], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + + {{- if not $objectData.hostInterface -}} + {{- fail "External Interface - Expected non-empty " -}} + {{- end -}} + + {{- if not $objectData.ipam -}} + {{- fail "External Interface - Expected non-empty " -}} + {{- end -}} + + {{- if not $objectData.ipam.type -}} + {{- fail "External Interface - Expected non-empty " -}} + {{- end -}} + + {{- $types := (list "dhcp" "static") -}} + {{- if not (mustHas $objectData.ipam.type $types) -}} + {{- fail (printf "External Interface - Expected to be one of [%s], but got [%s]" (join ", " $types) $objectData.ipam.type) -}} + {{- end -}} + + {{- if and (or $objectData.ipam.staticIPConfigurations $objectData.ipam.staticRoutes) (ne $objectData.ipam.type "static") -}} + {{- fail "External Interface - Expected empty and when is not [static]" -}} + {{- end -}} + + {{- if eq $objectData.ipam.type "static" -}} + {{- if not $objectData.ipam.staticIPConfigurations -}} + {{- fail "External Interface - Expected non-empty when is [static]" -}} + {{- end -}} + + {{- with $objectData.ipam.staticRoutes -}} + {{- range . -}} + {{- if not .destination -}} + {{- fail "External Interface - Expected non-empty in " -}} + {{- end -}} + + {{- if not .gateway -}} + {{- fail "External Interface - Expected non-empty in " -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_createData.tpl b/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_createData.tpl new file mode 100644 index 0000000..5ebef01 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_createData.tpl @@ -0,0 +1,43 @@ +{{/* Configmap Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.imagePullSecret.createData" (dict "objectData" $objectData "root" $rootCtx) -}} +rootCtx: The root context of the chart. +objectData: + data: The data of the imagePullSecret. +*/}} + +{{- define "tc.v1.common.lib.imagePullSecret.createData" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{- $registrySecret := dict -}} + + {{/* Auth is b64encoded and then the whole secret is b64encoded */}} + {{- $auth := printf "%s:%s" (tpl $objectData.data.username $rootCtx) (tpl $objectData.data.password $rootCtx) | b64enc -}} + + {{- $registry := dict -}} + {{- with $objectData.data -}} + {{- $registry = (dict "username" (tpl .username $rootCtx) "password" (tpl .password $rootCtx) + "email" (tpl .email $rootCtx) "auth" $auth) -}} + {{- end -}} + + {{- $registryKey := tpl $objectData.data.registry $rootCtx -}} + {{- $_ := set $registrySecret "auths" (dict $registryKey $registry) -}} + + {{/* + This should result in something like this: + { + "auths": { + "$registry": { + "username": "$username", + "password": "$password", + "email": "$email", + "auth": "($username:$password) base64" + } + } +} +*/}} + + {{/* Return the registrySecret as Json */}} + {{- $registrySecret | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_validation.tpl new file mode 100644 index 0000000..7d0f9fa --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/imagePullSecret/_validation.tpl @@ -0,0 +1,27 @@ +{{/* Configmap Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.imagePullSecret.validation" (dict "objectData" $objectData) -}} +objectData: + labels: The labels of the imagePullSecret. + annotations: The annotations of the imagePullSecret. + data: The data of the imagePullSecret. +*/}} + +{{- define "tc.v1.common.lib.imagePullSecret.validation" -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.data -}} + {{- fail "Image Pull Secret - Expected non-empty " -}} + {{- end -}} + + {{- if not (kindIs "map" $objectData.data) -}} + {{- fail (printf "Image Pull Secret - Expected to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}} + {{- end -}} + + {{- range $key := (list "username" "password" "registry" "email") -}} + {{- if not (get $objectData.data $key) -}} + {{- fail (printf "Image Pull Secret - Expected non-empty <%s>" $key) -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_allAnnotations.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_allAnnotations.tpl new file mode 100644 index 0000000..a00703f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_allAnnotations.tpl @@ -0,0 +1,9 @@ +{{/* Annotations that are added to all objects */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.allAnnotations" $ }} +*/}} +{{- define "tc.v1.common.lib.metadata.allAnnotations" -}} + {{/* Currently empty but can add later, if needed */}} +{{- include "tc.v1.common.lib.metadata.globalAnnotations" . }} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_allLabels.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_allLabels.tpl new file mode 100644 index 0000000..3346f79 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_allLabels.tpl @@ -0,0 +1,15 @@ +{{/* Labels that are added to all objects */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.allLabels" $ }} +*/}} +{{- define "tc.v1.common.lib.metadata.allLabels" -}} +helm.sh/chart: {{ include "tc.v1.common.lib.chart.names.chart" . }} +helm-revision: {{ .Release.Revision | quote }} +app.kubernetes.io/name: {{ include "tc.v1.common.lib.chart.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app: {{ include "tc.v1.common.lib.chart.names.chart" . }} +release: {{ .Release.Name }} +{{- include "tc.v1.common.lib.metadata.globalLabels" . }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_externalInterfaceAnnotations.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_externalInterfaceAnnotations.tpl new file mode 100644 index 0000000..01bbcff --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_externalInterfaceAnnotations.tpl @@ -0,0 +1,52 @@ + + +{{/* External Interface Annotations that are added to podSpec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $ "podShortName" $podShortName) }} +rootCtx is the root context of the chart +objectData is object containing the data of the pod +*/}} +{{- define "tc.v1.common.lib.metadata.externalInterfacePodAnnotations" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{- $ifaceIndexes := list -}} + + {{- range $index, $iface := $rootCtx.Values.scaleExternalInterface -}} + {{/* If targetSelectAll is set append the index */}} + {{- if .targetSelectAll -}} + {{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}} + {{/* Else If targetSelector is set and pod is selected append the index */}} + {{- else if and .targetSelector (mustHas $objectData.shortName .targetSelector) -}} + {{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}} + {{/* Else If none of the above, but pod is primary append the index */}} + {{- else if $objectData.primary -}} + {{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}} + {{- end -}} + {{- end -}} + + {{- $ifaceNames := list -}} + {{- if $rootCtx.Values.ixExternalInterfacesConfiguration -}} + {{- with $rootCtx.Values.ixExternalInterfacesConfigurationNames -}} + {{- range $ifaceName := . -}} + {{/* Get the index by splitting the iFaceName (ix-release-name-0) */}} + {{- $index := splitList "-" $ifaceName -}} + {{/* And pick the last item on the list */}} + {{- $index = mustLast $index -}} + + {{/* If the index is in the list of indexes to be added, append the name */}} + {{- if mustHas (int $index) $ifaceIndexes -}} + {{- $ifaceNames = mustAppend $ifaceNames $ifaceName -}} + {{- end -}} + + {{- end -}} + {{- else -}} + {{- fail "External Interface - Expected non empty " -}} + {{- end -}} + {{- end -}} + + {{/* If we have ifaceNames, then add the annotations to the pod calling this template */}} + {{- if $ifaceNames }} +k8s.v1.cni.cncf.io/networks: {{ join ", " $ifaceNames }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_globalAnnotations.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_globalAnnotations.tpl new file mode 100644 index 0000000..1133783 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_globalAnnotations.tpl @@ -0,0 +1,6 @@ +{{/* Returns the global annotations */}} +{{- define "tc.v1.common.lib.metadata.globalAnnotations" -}} + + {{- include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" .Values.global.annotations) -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_globalLabels.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_globalLabels.tpl new file mode 100644 index 0000000..672f522 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_globalLabels.tpl @@ -0,0 +1,6 @@ +{{/* Returns the global labels */}} +{{- define "tc.v1.common.lib.metadata.globalLabels" -}} + + {{- include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" .Values.global.labels) -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_namespace.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_namespace.tpl new file mode 100644 index 0000000..0a9fa98 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_namespace.tpl @@ -0,0 +1,35 @@ +{{- define "tc.v1.common.lib.metadata.namespace" -}} + {{- $caller := .caller -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{- $namespace := $rootCtx.Release.Namespace -}} + + {{- with $rootCtx.Values.global.namespace -}} + {{- $namespace = tpl . $rootCtx -}} + {{- end -}} + + {{- with $rootCtx.Values.namespace -}} + {{- $namespace = tpl . $rootCtx -}} + {{- end -}} + + {{- with $objectData.namespace -}} + {{- $namespace = tpl . $rootCtx -}} + {{- end -}} + + {{- if not (and (mustRegexMatch "^[a-z0-9]((-?[a-z0-9]-?)*[a-z0-9])?$" $namespace) (le (len $namespace) 63)) -}} + {{- fail (printf "%s - Namespace [%s] is not valid. Must start and end with an alphanumeric lowercase character. It can contain '-'. And must be at most 63 characters." $caller $namespace) -}} + {{- end -}} + + {{- if $rootCtx.Values.global.ixChartContext -}} + {{- if not (hasPrefix "ix-" $namespace) -}} + {{/* This is only to be used on CI that do not run in SCALE so we can skip the failure */}} + {{- if not $rootCtx.Values.global.ixChartContext.ci -}} + {{- fail (printf "%s - Namespace [%v] expected to have [ix-] prefix when installed in TrueNAS SCALE" $caller $namespace) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $namespace -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_podAnnotations.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_podAnnotations.tpl new file mode 100644 index 0000000..db9d92e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_podAnnotations.tpl @@ -0,0 +1,7 @@ +{{/* Annotations that are added to podSpec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.podAnnotations" $ }} +*/}} +{{- define "tc.v1.common.lib.metadata.podAnnotations" -}} +rollme: {{ randAlphaNum 5 | quote }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_podLabels.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_podLabels.tpl new file mode 100644 index 0000000..a227d36 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_podLabels.tpl @@ -0,0 +1,6 @@ +{{/* Labels that are added to podSpec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.podLabels" $ }} +*/}} +{{- define "tc.v1.common.lib.metadata.podLabels" -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_render.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_render.tpl new file mode 100644 index 0000000..9e5f3d9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_render.tpl @@ -0,0 +1,37 @@ +{{/* Renders a dict of labels */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "labels" $labels) }} +{{ include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $ "annotations" $annotations) }} +*/}} + +{{- define "tc.v1.common.lib.metadata.render" -}} + {{- $labels := .labels -}} + {{- $annotations := .annotations -}} + {{- $rootCtx := .rootCtx -}} + + {{- $seenLabels := list -}} + {{- $seenAnnotations := list -}} + + {{- with $labels -}} + {{- range $k, $v := . -}} + {{- if and $k $v -}} + {{- if not (mustHas $k $seenLabels) }} +{{ $k }}: {{ tpl $v $rootCtx | quote }} + {{- $seenLabels = mustAppend $seenLabels $k -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- with $annotations -}} + {{- range $k, $v := . -}} + {{- if and $k $v -}} + {{- if not (mustHas $k $seenAnnotations) }} +{{ $k }}: {{ tpl $v $rootCtx | quote }} + {{- $seenAnnotations = mustAppend $seenAnnotations $k -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_selectorLabels.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_selectorLabels.tpl new file mode 100644 index 0000000..aaf09be --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_selectorLabels.tpl @@ -0,0 +1,16 @@ +{{/* Labels that are used on selectors */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" $objectType "objectName" $objectName) }} +podName is the "shortName" of the pod. The one you define in the .Values.workload +*/}} +{{- define "tc.v1.common.lib.metadata.selectorLabels" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectType := .objectType -}} + {{- $objectName := .objectName }} + +{{- if and $objectType $objectName }} +{{ printf "%s.name" $objectType }}: {{ $objectName }} +{{- end }} +app.kubernetes.io/name: {{ include "tc.v1.common.lib.chart.names.name" $rootCtx }} +app.kubernetes.io/instance: {{ $rootCtx.Release.Name }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/metadata/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/metadata/_validation.tpl new file mode 100644 index 0000000..61b4c55 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/metadata/_validation.tpl @@ -0,0 +1,22 @@ +{{/* Metadata Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" $caller) -}} +objectData: + labels: The labels of the configmap. + annotations: The annotations of the configmap. + data: The data of the configmap. +*/}} + +{{- define "tc.v1.common.lib.metadata.validation" -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- if and $objectData.labels (not (kindIs "map" $objectData.labels)) -}} + {{- fail (printf "%s - Expected to be a dictionary, but got [%v]" $caller (kindOf $objectData.labels)) -}} + {{- end -}} + + {{- if and $objectData.annotations (not (kindIs "map" $objectData.annotations)) -}} + {{- fail (printf "%s - Expected to be a dictionary, but got [%v]" $caller (kindOf $objectData.annotations)) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_autoMountServiceAccountToken.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_autoMountServiceAccountToken.tpl new file mode 100644 index 0000000..f6cc5ff --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_autoMountServiceAccountToken.tpl @@ -0,0 +1,24 @@ +{{/* Returns automountServiceAccountToken */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.automountServiceAccountToken" (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.automountServiceAccountToken" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $automount := false -}} + + {{/* Initialize from the "global" option */}} + {{- if (kindIs "bool" $rootCtx.Values.podOptions.automountServiceAccountToken) -}} + {{- $automount = $rootCtx.Values.podOptions.automountServiceAccountToken -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- if (kindIs "bool" $objectData.podSpec.automountServiceAccountToken) -}} + {{- $automount = $objectData.podSpec.automountServiceAccountToken -}} + {{- end -}} + + {{- $automount -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_container.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_container.tpl new file mode 100644 index 0000000..90f51fa --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_container.tpl @@ -0,0 +1,62 @@ +{{/* Returns Container */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.container" (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.container" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $imageObj := fromJson (include "tc.v1.common.lib.container.imageSelector" (dict "rootCtx" $rootCtx "objectData" $objectData)) -}} + {{- $termination := fromJson (include "tc.v1.common.lib.container.termination" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +- name: {{ $objectData.name }} + image: {{ printf "%s:%s" $imageObj.repository $imageObj.tag }} + imagePullPolicy: {{ $imageObj.pullPolicy }} + tty: {{ $objectData.tty | default false }} + stdin: {{ $objectData.stdin | default false }} + {{- with (include "tc.v1.common.lib.container.command" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + command: + {{- . | nindent 4 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.container.args" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + args: + {{- . | nindent 4 }} + {{- end -}} + {{- with $termination.messagePath }} + terminationMessagePath: {{ . }} + {{- end -}} + {{- with $termination.messagePolicy }} + terminationMessagePolicy: {{ . }} + {{- end -}} + {{- with (include "tc.v1.common.lib.container.lifecycle" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + lifecycle: + {{- . | nindent 4 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.container.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + ports: + {{- . | nindent 4 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.container.volumeMount" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + volumeMounts: + {{- . | nindent 4 }} + {{- end -}} + {{- include "tc.v1.common.lib.container.probes" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- with (include "tc.v1.common.lib.container.resources" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + resources: + {{- . | nindent 4 }} + {{- end }} + securityContext: + {{- include "tc.v1.common.lib.container.securityContext" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 }} + {{- /* Create a dict for storing env's so it can be checked for dupes */ -}} + {{- $_ := set $objectData "envDupe" dict -}} + {{- with (include "tc.v1.common.lib.container.envFrom" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} + envFrom: + {{- . | nindent 4 }} + {{- end }} + env: + {{- include "tc.v1.common.lib.container.fixedEnv" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}} + {{- include "tc.v1.common.lib.container.env" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}} + {{- include "tc.v1.common.lib.container.envList" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}} + {{- $_ := unset $objectData "envDupe" -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_containerSpawner.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_containerSpawner.tpl new file mode 100644 index 0000000..66e3bb4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_containerSpawner.tpl @@ -0,0 +1,31 @@ +{{/* Containers */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.containerSpawner" (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.containerSpawner" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- include "tc.v1.common.lib.container.primaryValidation" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} + + {{- range $containerName, $containerValues := $objectData.podSpec.containers -}} + {{- if $containerValues.enabled -}} + {{- $container := (mustDeepCopy $containerValues) -}} + {{- $name := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}} + {{- if not $container.primary -}} + {{- $name = printf "%s-%s" $name $containerName -}} + {{- end -}} + + {{- $_ := set $container "name" $name -}} + {{- $_ := set $container "shortName" $containerName -}} + {{- $_ := set $container "podShortName" $objectData.shortName -}} + {{- $_ := set $container "podPrimary" $objectData.primary -}} + {{- $_ := set $container "podType" $objectData.type -}} + {{/* Created from the pod.securityContext, used by fixedEnv */}} + {{- $_ := set $container "calculatedFSGroup" $objectData.podSpec.calculatedFSGroup -}} + {{- include "tc.v1.common.lib.pod.container" (dict "rootCtx" $rootCtx "objectData" $container) | trim | nindent 0 -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_dns.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_dns.tpl new file mode 100644 index 0000000..48181fd --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_dns.tpl @@ -0,0 +1,90 @@ +{{/* Returns DNS Policy and Config */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.dns" (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.dns" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $policy := "ClusterFirst" -}} + {{- $config := dict -}} + + {{/* Initialize from the "global" option */}} + {{- with $rootCtx.Values.podOptions.dnsPolicy -}} + {{- $policy = . -}} + {{- end -}} + + {{- with $rootCtx.Values.podOptions.dnsConfig -}} + {{- $config = . -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- with $objectData.podSpec.dnsPolicy -}} + {{- $policy = . -}} + {{- end -}} + + {{- with $objectData.podSpec.dnsConfig -}} + {{- $config = . -}} + {{- end -}} + + {{/* Expand policy */}} + {{- $policy = (tpl $policy $rootCtx) -}} + + {{/* If hostNetwork is enabled, then use ClusterFirstWithHostNet */}} + {{- $hostNet := include "tc.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} + {{- if or (and (kindIs "string" $hostNet) (eq $hostNet "true")) (and (kindIs "bool" $hostNet) $hostNet) -}} + {{- $policy = "ClusterFirstWithHostNet" -}} + {{- end -}} + + {{- $policies := (list "ClusterFirst" "ClusterFirstWithHostNet" "Default" "None") -}} + {{- if not (mustHas $policy $policies) -}} + {{- fail (printf "Expected to be one of [%s], but got [%s]" (join ", " $policies) $policy) -}} + {{- end -}} + + {{/* When policy is set to None all keys are required */}} + {{- if eq $policy "None" -}} + + {{- range $key := (list "nameservers" "searches" "options") -}} + {{- if not (get $config $key) -}} + {{- fail (printf "Expected non-empty with set to [None]." $key) -}} + {{- end -}} + {{- end -}} + + {{- end }} +dnsPolicy: {{ $policy }} + {{- if or $config.nameservers $config.options $config.searches }} +dnsConfig: + {{- with $config.nameservers -}} + {{- if gt (len .) 3 -}} + {{- fail (printf "Expected no more than [3] , but got [%v]" (len .)) -}} + {{- end }} + nameservers: + {{- range . }} + - {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} + + {{- with $config.searches -}} + {{- if gt (len .) 6 -}} + {{- fail (printf "Expected no more than [6] , but got [%v]" (len .)) -}} + {{- end }} + searches: + {{- range . }} + - {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} + + {{- with $config.options }} + options: + {{- range . }} + - name: {{ tpl .name $rootCtx }} + {{- with .value }} + value: {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_enableServiceLinks.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_enableServiceLinks.tpl new file mode 100644 index 0000000..4d4864e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_enableServiceLinks.tpl @@ -0,0 +1,24 @@ +{{/* Returns enableServiceLinks */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.enableServiceLinks" (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.enableServiceLinks" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $enableServiceLinks := false -}} + + {{/* Initialize from the "global" option */}} + {{- if (kindIs "bool" $rootCtx.Values.podOptions.enableServiceLinks) -}} + {{- $enableServiceLinks = $rootCtx.Values.podOptions.enableServiceLinks -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- if (kindIs "bool" $objectData.podSpec.enableServiceLinks) -}} + {{- $enableServiceLinks = $objectData.podSpec.enableServiceLinks -}} + {{- end -}} + + {{- $enableServiceLinks -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_hostAliases.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_hostAliases.tpl new file mode 100644 index 0000000..60fb5a2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_hostAliases.tpl @@ -0,0 +1,37 @@ +{{/* Returns Host Aliases */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.hostAliases" (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.hostAliases" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $aliases := list -}} + + {{/* Initialize from the "global" option */}} + {{- with $rootCtx.Values.podOptions.hostAliases -}} + {{- $aliases = . -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- with $objectData.podSpec.hostAliases -}} + {{- $aliases = . -}} + {{- end -}} + + {{- range $aliases -}} + {{- if not .ip -}} + {{- fail (printf "Expected non-empty value on .") -}} + {{- end -}} + + {{- if not .hostnames -}} + {{- fail (printf "Expected non-empty list on .") -}} + {{- end }} +- ip: {{ tpl .ip $rootCtx }} + hostnames: + {{- range .hostnames }} + - {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_hostNetwork.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_hostNetwork.tpl new file mode 100644 index 0000000..1159c64 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_hostNetwork.tpl @@ -0,0 +1,24 @@ +{{/* Returns Host Network */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.hostNetwork" (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.hostNetwork" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostNet := false -}} + + {{/* Initialize from the "global" option */}} + {{- if (kindIs "bool" $rootCtx.Values.podOptions.hostNetwork) -}} + {{- $hostNet = $rootCtx.Values.podOptions.hostNetwork -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- if (kindIs "bool" $objectData.podSpec.hostNetwork) -}} + {{- $hostNet = $objectData.podSpec.hostNetwork -}} + {{- end -}} + + {{- $hostNet -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_hostPID.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_hostPID.tpl new file mode 100644 index 0000000..5859ec2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_hostPID.tpl @@ -0,0 +1,24 @@ +{{/* Returns Host PID */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.hostPID" (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.hostPID" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostPID := false -}} + + {{/* Initialize from the "global" option */}} + {{- if (kindIs "bool" $rootCtx.Values.podOptions.hostPID) -}} + {{- $hostPID = $rootCtx.Values.podOptions.hostPID -}} + {{- end -}} + + {{/* Override with pods option */}} + {{- if (kindIs "bool" $objectData.podSpec.hostPID) -}} + {{- $hostPID = $objectData.podSpec.hostPID -}} + {{- end -}} + + {{- $hostPID -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_hostname.tpl.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_hostname.tpl.tpl new file mode 100644 index 0000000..f68769d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_hostname.tpl.tpl @@ -0,0 +1,22 @@ +{{/* Returns Host Name */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.hostname" (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.hostname" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostname := "" -}} + + {{- with $objectData.podSpec.hostname -}} + {{- $hostname = tpl . $rootCtx -}} + {{- end -}} + + {{- if $hostname -}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $hostname) -}} + {{- end -}} + + {{- $hostname -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_imagePullSecret.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_imagePullSecret.tpl new file mode 100644 index 0000000..de0f23e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_imagePullSecret.tpl @@ -0,0 +1,38 @@ +{{/* Returns Image Pull Secret List */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.imagePullSecret" (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.imagePullSecret" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $imgPullSecrets := list -}} + + {{- range $name, $imgPull := $rootCtx.Values.imagePullSecret -}} + {{- $pullName := (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}} + + {{- if $imgPull.enabled -}} + {{/* If targetSelectAll is true */}} + {{- if $imgPull.targetSelectAll -}} + {{- $imgPullSecrets = mustAppend $imgPullSecrets $pullName -}} + + {{/* Else if targetSelector is a list */}} + {{- else if (kindIs "slice" $imgPull.targetSelector) -}} + {{- if (mustHas $objectData.shortName $imgPull.targetSelector) -}} + {{- $imgPullSecrets = mustAppend $imgPullSecrets $pullName -}} + {{- end -}} + + {{/* If not targetSelectAll or targetSelector, but is the primary pod */}} + {{- else if $objectData.primary -}} + {{- $imgPullSecrets = mustAppend $imgPullSecrets $pullName -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{- range $imgPullSecrets }} +- name: {{ . }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_initContainerSpawner.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_initContainerSpawner.tpl new file mode 100644 index 0000000..d0a8f63 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_initContainerSpawner.tpl @@ -0,0 +1,91 @@ +{{/* Init Containers */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.initContainerSpawner" (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.initContainerSpawner" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $initContainers := (dict "system" list + "init" list + "install" list + "upgrade" list) -}} + + {{- $types := (list "system" "init" "install" "upgrade") -}} + + {{- $mergedContainers := $objectData.podSpec.initContainers -}} + + {{- range $containerName, $containerValues := $mergedContainers -}} + + {{- $enabled := $containerValues.enabled -}} + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $rootCtx -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + {{- if $enabled -}} + + {{- if not ($containerValues.type) -}} + {{- fail "InitContainer - Expected non-empty " -}} + {{- end -}} + + {{- $containerType := tpl $containerValues.type $rootCtx -}} + {{- if not (mustHas $containerType $types) -}} + {{- fail (printf "InitContainer - Expected to be one of [%s], but got [%s]" (join ", " $types) $containerType) -}} + {{- end -}} + + {{- $container := (mustDeepCopy $containerValues) -}} + {{- $name := printf "%s-%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $containerType $containerName -}} + + {{- $_ := set $container "name" $name -}} + {{- $_ := set $container "shortName" $containerName -}} + {{- $_ := set $container "podShortName" $objectData.shortName -}} + {{- $_ := set $container "podPrimary" $objectData.primary -}} + {{- $_ := set $container "podType" $objectData.type -}} + + {{/* Remove keys that do not apply on init containers */}} + {{- $_ := set $container "lifecycle" dict -}} + {{- $_ := set $container "probes" dict -}} + {{/* Template expects probes dict defined even if enabled */}} + {{- $_ := set $container.probes "liveness" (dict "enabled" false) -}} + {{- $_ := set $container.probes "readiness" (dict "enabled" false) -}} + {{- $_ := set $container.probes "startup" (dict "enabled" false) -}} + + {{/* Created from the pod.securityContext, used by fixedEnv */}} + {{- $_ := set $container "calculatedFSGroup" $objectData.podSpec.calculatedFSGroup -}} + + {{/* Append to list of containers based on type */}} + {{- $tempContainers := (get $initContainers $containerType) -}} + {{- $_ := set $initContainers $containerType (mustAppend $tempContainers $container) -}} + {{- end -}} + {{- end -}} + + {{- if $rootCtx.Release.IsInstall -}} + {{- range $container := (get $initContainers "install") -}} + {{- include "tc.v1.common.lib.pod.container" (dict "rootCtx" $rootCtx "objectData" $container) -}} + {{- end -}} + {{- end -}} + + {{- if $rootCtx.Release.IsUpgrade -}} + {{- range $container := (get $initContainers "upgrade") -}} + {{- include "tc.v1.common.lib.pod.container" (dict "rootCtx" $rootCtx "objectData" $container) -}} + {{- end -}} + {{- end -}} + + {{- range $container := (get $initContainers "system") -}} + {{- include "tc.v1.common.lib.pod.container" (dict "rootCtx" $rootCtx "objectData" $container) -}} + {{- end -}} + + {{- range $container := (get $initContainers "init") -}} + {{- include "tc.v1.common.lib.pod.container" (dict "rootCtx" $rootCtx "objectData" $container) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_nodeSelector.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_nodeSelector.tpl new file mode 100644 index 0000000..019d13d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_nodeSelector.tpl @@ -0,0 +1,33 @@ +{{/* Returns Node Selector */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.nodeSelector" (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.nodeSelector" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $selectors := dict -}} + + {{/* Initialize from the "global" option */}} + {{- with $rootCtx.Values.podOptions.nodeSelector -}} + {{- $selectors = . -}} + {{- end -}} + + {{/* Override with pods option */}} + {{- with $objectData.podSpec.nodeSelector -}} + {{- $selectors = . -}} + {{- end -}} + + {{- if and (include "tc.v1.common.lib.util.stopAll" $rootCtx) (eq $objectData.type "DaemonSet") }} +"non-existing": "true" + {{ else }} + {{- range $k, $v := $selectors -}} + {{- if not $v -}} + {{- else }} +{{ $k }}: {{ tpl $v $rootCtx }} + {{- end -}} + {{- end -}} + {{ end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_podSecurityContext.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_podSecurityContext.tpl new file mode 100644 index 0000000..6bf2d6e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_podSecurityContext.tpl @@ -0,0 +1,117 @@ +{{/* Returns Pod Security Context */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.securityContext" (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.securityContext" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $rootCtx.Values.securityContext.pod -}} + {{- fail "Pod - Expected non-empty <.Values.securityContext.pod>" -}} + {{- end -}} + + {{/* Initialize from the "global" option */}} + {{- $secContext := mustDeepCopy $rootCtx.Values.securityContext.pod -}} + + {{/* Override with pods option */}} + {{- with $objectData.podSpec.securityContext -}} + {{- $secContext = mustMergeOverwrite $secContext . -}} + {{- end -}} + + {{- $gpuAdded := false -}} + {{- range $GPUValues := $rootCtx.Values.scaleGPU -}} + {{/* If there is a selector and pod is selected */}} + {{- if $GPUValues.targetSelector -}} + {{- if mustHas $objectData.shortName ($GPUValues.targetSelector | keys) -}} + {{- $gpuAdded = true -}} + {{- end -}} + {{/* If there is not a selector, but pod is primary */}} + {{- else if $objectData.primary -}} + {{- $gpuAdded = true -}} + {{- end -}} + {{- end -}} + + {{- $deviceGroups := (list 5 10 20 24) -}} + {{- $deviceAdded := false -}} + {{- range $persistenceName, $persistenceValues := $rootCtx.Values.persistence -}} + {{- if $persistenceValues.enabled -}} + {{- if eq $persistenceValues.type "device" -}} + {{- if $persistenceValues.targetSelectAll -}} + {{- $deviceAdded = true -}} + {{- else if $persistenceValues.targetSelector -}} + {{- if mustHas $objectData.shortName ($persistenceValues.targetSelector | keys) -}} + {{- $deviceAdded = true -}} + {{- end -}} + {{- else if $objectData.podPrimary -}} + {{- $deviceAdded = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if $gpuAdded -}} + {{- $_ := set $secContext "supplementalGroups" (concat $secContext.supplementalGroups (list 44 107)) -}} + {{- end -}} + + {{- if $deviceAdded -}} + {{- $_ := set $secContext "supplementalGroups" (concat $secContext.supplementalGroups $deviceGroups) -}} + {{- end -}} + + {{- $_ := set $secContext "supplementalGroups" (concat $secContext.supplementalGroups (list 568)) -}} + + {{- if not (deepEqual $secContext.supplementalGroups (mustUniq $secContext.supplementalGroups)) -}} + {{- fail (printf "Pod - Expected to have only unique values, but got [%s]" (join ", " $secContext.supplementalGroups)) -}} + {{- end -}} + + {{- $portRange := fromJson (include "tc.v1.common.lib.helpers.securityContext.getPortRange" (dict "rootCtx" $rootCtx "objectData" $objectData)) -}} + {{/* If a container wants to bind a port <= 1024 change the unprivileged_port_start */}} + {{- if and $portRange.low (le (int $portRange.low) 1024) -}} + {{/* That sysctl is not supported when hostNet is enabled */}} + {{- if ne (include "tc.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $objectData)) "true" -}} + {{- $_ := set $secContext "sysctls" (mustAppend $secContext.sysctls (dict "name" "net.ipv4.ip_unprivileged_port_start" "value" (printf "%v" $portRange.low))) -}} + {{- end -}} + {{- end -}} + + {{- if or (kindIs "invalid" $secContext.fsGroup) (eq (toString $secContext.fsGroup) "") -}} + {{- fail "Pod - Expected non-empty " -}} + {{- end -}} + + {{/* Used by the fixedEnv template */}} + {{- $_ := set $objectData.podSpec "calculatedFSGroup" $secContext.fsGroup -}} + + {{- if not $secContext.fsGroupChangePolicy -}} + {{- fail "Pod - Expected non-empty " -}} + {{- end -}} + + {{- $policies := (list "Always" "OnRootMismatch") -}} + {{- if not (mustHas $secContext.fsGroupChangePolicy $policies) -}} + {{- fail (printf "Pod - Expected to be one of [%s], but got [%s]" (join ", " $policies) $secContext.fsGroupChangePolicy) -}} + {{- end }} +fsGroup: {{ include "tc.v1.common.helper.makeIntOrNoop" $secContext.fsGroup }} +fsGroupChangePolicy: {{ $secContext.fsGroupChangePolicy }} + {{- with $secContext.supplementalGroups }} +supplementalGroups: + {{- range . }} + - {{ include "tc.v1.common.helper.makeIntOrNoop" . }} + {{- end -}} + {{- else }} +supplementalGroups: [] + {{- end -}} + {{- with $secContext.sysctls }} +sysctls: + {{- range . }} + {{- if not .name -}} + {{- fail "Pod - Expected non-empty in " -}} + {{- end -}} + {{- if not .value -}} + {{- fail "Pod - Expected non-empty in " -}} + {{- end }} + - name: {{ tpl .name $rootCtx | quote }} + value: {{ tpl .value $rootCtx | quote }} + {{- end -}} + {{- else }} +sysctls: [] + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_priorityClassName.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_priorityClassName.tpl new file mode 100644 index 0000000..aaf15ac --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_priorityClassName.tpl @@ -0,0 +1,24 @@ +{{/* Returns Priority Class Name */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.priorityClassName" (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.priorityClassName" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $className := "" -}} + + {{/* Initialize from the "global" option */}} + {{- with $rootCtx.Values.podOptions.priorityClassName -}} + {{- $className = tpl . $rootCtx -}} + {{- end -}} + + {{/* Override with pod's option */}} + {{- with $objectData.podSpec.priorityClassName -}} + {{- $className = tpl . $rootCtx -}} + {{- end -}} + + {{- $className -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_restartPolicy.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_restartPolicy.tpl new file mode 100644 index 0000000..d14c8c9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_restartPolicy.tpl @@ -0,0 +1,34 @@ +{{/* Returns Restart Policy */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.restartPolicy" (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.restartPolicy" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $policy := "Always" -}} + + {{/* Initialize from the "defaults" */}} + {{- with $rootCtx.Values.podOptions.restartPolicy -}} + {{- $policy = tpl . $rootCtx -}} + {{- end -}} + + {{/* Override from the pod values, if defined */}} + {{- with $objectData.podSpec.restartPolicy -}} + {{- $policy = tpl . $rootCtx -}} + {{- end -}} + + {{- $policies := (list "Never" "Always" "OnFailure") -}} + {{- if not (mustHas $policy $policies) -}} + {{- fail (printf "Expected to be one of [%s] but got [%s]" (join ", " $operators) $operator) -}} + {{- end -}} + + {{- if and (eq $operator "Equal") (or (not $key) (not $value)) -}} + {{- fail "Expected non-empty and with set to [Equal]" -}} + {{- end -}} + + {{- if and (eq $operator "Exists") $value -}} + {{- fail (printf "Expected empty with set to [Exists], but got [%s]" $value) -}} + {{- end -}} + + {{- $effects := (list "NoExecute" "NoSchedule" "PreferNoSchedule") -}} + {{- if and $effect (not (mustHas $effect $effects)) -}} + {{- fail (printf "Expected to be one of [%s], but got [%s]" (join ", " $effects) $effect) -}} + {{- end -}} + + {{- if and (not (kindIs "invalid" $tolSeconds)) (not (mustHas (kindOf $tolSeconds) (list "int" "int64" "float64"))) -}} + {{- fail (printf "Expected to be a number, but got [%v]" $tolSeconds) -}} + {{- end }} +- operator: {{ $operator }} + {{- with $key }} + key: {{ $key }} + {{- end -}} + {{- with $effect }} + effect: {{ $effect }} + {{- end -}} + {{- with $value }} + value: {{ . }} + {{- end -}} + {{- if (mustHas (kindOf $tolSeconds) (list "int" "int64" "float64")) }} + tolerationSeconds: {{ $tolSeconds }} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_topologySpreadConstraints .tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_topologySpreadConstraints .tpl new file mode 100644 index 0000000..5f24d70 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_topologySpreadConstraints .tpl @@ -0,0 +1,44 @@ +{{/* Returns topologySpreadConstraints */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.topologySpreadConstraints" (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.topologySpreadConstraints" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $constraints := list -}} + + {{/* Initialize from the "global" option */}} + {{- with $rootCtx.Values.podOptions.topologySpreadConstraints -}} + {{- $constraints = . -}} + {{- end -}} + + {{/* Override with pods option */}} + {{- with $objectData.podSpec.topologySpreadConstraints -}} + {{- $constraints = . -}} + {{- end -}} + + {{- if and ( or ( eq $objectData.type "Deployment" ) ( eq $objectData.type "StatefulSet" )) $rootCtx.Values.podOptions.defaultSpread -}} +- maxSkew: 1 + whenUnsatisfiable: ScheduleAnyway + topologyKey: "truecharts.org/rack" + labelSelector: + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.name) | indent 6 }} + nodeAffinityPolicy: Honor + nodeTaintsPolicy: Honor +- maxSkew: 1 + whenUnsatisfiable: ScheduleAnyway + topologyKey: "kubernetes.io/hostname" + labelSelector: + matchLabels: + {{- include "tc.v1.common.lib.metadata.selectorLabels" (dict "rootCtx" $rootCtx "objectType" "pod" "objectName" $objectData.name) | indent 6 }} + nodeAffinityPolicy: Honor + nodeTaintsPolicy: Honor + {{- end -}} + {{ with $constraints }} +{{ . | toYaml | indent 0 }} + {{ end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/_volumes.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/_volumes.tpl new file mode 100644 index 0000000..d054c2d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/_volumes.tpl @@ -0,0 +1,68 @@ +{{/* Returns Volumes */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volumes" (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.volumes" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $name, $persistenceValues := $rootCtx.Values.persistence -}} + {{- if $persistenceValues.enabled -}} + {{- $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 (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.fallbackDefaults.persistenceType) -}} + + {{- if eq "pvc" $type -}} + {{- include "tc.v1.common.lib.pod.volume.pvc" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}} + {{- else if eq "ixVolume" $type -}} + {{- include "tc.v1.common.lib.pod.volume.ixVolume" (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 "device" $type -}} + {{- include "tc.v1.common.lib.pod.volume.device" (dict "rootCtx" $rootCtx "objectData" $persistence) | trim | nindent 0 -}} + {{- end -}} + + {{- end -}} + + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_configmap.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_configmap.tpl new file mode 100644 index 0000000..f8b7b9e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_configmap.tpl @@ -0,0 +1,70 @@ +{{/* Returns ConfigMap Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.configmap" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.configmap" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.objectName -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + + {{- $objectName := tpl $objectData.objectName $rootCtx -}} + {{- $expandName := true -}} + {{- if kindIs "bool" $objectData.expandObjectName -}} + {{- $expandName = $objectData.expandObjectName -}} + {{- end -}} + + {{- if $expandName -}} + {{- $object := (get $rootCtx.Values.configmap $objectName) -}} + {{- if and (not $object) (not $objectData.optional) -}} + {{- fail (printf "Persistence - Expected configmap [%s] defined in to exist" $objectName) -}} + {{- end -}} + + {{- $objectName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectName) -}} + {{- end -}} + + {{- $optional := false -}} + {{- if hasKey $objectData "optional" -}} + {{- if not (kindIs "bool" $objectData.optional) -}} + {{- fail (printf "Persistence - Expected to be [bool], but got [%s]" (kindOf $objectData.optional)) -}} + {{- end -}} + {{- $optional = $objectData.optional -}} + {{- end -}} + + {{- $defMode := "" -}} + {{- if (and $objectData.defaultMode (not (kindIs "string" $objectData.defaultMode))) -}} + {{- fail (printf "Persistence - Expected to be [string], but got [%s]" (kindOf $objectData.defaultMode)) -}} + {{- end -}} + + {{- with $objectData.defaultMode -}} + {{- $defMode = tpl $objectData.defaultMode $rootCtx -}} + {{- end -}} + + {{- if and $defMode (not (mustRegexMatch "^[0-9]{4}$" $defMode)) -}} + {{- fail (printf "Persistence - Expected to have be in format of [\"0777\"], but got [%q]" $defMode) -}} + {{- end }} +- name: {{ $objectData.shortName }} + configMap: + name: {{ $objectName }} + {{- with $defMode }} + defaultMode: {{ . }} + {{- end }} + optional: {{ $optional }} + {{- with $objectData.items }} + items: + {{- range . -}} + {{- if not .key -}} + {{- fail "Persistence - Expected non-empty " -}} + {{- end -}} + {{- if not .path -}} + {{- fail "Persistence - Expected non-empty " -}} + {{- end }} + - key: {{ tpl .key $rootCtx }} + path: {{ tpl .path $rootCtx }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_device.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_device.tpl new file mode 100644 index 0000000..c1af694 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_device.tpl @@ -0,0 +1,53 @@ +{{/* Returns device (hostPath) Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.device" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.device" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostPathType := "" -}} + {{- if $objectData.hostPathType -}} + {{- $hostPathType = tpl $objectData.hostPathType $rootCtx -}} + {{- end -}} + + {{- if not $objectData.hostPath -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + {{- $hostPath := tpl $objectData.hostPath $rootCtx -}} + + {{- if not (hasPrefix "/" $hostPath) -}} + {{- fail "Persistence - Expected to start with a forward slash [/] on type" -}} + {{- end -}} + + {{- $charDevices := (list "tty") -}} + {{- if not $hostPathType -}} + {{- range $char := $charDevices -}} + {{- if hasPrefix (printf "/dev/%v" $char) $hostPath -}} + {{- $hostPathType = "CharDevice" -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $blockDevices := (list "sd" "hd" "nvme") -}} + {{- if not $hostPathType -}} + {{- range $block := $blockDevices -}} + {{- if hasPrefix (printf "/dev/%v" $block) $hostPath -}} + {{- $hostPathType = "BlockDevice" -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $types := (list "DirectoryOrCreate" "Directory" "FileOrCreate" "File" "Socket" "CharDevice" "BlockDevice") -}} + {{- if and $hostPathType (not (mustHas $hostPathType $types)) -}} + {{- fail (printf "Persistence - Expected to be one of [%s], but got [%s]" (join ", " $types) $hostPathType) -}} + {{- end }} +- name: {{ $objectData.shortName }} + hostPath: + path: {{ $hostPath }} + {{- with $hostPathType }} + type: {{ $hostPathType }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_emptyDir.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_emptyDir.tpl new file mode 100644 index 0000000..30d8431 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_emptyDir.tpl @@ -0,0 +1,43 @@ +{{/* Returns emptyDir Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.emptyDir" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.emptyDir" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $medium := "" -}} + {{- $size := "" -}} + {{- with $objectData.medium -}} + {{- $medium = tpl . $rootCtx -}} + {{- end -}} + {{- with $objectData.size -}} + {{- $size = tpl . $rootCtx -}} + {{- end -}} + + {{- if $size -}} + {{/* Size: https://regex101.com/r/NNPV2D/1 */}} + {{- if not (mustRegexMatch "^[1-9][0-9]*([EPTGMK]i?|e[0-9]+)?$" (toString $size)) -}} + {{- $formats := "(Suffixed with E/P/T/G/M/K - eg. 1G), (Suffixed with Ei/Pi/Ti/Gi/Mi/Ki - eg. 1Gi), (Plain Integer in bytes - eg. 1024), (Exponent - eg. 134e6)" -}} + {{- fail (printf "Persistence Expected to have one of the following formats [%s], but got [%s]" $formats $size) -}} + {{- end -}} + {{- end -}} + + {{- if and $medium (ne $medium "Memory") -}} + {{- fail (printf "Persistence - Expected [medium] to be one of [\"\", Memory], but got [%s] on type" $medium) -}} + {{- end }} +- name: {{ $objectData.shortName }} + {{- if or $medium $size }} + emptyDir: + {{- if $medium }} + medium: {{ $medium }} + {{- end -}} + {{- if $size }} + sizeLimit: {{ $size }} + {{- end -}} + {{- else }} + emptyDir: {} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_hostPath.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_hostPath.tpl new file mode 100644 index 0000000..5d66b97 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_hostPath.tpl @@ -0,0 +1,35 @@ +{{/* Returns hostPath Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.hostPath" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.hostPath" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostPathType := "" -}} + {{- if $objectData.hostPathType -}} + {{- $hostPathType = tpl $objectData.hostPathType $rootCtx -}} + {{- end -}} + + {{- if not $objectData.hostPath -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + {{- $hostPath := tpl $objectData.hostPath $rootCtx -}} + + {{- if not (hasPrefix "/" $hostPath) -}} + {{- fail "Persistence - Expected to start with a forward slash [/] on type" -}} + {{- end -}} + + {{- $types := (list "DirectoryOrCreate" "Directory" "FileOrCreate" "File" "Socket" "CharDevice" "BlockDevice") -}} + {{- if and $hostPathType (not (mustHas $hostPathType $types)) -}} + {{- fail (printf "Persistence - Expected to be one of [%s], but got [%s]" (join ", " $types) $hostPathType) -}} + {{- end }} +- name: {{ $objectData.shortName }} + hostPath: + path: {{ $hostPath }} + {{- with $hostPathType }} + type: {{ $hostPathType }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_ixVolume.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_ixVolume.tpl new file mode 100644 index 0000000..225281c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_ixVolume.tpl @@ -0,0 +1,56 @@ +{{/* Returns ixVolume Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.ixVolume" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.ixVolume" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $hostPathType := "" -}} + {{- if $objectData.hostPathType -}} + {{- $hostPathType = tpl $objectData.hostPathType $rootCtx -}} + {{- end -}} + + {{- if not $objectData.datasetName -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + {{- $datasetName := tpl $objectData.datasetName $rootCtx -}} + + {{- if not $rootCtx.Values.ixVolumes -}} + {{- fail "Persistence - Expected non-empty in values on type" -}} + {{- end -}} + + {{- $hostPath := "" -}} + {{- $found := false -}} + {{- range $idx, $normalizedHostPath := $rootCtx.Values.ixVolumes -}} + {{- if eq $datasetName (base $normalizedHostPath.hostPath) -}} + {{- $found = true -}} + {{- $hostPath = $normalizedHostPath.hostPath -}} + {{- end -}} + {{- end -}} + + {{- if not $found -}} {{/* If we go over the ixVolumes and we dont find a match, fail */}} + {{- $datasets := list -}} + {{- range $rootCtx.Values.ixVolumes -}} + {{- $datasets = mustAppend $datasets (base .hostPath) -}} + {{- end -}} + {{- fail (printf "Persistence - Expected [%s] to exist on list, but list contained [%s] on type" $datasetName (join ", " $datasets)) -}} + {{- end -}} + + {{- if not (hasPrefix "/" $hostPath) -}} + {{- fail "Persistence - Expected normalized path from to start with a forward slash [/] on type" -}} + {{- end -}} + + {{- $types := (list "DirectoryOrCreate" "Directory" "FileOrCreate" "File" "Socket" "CharDevice" "BlockDevice") -}} + {{- if and $hostPathType (not (mustHas $hostPathType $types)) -}} + {{- fail (printf "Persistence - Expected to be one of [%s], but got [%s]" (join ", " $types) $hostPathType) -}} + {{- end }} +- name: {{ $objectData.shortName }} + hostPath: + path: {{ $hostPath }} + {{- with $hostPathType }} + type: {{ $hostPathType }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_nfs.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_nfs.tpl new file mode 100644 index 0000000..3e91208 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_nfs.tpl @@ -0,0 +1,27 @@ +{{/* Returns NFS Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.nfs" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.nfs" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.path -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + + {{- $path := tpl $objectData.path $rootCtx -}} + {{- if not (hasPrefix "/" $path) -}} + {{- fail "Persistence - Expected to start with a forward slash [/] on type" -}} + {{- end -}} + + {{- if not $objectData.server -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end }} +- name: {{ $objectData.shortName }} + nfs: + path: {{ $path }} + server: {{ tpl $objectData.server $rootCtx }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_pvc.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_pvc.tpl new file mode 100644 index 0000000..b0a2fe2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_pvc.tpl @@ -0,0 +1,18 @@ +{{/* Returns PVC Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.pvc" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.pvc" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $pvcName := (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectData.shortName) -}} + {{- with $objectData.existingClaim -}} + {{- $pvcName = tpl . $rootCtx -}} + {{- end }} +- name: {{ $objectData.shortName }} + persistentVolumeClaim: + claimName: {{ $pvcName }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_secret.tpl b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_secret.tpl new file mode 100644 index 0000000..223b376 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/pod/volumes/_secret.tpl @@ -0,0 +1,71 @@ +{{/* Returns Secret Volume */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pod.volume.secret" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the volume. +*/}} +{{- define "tc.v1.common.lib.pod.volume.secret" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.objectName -}} + {{- fail "Persistence - Expected non-empty on type" -}} + {{- end -}} + + {{- $objectName := tpl $objectData.objectName $rootCtx -}} + {{- $expandName := true -}} + {{- if kindIs "bool" $objectData.expandObjectName -}} + {{- $expandName = $objectData.expandObjectName -}} + {{- end -}} + + {{- if $expandName -}} + {{- $object := (get $rootCtx.Values.secret $objectName) -}} + {{- $certObject := (get $rootCtx.Values.scaleCertificate $objectName) -}} + {{- if and (not $object) (not $certObject) (not $objectData.optional) -}} + {{- fail (printf "Persistence - Expected secret [%s] defined in to exist" $objectName) -}} + {{- end -}} + + {{- $objectName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectName) -}} + {{- end -}} + + {{- $optional := false -}} + {{- if hasKey $objectData "optional" -}} + {{- if not (kindIs "bool" $objectData.optional) -}} + {{- fail (printf "Persistence - Expected to be [bool], but got [%s]" (kindOf $objectData.optional)) -}} + {{- end -}} + {{- $optional = $objectData.optional -}} + {{- end -}} + + {{- $defMode := "" -}} + {{- if (and $objectData.defaultMode (not (kindIs "string" $objectData.defaultMode))) -}} + {{- fail (printf "Persistence - Expected to be [string], but got [%s]" (kindOf $objectData.defaultMode)) -}} + {{- end -}} + + {{- with $objectData.defaultMode -}} + {{- $defMode = tpl $objectData.defaultMode $rootCtx -}} + {{- end -}} + + {{- if and $defMode (not (mustRegexMatch "^[0-9]{4}$" $defMode)) -}} + {{- fail (printf "Persistence - Expected to have be in format of [\"0777\"], but got [%q]" $defMode) -}} + {{- end }} +- name: {{ $objectData.shortName }} + secret: + secretName: {{ $objectName }} + {{- with $defMode }} + defaultMode: {{ . }} + {{- end }} + optional: {{ $optional }} + {{- with $objectData.items }} + items: + {{- range . -}} + {{- if not .key -}} + {{- fail "Persistence - Expected non-empty " -}} + {{- end -}} + {{- if not .path -}} + {{- fail "Persistence - Expected non-empty " -}} + {{- end }} + - key: {{ tpl .key $rootCtx }} + path: {{ tpl .path $rootCtx }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/podDistruptionBudget/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/podDistruptionBudget/_validation.tpl new file mode 100644 index 0000000..d0eb993 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/podDistruptionBudget/_validation.tpl @@ -0,0 +1,48 @@ +{{/* Metadata Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.podDisruptionBudget.validation" (dict "objectData" $objectData "caller" $caller) -}} +objectData: + labels: The labels of the configmap. + annotations: The annotations of the configmap. + data: The data of the configmap. +*/}} + +{{- define "tc.v1.common.lib.podDisruptionBudget.validation" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if and $objectData.targetSelector (not (kindIs "string" $objectData.targetSelector)) -}} + {{- fail (printf "Pod Disruption Budget - Expected to be [string], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + + {{- if and (not $objectData.targetSelector) (not $objectData.customLabels) -}} + {{- fail (printf "Pod Disruption Budget - Expected one of [targetSelector, customLabels] to be defined in " $objectData.shortName) -}} + {{- end -}} + + {{- if and $objectData.targetSelector $objectData.customLabels -}} + {{- fail (printf "Pod Disruption Budget - Expected only one of [targetSelector, customLabels] to be defined in " $objectData.shortName) -}} + {{- end -}} + + {{- with $objectData.unhealthyPodEvictionPolicy -}} + {{- $policies := (list "IfHealthyBudget" "AlwaysAllow") -}} + {{- if not (mustHas (tpl . $rootCtx) $policies) -}} + {{- fail (printf "Pod Disruption Budget - Expected to be one of [%s], but got [%s]" (join ", " $policies) .) -}} + {{- end -}} + {{- end -}} + + {{- $hasKey := false -}} + {{- $keys := (list "minAvailable" "maxUnavailable") -}} + {{- range $key := $keys -}} + {{- if hasKey $objectData $key -}} + {{- $hasKey = true -}} + {{- if kindIs "invalid" (get $objectData $key) -}} + {{- fail (printf "Pod Disruption Budget - Expected the defined key [%v] in to not be empty" $key $objectData.shortName) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $hasKey -}} + {{- fail (printf "Pod Disruption Budget - Expected at least one of [%s] to be defined in " (join ", " $keys) $objectData.shortName) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/rbac/_getServiceAccounts.tpl b/helm-charts/dashy/charts/common/templates/lib/rbac/_getServiceAccounts.tpl new file mode 100644 index 0000000..61a2305 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/rbac/_getServiceAccounts.tpl @@ -0,0 +1,52 @@ +{{/* Returns Service Account List for rbac */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.rbac.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the RBAC. +*/}} +{{/* Parses service accounts, and checks if RBAC have selected any of them */}} +{{- define "tc.v1.common.lib.rbac.serviceAccount" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $serviceAccounts := list -}} + + {{- range $name, $serviceAccount := $rootCtx.Values.serviceAccount -}} + {{- $saName := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}} + + {{- if $serviceAccount.enabled -}} + + {{- if not $serviceAccount.primary -}} + {{- $saName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}} + {{- end -}} + + {{/* If allServiceAccounts is true */}} + {{- if $objectData.allServiceAccounts -}} + {{- $serviceAccounts = mustAppend $serviceAccounts $saName -}} + + {{/* Else if serviceAccounts is a list */}} + {{- else if (kindIs "slice" $objectData.serviceAccounts) -}} + {{- if (mustHas $name $objectData.serviceAccounts) -}} + {{- $serviceAccounts = mustAppend $serviceAccounts $saName -}} + {{- end -}} + + {{/* If not "allServiceAccounts" or "serviceAccounts", assign the primary service account to rbac */}} + {{- else if $serviceAccount.primary -}} + {{- if $objectData.primary -}} + {{- $serviceAccounts = mustAppend $serviceAccounts $saName -}} + {{- end -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{- if not $serviceAccounts -}} + {{- fail "RBAC - Expected at least one serviceAccount to be assigned. Assign one using [allServiceAccounts (boolean), serviceAccounts (list)]" -}} + {{- end -}} + + {{- range $serviceAccounts }} +- kind: ServiceAccount + name: {{ . }} + namespace: {{ $rootCtx.Release.Namespace }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/rbac/_rules.tpl b/helm-charts/dashy/charts/common/templates/lib/rbac/_rules.tpl new file mode 100644 index 0000000..6f46e51 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/rbac/_rules.tpl @@ -0,0 +1,50 @@ +{{/* Returns Rules for rbac */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.rbac.rules" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the RBAC. +*/}} +{{/* Parses service accounts, and checks if RBAC have selected any of them */}} +{{- define "tc.v1.common.lib.rbac.rules" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.rules -}} + {{- fail "RBAC - Expected non-empty " -}} + {{- end -}} + + {{- range $objectData.rules -}} + {{- if not .apiGroups -}} + {{- fail "RBAC - Expected non-empty " -}} + {{- end -}} + {{- if not .resources -}} + {{- fail "RBAC - Expected non-empty " -}} + {{- end -}} + {{- if not .verbs -}} + {{- fail "RBAC - Expected non-empty " -}} + {{- end -}} + + {{- /* apiGroups */}} +- apiGroups: + {{- range .apiGroups }} + - {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- /* resources */}} + resources: + {{- range .resources -}} + {{- if not . -}} + {{- fail "RBAC - Expected non-empty entry in " -}} + {{- end }} + - {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- /* verbs */}} + verbs: + {{- range .verbs -}} + {{- if not . -}} + {{- fail "RBAC - Expected non-empty entry in " -}} + {{- end }} + - {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/rbac/_subjects.tpl b/helm-charts/dashy/charts/common/templates/lib/rbac/_subjects.tpl new file mode 100644 index 0000000..58f8c63 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/rbac/_subjects.tpl @@ -0,0 +1,17 @@ +{{/* Returns Subjects for rbac */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.rbac.subjects" (dict "rootCtx" $ "objectData" $objectData) }} +rootCtx: The root context of the chart. +objectData: The object data to be used to render the RBAC. +*/}} +{{/* Parses service accounts, and checks if RBAC have selected any of them */}} +{{- define "tc.v1.common.lib.rbac.subjects" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $objectData.subjects }} +- kind: {{ tpl (required "RBAC - Expected non-empty " .kind) $rootCtx | quote }} + name: {{ tpl (required "RBAC - Expected non-empty " .name) $rootCtx | quote }} + apiGroup: {{ tpl (required "RBAC - Expected non-empty " .apiGroup) $rootCtx | quote }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/rbac/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/rbac/_validation.tpl new file mode 100644 index 0000000..81f7ca8 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/rbac/_validation.tpl @@ -0,0 +1,38 @@ +{{/* RBAC Primary Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.rbac.primaryValidation" $ -}} +*/}} + +{{- define "tc.v1.common.lib.rbac.primaryValidation" -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{- range $name, $rbac := .Values.rbac -}} + + {{/* If rbac is enabled */}} + {{- if $rbac.enabled -}} + {{- $hasEnabled = true -}} + + {{/* And rbac is primary */}} + {{- if and (hasKey $rbac "primary") ($rbac.primary) -}} + + {{/* Fail if there is already a primary rbac */}} + {{- if $hasPrimary -}} + {{- fail "RBAC - Only one rbac can be primary" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- end -}} + + {{- end -}} + {{- end -}} + + {{/* Require at least one primary rbac, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "RBAC - At least one enabled rbac must be primary" -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_getData.tpl b/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_getData.tpl new file mode 100644 index 0000000..3f8214f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_getData.tpl @@ -0,0 +1,40 @@ +{{/* Get Certificate Data */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.scaleCertificate.getData" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the certificate +*/}} +{{- define "tc.v1.common.lib.scaleCertificate.getData" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{- $certID := (toString $objectData.id) -}} + + {{/* Make sure certificate exists */}} + {{- if hasKey $rootCtx.Values "ixCertificates" -}} + {{- if not $rootCtx.Values.ixCertificates -}} + {{- fail "Certificate - Expected non-empty " -}} + {{- end -}} + + {{- if not (hasKey $rootCtx.Values.ixCertificates $certID) -}} + {{- fail (printf "Certificate - Expected certificate with [%q] to exist in " $certID) -}} + {{- end -}} + {{- end -}} + + {{- $data := get $rootCtx.Values.ixCertificates $certID -}} + + {{- range $flag := (list "revoked" "expired") -}} + {{- if (get $data $flag) -}} + {{- fail (printf "Certificate - Expected non-%s certificate with [%q]" $flag $certID) -}} + {{- end -}} + {{- end -}} + + {{- range $key := (list "certificate" "privatekey") -}} + {{- if not (get $data $key) -}} + {{- fail (printf "Certificate - Expected non-empty [%s] in certificate with [%q] in " $key $certID) -}} + {{- end -}} + {{- end -}} + + + {{- $data | toJson -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_validation.tpl new file mode 100644 index 0000000..bd4f951 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/scaleCertificate/_validation.tpl @@ -0,0 +1,18 @@ +{{/* Certificate Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.scaleCertificate.validation" (dict "objectData" $objectData) -}} +objectData: The object data of the certificate. +*/}} + +{{- define "tc.v1.common.lib.scaleCertificate.validation" -}} + {{- $objectData := .objectData -}} + + {{- if not $objectData.id -}} + {{- fail "Certificate - Expected non-empty " -}} + {{- end -}} + + {{- if and $objectData.targetSelector (not (kindIs "map" $objectData.targetSelector)) -}} + {{- fail (printf "Certificate - Expected to be a [map], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/secret/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/secret/_validation.tpl new file mode 100644 index 0000000..5f930c5 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/secret/_validation.tpl @@ -0,0 +1,25 @@ +{{/* Secret Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.secret.validation" (dict "objectData" $objectData) -}} +objectData: + labels: The labels of the secret. + annotations: The annotations of the secret. + data: The data of the secret. +*/}} + +{{- define "tc.v1.common.lib.secret.validation" -}} + {{- $objectData := .objectData -}} + + {{- if and ( not $objectData.data ) ( not $objectData.stringData ) -}} + {{- fail "Secret - Expected non-empty or " -}} + {{- end -}} + + {{- if and $objectData.data (not (kindIs "map" $objectData.data)) -}} + {{- fail (printf "Secret - Expected to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}} + {{- end -}} + + {{- if and (hasKey $objectData "type") (not $objectData.type) -}} + {{- fail (printf "Secret - Found key, but it's empty") -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/_additionalAnnotations.tpl b/helm-charts/dashy/charts/common/templates/lib/service/_additionalAnnotations.tpl new file mode 100644 index 0000000..ab4e8dc --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/_additionalAnnotations.tpl @@ -0,0 +1,40 @@ +{{/* Service - MetalLB Annotations */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.metalLBAnnotations" (dict "rootCtx" $rootCtx "objectData" $objectData "annotations" $annotations) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +annotations: The annotations variable reference, to append the MetalLB annotations +*/}} + +{{- define "tc.v1.common.lib.service.metalLBAnnotations" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $annotations := .annotations -}} + + {{- $sharedKey := include "tc.v1.common.lib.chart.names.fullname" $rootCtx -}} + + {{/* A custom shared key can be defined per service even between multiple charts */}} + {{- with $objectData.sharedKey -}} + {{- $sharedKey = tpl . $rootCtx -}} + {{- end -}} + + {{- if $rootCtx.Values.global.addMetalLBAnnotations -}} + {{- $_ := set $annotations "metallb.universe.tf/allow-shared-ip" $sharedKey -}} + {{- end -}} +{{- end -}} + +{{/* Service - Traefik Annotations */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.traefikAnnotations" (dict "rootCtx" $rootCtx "annotations" $annotations) -}} +rootCtx: The root context of the chart. +annotations: The annotations variable reference, to append the Traefik annotations +*/}} + +{{- define "tc.v1.common.lib.service.traefikAnnotations" -}} + {{- $rootCtx := .rootCtx -}} + {{- $annotations := .annotations -}} + + {{- if $rootCtx.Values.global.addTraefikAnnotations -}} + {{- $_ := set $annotations "traefik.ingress.kubernetes.io/service.serversscheme" "https" -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/_ports.tpl b/helm-charts/dashy/charts/common/templates/lib/service/_ports.tpl new file mode 100644 index 0000000..55585e9 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/_ports.tpl @@ -0,0 +1,63 @@ +{{/* Service - Ports */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.ports" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the service +*/}} + +{{- define "tc.v1.common.lib.service.ports" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $tcpProtocols := (list "tcp" "http" "https") -}} + {{- range $name, $portValues := $objectData.ports -}} + {{- if $portValues.enabled -}} + {{- $protocol := $rootCtx.Values.fallbackDefaults.serviceProtocol -}} {{/* Default to fallback protocol, if no protocol is defined */}} + {{- $port := $portValues.port -}} + {{- $targetPort := $portValues.targetPort -}} + {{- $nodePort := $portValues.nodePort -}} + + {{/* Expand port */}} + {{- if (kindIs "string" $port) -}} + {{- $port = (tpl $port $rootCtx) -}} + {{- end -}} + {{- $port = int $port -}} + + {{/* Expand targetPort */}} + {{- if (kindIs "string" $targetPort) -}} + {{- $targetPort = tpl $targetPort $rootCtx -}} + {{- end -}} + {{- $targetPort = int $targetPort -}} + + {{/* Expand nodePort */}} + {{- if (kindIs "string" $nodePort) -}} + {{- $nodePort = tpl $nodePort $rootCtx -}} + {{- end -}} + {{- $nodePort = int $nodePort -}} + + {{- with $portValues.protocol -}} + {{- $protocol = tpl . $rootCtx -}} + + {{- if mustHas $protocol $tcpProtocols -}} + {{- $protocol = "tcp" -}} + {{- end -}} + {{- end }} +- name: {{ $name }} + port: {{ $port }} + protocol: {{ $protocol | upper }} + targetPort: {{ $targetPort | default $port }} {{/* If no targetPort, default to port */}} + {{- if (eq $objectData.type "NodePort") -}} + {{- if not $nodePort -}} + {{- fail "Service - Expected non-empty on NodePort service type" -}} + {{- end -}} + + {{- $minNodePort := int $rootCtx.Values.global.minNodePort -}} + {{- if (lt $nodePort $minNodePort) -}} + {{- fail (printf "Service - Expected to be higher than [%v], but got [%v]" $minNodePort $nodePort) -}} + {{- end }} + nodePort: {{ $nodePort }} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/service/_validation.tpl new file mode 100644 index 0000000..9c5c193 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/_validation.tpl @@ -0,0 +1,133 @@ +{{/* Service Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.validation" (dict "objectData" $objectData) -}} +objectData: + rootCtx: The root context of the chart. + objectData: The service object. +*/}} + +{{- define "tc.v1.common.lib.service.validation" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- if and $objectData.targetSelector (not (kindIs "string" $objectData.targetSelector)) -}} + {{- fail (printf "Service - Expected to be [string], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + + {{- $svcTypes := (list "ClusterIP" "LoadBalancer" "NodePort" "ExternalName" "ExternalIP") -}} + {{- if and $objectData.type (not (mustHas $objectData.type $svcTypes)) -}} + {{- fail (printf "Service - Expected to be one of [%s] but got [%s]" (join ", " $svcTypes) $objectData.type) -}} + {{- end -}} + + {{- $hasEnabledPort := false -}} + {{- if ne $objectData.type "ExternalName" -}} + {{- range $name, $port := $objectData.ports -}} + {{- if $port.enabled -}} + {{- $hasEnabledPort = true -}} + + {{- if and $port.targetSelector (not (kindIs "string" $port.targetSelector)) -}} + {{- fail (printf "Service - Expected to be [string], but got [%s]" (kindOf $port.targetSelector)) -}} + {{- end -}} + + {{- if not $port.port -}} + {{- fail (printf "Service - Expected non-empty ") -}} + {{- end -}} + + {{- $protocolTypes := (list "tcp" "udp" "http" "https") -}} + {{- if $port.protocol -}} + {{- if not (mustHas (tpl $port.protocol $rootCtx) $protocolTypes) -}} + {{- fail (printf "Service - Expected to be one of [%s] but got [%s]" (join ", " $protocolTypes) $port.protocol) -}} + {{- end -}} + {{- end -}} + + {{- end -}} + {{- end -}} + + {{- if not $hasEnabledPort -}} + {{- fail "Service - Expected enabled service to have at least one port" -}} + {{- end -}} + {{- end -}} + +{{- end -}} + +{{/* Service Primary Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.primaryValidation" $ -}} +*/}} + +{{- define "tc.v1.common.lib.service.primaryValidation" -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{- range $name, $service := .Values.service -}} + + {{/* If service is enabled */}} + {{- if $service.enabled -}} + {{- $hasEnabled = true -}} + + {{/* And service is primary */}} + {{- if and (hasKey $service "primary") ($service.primary) -}} + {{/* Fail if there is already a primary service */}} + {{- if $hasPrimary -}} + {{- fail "Service - Only one service can be primary" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- include "tc.v1.common.lib.servicePort.primaryValidation" (dict "objectData" $service.ports) -}} + + {{- end -}} + + {{- end -}} + {{- end -}} + + {{/* Require at least one primary service, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "Service - At least one enabled service must be primary" -}} + {{- end -}} + +{{- end -}} + +{{/* Service Port Primary Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.primaryValidation" (dict "objectData" $objectData -}} +objectData: + The ports of the service. +*/}} + +{{- define "tc.v1.common.lib.servicePort.primaryValidation" -}} + {{- $objectData := .objectData -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{- range $name, $port := $objectData -}} + + {{/* If service is enabled */}} + {{- if $port.enabled -}} + {{- $hasEnabled = true -}} + + {{/* And service is primary */}} + {{- if and (hasKey $port "primary") ($port.primary) -}} + + {{/* Fail if there is already a primary port */}} + {{- if $hasPrimary -}} + {{- fail "Service - Only one port per service can be primary" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- end -}} + + {{- end -}} + {{- end -}} + + {{/* Require at least one primary service, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "Service - At least one enabled port in service must be primary" -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_cluster_ip.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_cluster_ip.tpl new file mode 100644 index 0000000..97c8a37 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_cluster_ip.tpl @@ -0,0 +1,16 @@ +{{/* Service - clusterIP */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.clusterIP" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + + {{- with $objectData.clusterIP }} +clusterIP: {{ tpl . $rootCtx }} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalIPs.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalIPs.tpl new file mode 100644 index 0000000..fd53714 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalIPs.tpl @@ -0,0 +1,17 @@ +{{/* Service - externalIPs */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.externalIPs" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- with $objectData.externalIPs -}} + {{- range . }} +- {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalTrafficPolicy.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalTrafficPolicy.tpl new file mode 100644 index 0000000..55642a4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_externalTrafficPolicy.tpl @@ -0,0 +1,22 @@ +{{/* Service - externalTrafficPolicy */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.externalTrafficPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.externalTrafficPolicy" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + + {{- with $objectData.externalTrafficPolicy }} + {{- $policy := tpl . $rootCtx -}} + {{- $policies := (list "Cluster" "Local") -}} + + {{- if not (mustHas $policy $policies) -}} + {{- fail (printf "Service - Expected to be one of [%s], but got [%s]" (join ", " $policies) $policy) -}} + {{- end }} +externalTrafficPolicy: {{ $policy }} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_ipFamily.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_ipFamily.tpl new file mode 100644 index 0000000..eebdd47 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_ipFamily.tpl @@ -0,0 +1,38 @@ +{{/* Service - ipFamily */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.ipFamily" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.ipFamily" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- with $objectData.ipFamilyPolicy -}} + {{- $famPolicy := tpl . $rootCtx -}} + + {{- $stacks := (list "SingleStack" "PreferDualStack" "RequireDualStack") -}} + {{- if not (mustHas $famPolicy $stacks) -}} + {{- fail (printf "Service - Expected to be one of [%s], but got [%s]" (join ", " $stacks) $famPolicy) -}} + {{- end }} +ipFamilyPolicy: {{ $famPolicy }} + {{- end -}} + + {{- if and $objectData.ipFamilies (not (kindIs "slice" $objectData.ipFamilies)) -}} + {{- fail (printf "Service - Expected to be a list, but got a [%s]" (kindOf $objectData.ipFamilies)) -}} + {{- end -}} + + {{- with $objectData.ipFamilies }} +ipFamilies: + {{- range . }} + {{- $ipFam := tpl . $rootCtx -}} + + {{- $stacks := (list "IPv4" "IPv6") -}} + {{- if not (mustHas $ipFam $stacks) -}} + {{- fail (printf "Service - Expected to be one of [%s], but got [%s]" (join ", " $stacks) $ipFam) -}} + {{- end }} + - {{ $ipFam }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_publishNotReadyAddresses.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_publishNotReadyAddresses.tpl new file mode 100644 index 0000000..6f9626e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_publishNotReadyAddresses.tpl @@ -0,0 +1,19 @@ +{{/* Service - publishNotReadyAddresses */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.publishNotReadyAddresses" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + + {{- $publishAddr := false -}} + + {{- if (kindIs "bool" $objectData.publishNotReadyAddresses) -}} + {{- $publishAddr = $objectData.publishNotReadyAddresses -}} + {{- end -}} + + {{- $publishAddr -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_sessionAffinity.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_sessionAffinity.tpl new file mode 100644 index 0000000..a06d2b6 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeConfig/_sessionAffinity.tpl @@ -0,0 +1,42 @@ +{{/* Service - Session Affinity */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.sessionAffinity" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- with $objectData.sessionAffinity -}} + {{- $affinity := tpl . $rootCtx -}} + {{- $affinities := (list "ClientIP" "None") -}} + {{- if not (mustHas $affinity $affinities) -}} + {{- fail (printf "Service - Expected to be one of [%s], but got [%s]" (join ", " $affinities) $affinity) -}} + {{- end }} +sessionAffinity: {{ $affinity }} + {{- if eq $affinity "ClientIP" -}} + {{- with $objectData.sessionAffinityConfig -}} + {{- with .clientIP -}} + + {{- $timeout := .timeoutSeconds -}} + {{- if kindIs "string" $timeout -}} + {{- $timeout = tpl $timeout $rootCtx -}} + {{- end -}} + + {{- $timeout = int $timeout -}} + {{- if and $timeout (mustHas (kindOf $timeout) (list "float64" "int64" "int")) -}} + {{- if or (lt $timeout 0) (gt $timeout 86400) -}} + {{- fail (printf "Service - Expected to be between [0 - 86400], but got [%v]" $timeout) -}} + {{- end }} +sessionAffinityConfig: + clientIP: + timeoutSeconds: {{ $timeout }} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_clusterIP.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_clusterIP.tpl new file mode 100644 index 0000000..9b45d4f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_clusterIP.tpl @@ -0,0 +1,21 @@ +{{/* Service - ClusterIP Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.spec.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.spec.clusterIP" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + +type: ClusterIP +publishNotReadyAddresses: {{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim }} + {{- with (include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +externalIPs: + {{- . | nindent 2 }} + {{- end -}} + {{- include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.ipFamily" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalIP.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalIP.tpl new file mode 100644 index 0000000..e43e446 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalIP.tpl @@ -0,0 +1,19 @@ +{{/* Service - ExternalIP Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.spec.externalIP" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.spec.externalIP" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + +publishNotReadyAddresses: {{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim }} + {{- with (include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +externalIPs: + {{- . | nindent 2 }} + {{- end -}} + {{- include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.externalTrafficPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalName.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalName.tpl new file mode 100644 index 0000000..2f51214 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_externalName.tpl @@ -0,0 +1,26 @@ +{{/* Service - ExternalName Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.spec.externalName" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.spec.externalName" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + + {{- if not $objectData.externalName -}} + {{- fail "Service - Expected non-empty on ExternalName service type." -}} + {{- end }} + +type: ExternalName +externalName: {{ tpl $objectData.externalName $rootCtx }} +publishNotReadyAddresses: {{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim }} + {{- with (include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +externalIPs: + {{- . | nindent 2 }} + {{- end }} + {{- include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.externalTrafficPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_loadBalancer.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_loadBalancer.tpl new file mode 100644 index 0000000..261c188 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_loadBalancer.tpl @@ -0,0 +1,33 @@ +{{/* Service - LoadBalancer Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.spec.loadBalancer" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.spec.loadBalancer" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + +type: LoadBalancer +allocateLoadBalancerNodePorts: {{ $objectData.allocateLoadBalancerNodePorts | default false }} +publishNotReadyAddresses: {{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim }} + {{- with (include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +externalIPs: + {{- . | nindent 2 }} + {{- end -}} + {{- with $objectData.loadBalancerIP }} +loadBalancerIP: {{ tpl . $rootCtx }} + {{- end -}} + + {{- with $objectData.loadBalancerSourceRanges }} +loadBalancerSourceRanges: + {{- range . }} + - {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} + {{- include "tc.v1.common.lib.service.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.ipFamily" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.externalTrafficPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_nodePort.tpl b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_nodePort.tpl new file mode 100644 index 0000000..a6bb34f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/service/serviceTypeSpecs/_nodePort.tpl @@ -0,0 +1,22 @@ +{{/* Service - NodePort Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.service.spec.nodePort" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The service object data +*/}} + +{{- define "tc.v1.common.lib.service.spec.nodePort" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} + +type: NodePort +publishNotReadyAddresses: {{ include "tc.v1.common.lib.service.publishNotReadyAddresses" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim }} + {{- with (include "tc.v1.common.lib.service.externalIPs" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +externalIPs: + {{- . | nindent 2 }} + {{- end -}} + {{- include "tc.v1.common.lib.service.sessionAffinity" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.clusterIP" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.ipFamily" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} + {{- include "tc.v1.common.lib.service.externalTrafficPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 0 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/serviceAccount/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/serviceAccount/_validation.tpl new file mode 100644 index 0000000..6c82b2c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/serviceAccount/_validation.tpl @@ -0,0 +1,38 @@ +{{/* Service Account Primary Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.serviceAccount.primaryValidation" $ -}} +*/}} + +{{- define "tc.v1.common.lib.serviceAccount.primaryValidation" -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{- range $name, $serviceAccount := .Values.serviceAccount -}} + + {{/* If service account is enabled */}} + {{- if $serviceAccount.enabled -}} + {{- $hasEnabled = true -}} + + {{/* And service account is primary */}} + {{- if and (hasKey $serviceAccount "primary") ($serviceAccount.primary) -}} + + {{/* Fail if there is already a primary service account */}} + {{- if $hasPrimary -}} + {{- fail "Service Account - Only one service account can be primary" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- end -}} + + {{- end -}} + {{- end -}} + + {{/* Require at least one primary service account, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "Service Account - At least one enabled service account must be primary" -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/storage/_accessModes.tpl b/helm-charts/dashy/charts/common/templates/lib/storage/_accessModes.tpl new file mode 100644 index 0000000..7e45f68 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/storage/_accessModes.tpl @@ -0,0 +1,32 @@ +{{/* PVC - Access Modes */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.pvc.accessModes" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the pvc +*/}} + +{{- define "tc.v1.common.lib.pvc.accessModes" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + {{- $caller := .caller -}} + + {{- $accessModes := $objectData.accessModes -}} + + {{- if kindIs "string" $accessModes -}} + {{- $accessModes = (list $accessModes) -}} + {{- end -}} + + {{- if not $accessModes -}} + {{- $accessModes = $rootCtx.Values.fallbackDefaults.accessModes -}} + {{- end -}} + + {{- $validAccessModes := (list "ReadWriteOnce" "ReadOnlyMany" "ReadWriteMany" "ReadWriteOncePod") -}} + + {{- range $accessModes -}} + {{- $mode := tpl . $rootCtx -}} + {{- if not (mustHas $mode $validAccessModes) -}} + {{- fail (printf "%s - Expected entry to be one of [%s], but got [%s]" $caller (join ", " $validAccessModes) $mode) -}} + {{- end }} +- {{ $mode }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/storage/_storageClassName.tpl b/helm-charts/dashy/charts/common/templates/lib/storage/_storageClassName.tpl new file mode 100644 index 0000000..a4f4f6d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/storage/_storageClassName.tpl @@ -0,0 +1,54 @@ +{{/* PVC - Storage Class Name */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.storage.storageClassName" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: The object data of the pvc +*/}} +{{- define "tc.v1.common.lib.storage.storageClassName" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $caller := .caller -}} + + {{/* + If storageClass is defined on the objectData: + * "-" returns "", which means requesting a PV without class + * "SCALE-ZFS" returns the value set on Values.global.ixChartContext.storageClassName + (*) "SCALE-SMB" returns the value set on Values.global.ixChartContext.smbStorageClassName (Example for the future) + * Else return the original defined storageClass + + Else if we are in an ixChartContext, always return the storageClassName defined on the ixChartContext + + Else if there is a storageClass defined in Values.fallbackDefaults.storageClass, return this + + In any other case, return nothing + */}} + + {{- $className := "" -}} + {{- if $objectData.storageClass -}} + {{- $storageClass := (tpl $objectData.storageClass $rootCtx) -}} + + {{- if eq "-" $storageClass -}} + {{- $className = "\"\"" -}} + {{- else if eq "SCALE-ZFS" $storageClass -}} + {{- if not $rootCtx.Values.global.ixChartContext.storageClassName -}} + {{- fail (printf "%s - Expected non-empty on [SCALE-ZFS] storageClass" $caller) -}} + {{- end -}} + {{- $className = tpl $rootCtx.Values.global.ixChartContext.storageClassName $rootCtx -}} + {{- else -}} + {{- $className = tpl $storageClass $rootCtx -}} + {{- end -}} + + {{- else if $rootCtx.Values.global.ixChartContext -}} + {{- if not $rootCtx.Values.global.ixChartContext.storageClassName -}} + {{- fail (printf "%s - Expected non-empty " $caller) -}} + {{- end -}} + {{- $className = tpl $rootCtx.Values.global.ixChartContext.storageClassName $rootCtx -}} + + {{- else if $rootCtx.Values.fallbackDefaults.storageClass -}} + + {{- $className = tpl $rootCtx.Values.fallbackDefaults.storageClass $rootCtx -}} + + {{- end -}} + + {{- $className -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/storage/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/storage/_validation.tpl new file mode 100644 index 0000000..3c71a7b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/storage/_validation.tpl @@ -0,0 +1,39 @@ +{{/* PVC Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.persistence.validation" (dict "objectData" $objectData) -}} +objectData: + rootCtx: The root context of the chart. + objectData: The pvc object. +*/}} + +{{- define "tc.v1.common.lib.persistence.validation" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- $types := (list "pvc" "emptyDir" "nfs" "hostPath" "ixVolume" "secret" "configmap" "device") -}} + {{- if not (mustHas $objectData.type $types) -}} + {{- fail (printf "Persistence - Expected to be one of [%s], but got [%s]" (join ", " $types) $objectData.type) -}} + {{- end -}} + + {{- if and $objectData.targetSelector (not (kindIs "map" $objectData.targetSelector)) -}} + {{- fail (printf "Persistence - Expected to be [dict], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + +{{- end -}} + +{{/* VCT Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.vct.validation" (dict "objectData" $objectData) -}} +objectData: + rootCtx: The root context of the chart. + objectData: The vct object. +*/}} + +{{- define "tc.v1.common.lib.vct.validation" -}} + {{- $objectData := .objectData -}} + + {{- if and $objectData.targetSelector (not (kindIs "map" $objectData.targetSelector)) -}} + {{- fail (printf "Volume Claim Templates - Expected to be [dict], but got [%s]" (kindOf $objectData.targetSelector)) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/storage/_volumeClaimTemplates.tpl b/helm-charts/dashy/charts/common/templates/lib/storage/_volumeClaimTemplates.tpl new file mode 100644 index 0000000..37e55e0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/storage/_volumeClaimTemplates.tpl @@ -0,0 +1,66 @@ +{{/* Returns Volume Claim Templates */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.storage.volumeClaimTemplates" (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.storage.volumeClaimTemplates" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData -}} + + {{- range $name, $vctValues := $rootCtx.Values.volumeClaimTemplates -}} + + {{- if $vctValues.enabled -}} + {{- $vct := (mustDeepCopy $vctValues) -}} + + {{- $selected := false -}} + {{- $_ := set $vct "shortName" $name -}} + + {{- include "tc.v1.common.lib.vct.validation" (dict "objectData" $vct) -}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $vct.shortName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $vct "caller" "Volume Claim Templates") -}} + + {{/* If targetSelector is set, check if pod is selected */}} + {{- if $vct.targetSelector -}} + {{- if (mustHas $objectData.shortName (keys $vct.targetSelector)) -}} + {{- $selected = true -}} + {{- end -}} + + {{/* If no targetSelector is set or targetSelectAll, check if pod is primary */}} + {{- else -}} + {{- if $objectData.primary -}} + {{- $selected = true -}} + {{- end -}} + {{- end -}} + + {{/* If pod selected */}} + {{- if $selected -}} + {{- $vctSize := $rootCtx.Values.fallbackDefaults.vctSize -}} + {{- with $vct.size -}} + {{- $vctSize = tpl . $rootCtx -}} + {{- end }} +- metadata: + name: {{ $vct.shortName }} + {{- $labels := $vct.labels | default dict -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }} + labels: + {{- . | nindent 6 }} + {{- end -}} + {{- $annotations := $vct.annotations | default dict -}} + {{- with (include "tc.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }} + annotations: + {{- . | nindent 6 }} + {{- end }} + spec: + {{- with (include "tc.v1.common.lib.storage.storageClassName" (dict "rootCtx" $rootCtx "objectData" $vct "caller" "Volume Claim Templates") | trim) }} + storageClassName: {{ . }} + {{- end }} + accessModes: + {{- include "tc.v1.common.lib.pvc.accessModes" (dict "rootCtx" $rootCtx "objectData" $vct "caller" "Volume Claim Templates") | trim | nindent 6 }} + resources: + requests: + storage: {{ $vctSize }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_autoperms.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_autoperms.tpl new file mode 100644 index 0000000..773b45c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_autoperms.tpl @@ -0,0 +1,144 @@ +{{/* Contains the auto-permissions job */}} +{{- define "tc.v1.common.lib.util.autoperms" -}} + +{{- $permAllowedTypes := (list "hostPath" "emptyDir" "nfs" "ixVolume") -}} +{{/* If you change this path, you must change it under _volumeMounts.tpl too*/}} +{{- $basePath := "/mounts" -}} + +{{/* Init an empty dict to hold data */}} +{{- $mounts := dict -}} + +{{/* Go over persistence and gather needed data */}} +{{- range $name, $mount := .Values.persistence -}} + {{- if and $mount.enabled $mount.autoPermissions -}} + {{/* If autoPermissions is enabled...*/}} + {{- if $mount.autoPermissions.enabled -}} + {{- if or $mount.autoPermissions.chown $mount.autoPermissions.chmod -}} + {{- $type := $.Values.fallbackDefaults.persistenceType -}} + {{- if $mount.type -}} + {{- $type = $mount.type -}} + {{- end -}} + + {{- if not (mustHas $type $permAllowedTypes) -}} + {{- fail (printf "Auto Permissions - Allowed persistent types for auto permissions are [%v], but got [%v] on [%v]" (join ", " $permAllowedTypes) $type $name) -}} + {{- end -}} + + {{- if $mount.readOnly -}} + {{- fail (printf "Auto Permissions - You cannot change permissions/ownership automatically on [%v] with readOnly enabled" $name) -}} + {{- end -}} + + {{/* Add some data regarding what actions to perform */}} + {{- $_ := set $mounts $name $mount.autoPermissions -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if $mounts }} +enabled: true +type: Job +annotations: + "helm.sh/hook": pre-install, pre-upgrade + "helm.sh/hook-weight": "3" + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation,hook-failed +podSpec: + restartPolicy: Never + containers: + # If you change this name, you must change it under _volumeMounts.tpl + autopermissions: + enabled: true + primary: true + imageSelector: alpineImage + securityContext: + runAsNonRoot: false + runAsUser: 0 + capabilities: + disableS6Caps: true + add: + - CHOWN + - DAC_OVERRIDE + - FOWNER + resources: + limits: + cpu: 2000m + memory: 2Gi + probes: + liveness: + type: exec + command: + - cat + - /tmp/healthy + readiness: + type: exec + command: + - cat + - /tmp/healthy + startup: + type: exec + command: + - cat + - /tmp/healthy + command: + - /bin/sh + - -c + args: + - | + echo "Starting auto permissions job..." + touch /tmp/healthy + + echo "Automatically correcting ownership and permissions..." + + {{- range $name, $vol := $mounts }} + {{- $mountPath := (printf "%v/%v" $basePath $name) -}} + + {{- $user := "" -}} + {{- if $vol.user -}} + {{- $user = $vol.user -}} + {{- end -}} + + {{- $group := $.Values.securityContext.pod.fsGroup -}} + {{- if $vol.group -}} + {{- $group = $vol.group -}} + {{- end -}} + + {{- $r := "" -}} + {{- if $vol.recursive -}} + {{- $r = "-$" -}} + {{- end -}} + + {{/* Permissions */}} + {{- if $vol.chmod }} + echo "Automatically correcting permissions for {{ $mountPath }}..." + before=$(stat -c "%a" {{ $mountPath }}) + chmod {{ $r }} {{ $vol.chmod }} {{ $mountPath }} || echo "Failed setting permissions using chmod..." + echo "Permissions after: [$before]" + echo "Permissions after: [$(stat -c "%a" {{ $mountPath }})]" + echo "" + {{- end -}} + + {{/* Ownership */}} + {{- if $vol.chown }} + echo "Automatically correcting ownership for {{ $mountPath }}..." + before=$(stat -c "%u:%g" {{ $mountPath }}) + {{- if $.Values.global.ixChartContext }}{{/* TODO: Add user here too? */}} + /usr/sbin/nfs4xdr_winacl -a chown -G {{ $group }} {{ $r | lower }} -c "{{ $mountPath }}" -p "{{ $mountPath }}" || echo "Failed setting ownership using winacl..." + {{- else }} + chown {{ $r }} -f {{ $user }}:{{ $group }} {{ $mountPath }} || echo "Failed setting ownership using chown..." + {{- end }} + + echo "Ownership before: [$before]" + echo "Ownership after: [$(stat -c "%u:%g" {{ $mountPath }})]" + echo "" + {{- end -}} + {{- end }} + echo "Finished auto permissions job..." +{{- end -}} +{{- end -}} + +{{- define "tc.v1.common.lib.util.autoperms.job" -}} + {{- $job := (include "tc.v1.common.lib.util.autoperms" $) | fromYaml -}} + {{- if $job -}} + # If you change this name, you must change it under _volumes.tpl + {{- $_ := set $.Values.workload "autopermissions" $job -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_chartcontext.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_chartcontext.tpl new file mode 100644 index 0000000..429ec76 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_chartcontext.tpl @@ -0,0 +1,152 @@ +{{/* Returns the primary Workload object */}} +{{- define "tc.v1.common.lib.util.chartcontext" -}} + {{/* Create defaults */}} + {{- $protocol := "https" -}} + {{- $host := "127.0.0.1" -}} + {{- $port := "443" -}} + {{- $url := "" -}} + {{- $podCIDR := "172.16.0.0/16" -}} + {{- $svcCIDR := "172.17.0.0/16" -}} + + {{/* set temporary storage for ingress name and port */}} + {{- $targetIngress := "" -}} + {{- $selectedIngress := "" -}} + + {{/* Get service, default to primary */}} + {{- $selectedService := fromYaml (include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $ )) -}} + + {{/* read loadbalancer IPs for metallb */}} + {{- if eq $selectedService.type "LoadBalancer" -}} + {{- with $selectedService.loadBalancerIP -}} + {{- $host = toString . -}} + {{- end -}} + + {{/* set temporary storage for port name and port */}} + {{- $targetPort := "" -}} + {{- $selectedPort := "" -}} + {{/* Fetch port values */}} + {{- $targetPort = include "tc.v1.common.lib.util.service.ports.primary" (dict "svcName" $selectedService.shortName "svcValues" $selectedService) -}} + {{- $selectedPort = get $selectedService.ports $targetPort -}} + {{/* store port number */}} + {{- $port = $selectedPort.port -}} + {{- end -}} + + {{/* Fetch ingress values */}} + {{- $targetIngress = include "tc.v1.common.lib.util.ingress.primary" $ -}} + {{- $selectedIngress = get $.Values.ingress $targetIngress -}} + + {{/* store host from ingress number */}} + {{- if $selectedIngress -}} + {{- if $selectedIngress.enabled -}} + {{- with (index $selectedIngress.hosts 0) -}} + {{- $host = .host -}} + {{- end -}} + + {{/* Get the port for the ingress entrypoint */}} + + {{- $namespace := "tc-system" -}} + {{- if $.Values.operator.traefik -}} + {{- if $.Values.operator.traefik.namespace -}} + {{- $namespace = $.Values.operator.traefik.namespace -}} + {{- end -}} + {{- end -}} + + {{- if $selectedIngress.ingressClassName -}} + {{- if $.Values.global.ixChartContext -}} + {{- $namespace = (printf "ix-%s" $selectedIngress.ingressClassName) -}} + {{- else -}} + {{- $namespace = $selectedIngress.ingressClassName -}} + {{- end -}} + + {{- end -}} + + {{- $traefikportalhook := lookup "v1" "ConfigMap" $namespace "portalhook" | default dict -}} + {{/* If there is no portalhook */}} + {{- if not $traefikportalhook -}} + {{/* Get all configmaps */}} + {{- $hooks := lookup "v1" "ConfigMap" $namespace "" -}} + + {{- $portalHooks := list -}} + {{- range $hook := ($hooks.items | default list) -}} + {{- $hookData := (get $hook "data") -}} + {{- $hookMetaData := (get $hook "metadata") -}} + {{- if and $hookData $hookMetaData -}} + {{/* Filter portalhook-* */}} + {{- if $hookMetaData.name -}} + {{- if hasPrefix "portalhook-" $hookMetaData.name -}} + {{- $portalHooks = mustAppend $portalHooks $hook -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{/* use the first available portalhook */}} + {{- if $portalHooks -}} + {{- $traefikportalhook = index $portalHooks 0 -}} + {{- end -}} + {{- end -}} + + {{- $entrypoint := "websecure" -}} + {{- if $selectedIngress.entrypoint -}} + {{- $entrypoint = $selectedIngress.entrypoint -}} + {{- end -}} + {{- if $traefikportalhook -}} + {{- if (get $traefikportalhook.data $entrypoint) -}} + {{- $port = (get $traefikportalhook.data $entrypoint) -}} + {{- else if $traefikportalhook.data.websecure -}} + {{- $port = $traefikportalhook.data.websecure -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $port = toString $port -}} + + {{/* sanitise */}} + {{- if eq $port "443" -}} + {{- $protocol = "https" -}} + {{- end -}} + + {{- if eq $port "80" -}} + {{- $protocol = "http" -}} + {{- end -}} + + {{- if or (and (eq $protocol "https") (eq $port "443")) (and (eq $protocol "http") (eq $port "80")) -}} + {{- $port = "" -}} + {{- end -}} + + {{/* Construct URL*/}} + {{- if $port -}} + {{- $url = printf "%s://%s:%s" $protocol $host $port -}} + {{- else -}} + {{- $url = printf "%s://%s" $protocol $host -}} + {{- end -}} + + {{/* TrueNAS SCALE specific code */}} + {{- if $.Values.global.ixChartContext -}} + {{- if $.Values.global.ixChartContext.kubernetes_config -}} + {{- $podCIDR = $.Values.global.ixChartContext.kubernetes_config.cluster_cidr -}} + {{- $svcCIDR = $.Values.global.ixChartContext.kubernetes_config.service_cidr -}} + {{- end -}} + {{- else -}} + {{/* TODO: Find ways to implement CIDR detection */}} + {{- end -}} + + {{- if $.Values.chartContext -}} + {{- if $.Values.chartContext.APPURL -}} + {{- $url = $.Values.chartContext.APPURL -}} + {{- end -}} + + {{- if $.Values.chartContext.podCIDR -}} + {{- $podCIDR = $.Values.chartContext.podCIDR -}} + {{- end -}} + + {{- if $.Values.chartContext.svcCIDR -}} + {{- $svcCIDR = $.Values.chartContext.svcCIDR -}} + {{- end -}} + {{- end -}} + + {{- $_ := set $.Values.chartContext "APPURL" $url -}} + {{- $_ := set $.Values.chartContext "podCIDR" $podCIDR -}} + {{- $_ := set $.Values.chartContext "svcCIDR" $svcCIDR -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_certificate.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_certificate.tpl new file mode 100644 index 0000000..fabc2b3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_certificate.tpl @@ -0,0 +1,23 @@ +{{/* Return the name of the primary Cert object */}} +{{- define "tc.v1.common.lib.util.cert.primary" -}} + {{- $Certs := $.Values.cert -}} + + {{- $enabledCerts := dict -}} + {{- range $name, $cert := $Certs -}} + {{- if $cert.enabled -}} + {{- $_ := set $enabledCerts $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $cert := $enabledCerts -}} + {{- if and (hasKey $cert "primary") $cert.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $Certs | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_cnpg.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_cnpg.tpl new file mode 100644 index 0000000..07ea0c0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_cnpg.tpl @@ -0,0 +1,23 @@ +{{/* Return the name of the primary cnpg object */}} +{{- define "tc.v1.common.lib.util.cnpg.primary" -}} + {{- $cnpgs := .Values.cnpg -}} + + {{- $enabledcnpges := dict -}} + {{- range $name, $cnpg := $cnpgs -}} + {{- if $cnpg.enabled -}} + {{- $_ := set $enabledcnpges $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $cnpg := $enabledcnpges -}} + {{- if and (hasKey $cnpg "primary") $cnpg.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $enabledcnpges | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_ingress.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_ingress.tpl new file mode 100644 index 0000000..e1e50b6 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_ingress.tpl @@ -0,0 +1,23 @@ +{{/* Return the name of the primary ingress object */}} +{{- define "tc.v1.common.lib.util.ingress.primary" -}} + {{- $ingresses := $.Values.ingress -}} + + {{- $enabledIngresses := dict -}} + {{- range $name, $ingress := $ingresses -}} + {{- if $ingress.enabled -}} + {{- $_ := set $enabledIngresses $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $ingress := $enabledIngresses -}} + {{- if and (hasKey $ingress "primary") $ingress.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $enabledIngresses | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_metrics.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_metrics.tpl new file mode 100644 index 0000000..f085399 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_metrics.tpl @@ -0,0 +1,30 @@ +{{/* Return the name of the primary metrics object */}} +{{- define "tc.v1.common.lib.util.metrics.primary" -}} + {{- $metrics := .Values.metrics -}} + + {{- $enabledMetrics := dict -}} + {{- range $name, $metrics := $metrics -}} + {{- if $metrics.enabled -}} + {{- $_ := set $enabledMetrics $name $metrics -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $metrics := $enabledMetrics -}} + {{- if (hasKey $metrics "primary") -}} + {{- if $metrics.primary -}} + {{- if $result -}} + {{- fail "More than one metrics are set as primary. This is not supported." -}} + {{- end -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- if eq (len $enabledMetrics) 1 -}} + {{- $result = keys $enabledMetrics | mustFirst -}} + {{- end -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_port.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_port.tpl new file mode 100644 index 0000000..f3e21a8 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_port.tpl @@ -0,0 +1,41 @@ +{{/* A dict containing .values and .serviceName is passed when this function is called */}} +{{/* Return the primary port for a given Service object. */}} +{{- define "tc.v1.common.lib.util.service.ports.primary" -}} + {{- $svcName := .svcName -}} + {{- $svcValues := .svcValues -}} + + {{- $enabledPorts := dict -}} + + {{- range $name, $port := $svcValues.ports -}} + {{- if $port.enabled -}} + {{- $_ := set $enabledPorts $name $port -}} + {{- end -}} + {{- end -}} + + {{- if not $enabledPorts -}} + {{- fail (printf "No ports are enabled for the service: (%s)" $svcName) -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $port := $enabledPorts -}} + {{- if (hasKey $port "primary") -}} + {{- if $port.primary -}} + {{- if $result -}} + {{- fail (printf "More than one ports are set as primary in the (%s) service. This is not supported." $svcName ) -}} + {{- end -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- if eq (len $enabledPorts) 1 -}} + {{- $result = keys $enabledPorts | mustFirst -}} + {{- else -}} + {{- if $enabledPorts -}} + {{- fail (printf "At least one port must be set as primary in service (%s)" $svcName) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_route.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_route.tpl new file mode 100644 index 0000000..04da801 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_route.tpl @@ -0,0 +1,23 @@ +{{/* Return the name of the primary route object */}} +{{- define "tc.v1.common.lib.util.route.primary" -}} + {{- $routees := $.Values.route -}} + + {{- $enabledroutees := dict -}} + {{- range $name, $route := $routees -}} + {{- if $route.enabled -}} + {{- $_ := set $enabledroutees $name . -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $route := $enabledroutees -}} + {{- if and (hasKey $route "primary") $route.primary -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- $result = keys $enabledroutees | first -}} + {{- end -}} + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_service.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_service.tpl new file mode 100644 index 0000000..b661a25 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_service.tpl @@ -0,0 +1,39 @@ +{{/* Returns the primary service object */}} +{{- define "tc.v1.common.lib.util.service.primary" -}} + {{- $services := .services -}} + + {{- $enabledServices := dict -}} + {{- range $name, $service := $services -}} + {{- if $service.enabled -}} + {{- $_ := set $enabledServices $name $service -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $service := $enabledServices -}} + {{- if (hasKey $service "primary") -}} + {{- if $service.primary -}} + {{- if $result -}} + {{- fail "More than one services are set as primary. This is not supported." -}} + {{- end -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- if eq (len $enabledServices) 1 -}} + {{- $result = keys $enabledServices | mustFirst -}} + {{- else -}} + {{- if $enabledServices -}} + {{- fail "At least one Service must be set as primary" -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if $result -}} + {{- $result -}} + {{- else -}} + {{- fail "No primary and enabled service found" -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_primary_workload.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_primary_workload.tpl new file mode 100644 index 0000000..b24836b --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_primary_workload.tpl @@ -0,0 +1,35 @@ +{{/* Returns the primary Workload object */}} +{{- define "tc.v1.common.lib.util.workload.primary" -}} + {{- $Workloads := .workload -}} + + {{- $enabledWorkloads := dict -}} + {{- range $name, $Workload := $Workloads -}} + {{- if $Workload.enabled -}} + {{- $_ := set $enabledWorkloads $name $Workload -}} + {{- end -}} + {{- end -}} + + {{- $result := "" -}} + {{- range $name, $Workload := $enabledWorkloads -}} + {{- if (hasKey $Workload "primary") -}} + {{- if $Workload.primary -}} + {{- if $result -}} + {{- fail "More than one Workloads are set as primary. This is not supported." -}} + {{- end -}} + {{- $result = $name -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $result -}} + {{- if eq (len $enabledWorkloads) 1 -}} + {{- $result = keys $enabledWorkloads | mustFirst -}} + {{- else -}} + {{- if $enabledWorkloads -}} + {{- fail "At least one Workload must be set as primary" -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- $result -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_register_operator.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_register_operator.tpl new file mode 100644 index 0000000..682ec42 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_register_operator.tpl @@ -0,0 +1,25 @@ +{{- define "tc.v1.common.lib.util.operator.register" -}} + {{- if .Values.operator.register -}} + + {{/* If it is an install operator check the operator does not exist */}} + {{/* We do not want to fail on upgrades, as the operator will always be present */}} + {{- if $.Release.IsInstall -}} + {{- $opExists := include "tc.v1.common.lib.util.operator.verify" (dict "rootCtx" $ "opName" $.Chart.Name) -}} + {{/* If the operator exists, fail to continue */}} + {{- if eq $opExists "true" -}} + {{- fail (printf "Operator [%v] is already installed. Can only be installed once" $.Chart.Name) -}} + {{- end -}} + {{- end -}} + + {{/* Create/Update the ConfigMap */}} + {{- $objectData := (dict "enabled" true + "data" (dict "tc-operator-name" $.Chart.Name + "tc-operator-version" $.Chart.Version)) -}} + {{/* data.tc-operator-name - The name the operator */}} + {{/* data.tc-operator-version - The version of the installed operator */}} + + {{/* Create a configmap with the above data */}} + {{/* Name will be expanded to "release-name-chart-name-tc-data" */}} + {{- $_ := set $.Values.configmap "tc-data" $objectData -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_stopAll.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_stopAll.tpl new file mode 100644 index 0000000..dfd4d36 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_stopAll.tpl @@ -0,0 +1,16 @@ +{{- define "tc.v1.common.lib.util.stopAll" -}} + {{- $rootCtx := . -}} + + {{- $stop := "" -}} + {{- if $rootCtx.Values.global.stopAll -}} + {{- $stop = true -}} + {{- end -}} + + {{- with $rootCtx.Values.global.ixChartContext -}} + {{- if .isStopped -}} + {{- $stop = true -}} + {{- end -}} + {{- end -}} + + {{- $stop -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/util/_verify_operator.tpl b/helm-charts/dashy/charts/common/templates/lib/util/_verify_operator.tpl new file mode 100644 index 0000000..f427eec --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/util/_verify_operator.tpl @@ -0,0 +1,135 @@ +{{- define "tc.v1.common.lib.util.operator.verifyAll" -}} + {{- if .Values.operator.verify.enabled -}} + {{/* Go over all operators that need to be verified */}} + {{- $operatorList := .Values.operator.verify.additionalOperators -}} + + {{- $cnpg := false -}} + {{- range $opName := $.Values.cnpg -}} + {{- if .enabled -}} + {{- $cnpg = true -}} + {{- end -}} + {{- end -}} + {{- if $cnpg -}} + {{- $operatorList = mustAppend $operatorList "cloudnative-pg" -}} + {{- end -}} + + {{- $ingress := false -}} + {{- range $opName := $.Values.ingress -}} + {{- if .enabled -}} + {{- $ingress = true -}} + {{- end -}} + {{- end -}} + {{- if $ingress -}} + {{- $operatorList = mustAppend $operatorList "traefik" -}} + {{- end -}} + + {{- $clusterCertificate := false -}} + {{- if $.Values.clusterCertificates -}} + {{- range $opName := $.Values.clusterCertificates.certificates -}} + {{- if .enabled -}} + {{- $clusterCertificate = true -}} + {{- end -}} + {{- end -}} + {{- if $clusterCertificate -}} + {{- $operatorList = mustAppend $operatorList "kubernetes-reflector" -}} + {{- end -}} + {{- end -}} + + {{- $metrics := false -}} + {{- range $opName := $.Values.metrics -}} + {{- if .enabled -}} + {{- $metrics = true -}} + {{- end -}} + {{- end -}} + {{- if $metrics -}} + {{- $operatorList = mustAppend $operatorList "prometheus-operator" -}} + {{- end -}} + + {{- range $opName := $operatorList -}} + {{- $fetchedOpData := include "tc.v1.common.lib.util.operator.verify" (dict "rootCtx" $ "opName" $opName) -}} + + {{/* If the operator was not found */}} + {{- if eq $fetchedOpData "false" -}} + {{/* Fail only if explicitly asked */}} + {{- if $.Values.operator.verify.failOnError -}} + {{- fail (printf "Operator [%s] has to be installed first" $opName) -}} + {{- end -}} + {{/* If $fetchedOpData is not false, we should have JSON data */}} + {{- else -}} + {{- $opData := ($fetchedOpData | fromJson) -}} + {{- $_ := set $.Values.operator $opName $opData -}} + + {{/* Prepare the data for the cache ConfigMap */}} + {{- $cacheDataWrite := (dict "enabled" true "data" $opData) -}} + {{/* Create/Update the Configmap - ConfigMap name will be expanded to "$fullname-operator-$opName" */}} + {{- $_ := set $.Values.configmap (printf "operator-%s" $opName) $cacheDataWrite -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "tc.v1.common.lib.util.operator.verify" -}} + {{- $rootCtx := .rootCtx -}} + {{- $opName := .opName -}} + + {{- $opExists := false -}} + {{- $opData := dict -}} + {{- $fullname := (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) -}} + {{- $cache := (lookup "v1" "ConfigMap" $rootCtx.Release.Namespace (printf "%v-operator-%v" $fullname $opName)) | default dict -}} + + {{- if $cache.data -}} + {{/* Fetch data that the operator itself stored in the tc-data configmap */}} + {{- $viaCache := (lookup "v1" "ConfigMap" $cache.data.namespace (printf "%v-tc-data" $fullname)) | default dict -}} + {{- if $viaCache -}} + {{- if not $viaCache.data -}} + {{- fail (printf "Operator - Expected [tc-data] ConfigMap to have non-empty [data] for operator [%v]" $opName) -}} + {{- end -}} + + {{- $name := (get $viaCache.data "tc-operator-name") -}} + {{- $version := (get $viaCache.data "tc-operator-version") -}} + + {{/* If fetched name does not matches the "$opName"... */}} + {{- if ne $name $opName -}} + {{- fail (printf "Operator - ConfigMap [tc-data] does not contain the operator [%v] name. Something went wrong." $opName) -}} + {{- end -}} + + {{/* If matches continue and mark operator as found */}} + {{- $opExists = true -}} + {{/* Prepare the data */}} + {{- $opData = (dict "name" $name + "namespace" $viaCache.metadata.namespace + "version" $version) -}} + {{- end -}} + {{- end -}} + + {{/* Go over all configmaps */}} + {{- if not $opExists -}} + {{- range $index, $cm := (lookup "v1" "ConfigMap" "" "").items -}} + {{- if $cm.data -}} + {{/* If "tc-operator-name" does not exist will return "" */}} + {{- $name := (get $cm.data "tc-operator-name") -}} + {{- $version := (get $cm.data "tc-operator-version") -}} + + {{/* If fetched name matches the "$opName"... */}} + {{- if eq $name $opName -}} + {{- if $opExists -}} + {{- fail (printf "Found duplicate configmaps for operator [%s]" $opName) -}} + {{- end -}} + + {{/* Mark operator as found*/}} + {{- $opExists = true -}} + {{- $opData = (dict "name" $name + "namespace" $cm.metadata.namespace + "version" $version) -}} + + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if $opExists -}} {{/* If operator was found, return its data as JSON */}} + {{- $opData | toJson -}} + {{- else -}} {{/* If operator was not found, return stringified false */}} + {{- $opExists | toString -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/webhook/_admissionReviewVersions.tpl b/helm-charts/dashy/charts/common/templates/lib/webhook/_admissionReviewVersions.tpl new file mode 100644 index 0000000..ff4a81d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/webhook/_admissionReviewVersions.tpl @@ -0,0 +1,8 @@ +{{- define "tc.v1.common.lib.webhook.admissionReviewVersions" -}} + {{- $admissionReviewVersions := .admissionReviewVersions -}} + {{- $rootCtx := .rootCtx }} +admissionReviewVersions: + {{- range $admissionReviewVersions }} + - {{ tpl . $rootCtx }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/webhook/_clientConfig.tpl b/helm-charts/dashy/charts/common/templates/lib/webhook/_clientConfig.tpl new file mode 100644 index 0000000..14b2444 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/webhook/_clientConfig.tpl @@ -0,0 +1,22 @@ +{{- define "tc.v1.common.lib.webhook.clientConfig" -}} + {{- $clientConfig := .clientConfig -}} + {{- $rootCtx := .rootCtx }} +clientConfig: + {{- if $clientConfig.caBundle }} + caBundle: {{ tpl $clientConfig.caBundle $rootCtx | quote }} + {{- end -}} + {{- if $clientConfig.url }} + url: {{ tpl $clientConfig.url $rootCtx | quote }} + {{- end -}} + {{- if $clientConfig.service }} + service: + name: {{ tpl $clientConfig.service.name $rootCtx }} + namespace: {{ tpl $clientConfig.service.namespace $rootCtx }} + {{- with $clientConfig.service.path }} + path: {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- with $clientConfig.service.port }} + port: {{ tpl . $rootCtx }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/webhook/_rules.tpl b/helm-charts/dashy/charts/common/templates/lib/webhook/_rules.tpl new file mode 100644 index 0000000..dfa1952 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/webhook/_rules.tpl @@ -0,0 +1,26 @@ +{{- define "tc.v1.common.lib.webhook.rules" -}} + {{- $rules := .rules -}} + {{- $rootCtx := .rootCtx }} +rules: + {{- range $rule := $rules }} + - apiVersions: + {{- range $rule.apiVersions }} + - {{ tpl . $rootCtx | quote }} + {{- end }} + apiGroups: + {{- range $rule.apiGroups }} + - {{ tpl . $rootCtx | quote }} + {{- end }} + operations: + {{- range $rule.operations }} + - {{ tpl . $rootCtx | quote }} + {{- end }} + resources: + {{- range $rule.resources }} + - {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- with $rule.scope }} + scope: {{ tpl . $rootCtx | quote }} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/webhook/_validation.tpl b/helm-charts/dashy/charts/common/templates/lib/webhook/_validation.tpl new file mode 100644 index 0000000..6ab05d4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/webhook/_validation.tpl @@ -0,0 +1,152 @@ +{{- define "tc.v1.common.lib.webhook.validation" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + + {{- if not $objectData.type -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName) -}} + {{- end -}} + + {{- $type := tpl $objectData.type $rootCtx -}} + {{- $types := (list "validating" "mutating") -}} + {{- if not (mustHas $type $types) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName (join ", " $types) $type) -}} + {{- end -}} + + {{- if not $objectData.webhooks -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName) -}} + {{- end -}} + + {{- if not (kindIs "slice" $objectData.webhooks) -}} + {{- fail (printf "Webhook - Expected in to be a list, but got [%v]" $objectData.shortName (kindOf $objectData.webhooks)) -}} + {{- end -}} + + {{- range $webhook := $objectData.webhooks -}} + {{- if not $webhook.name -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName) -}} + {{- end -}} + + {{- $webhookName := tpl $webhook.name $rootCtx -}} + + {{- if not $webhook.admissionReviewVersions -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- range $adm := $webhook.admissionReviewVersions -}} + {{- if not (kindIs "string" $adm) -}} + {{- fail (printf "Webhook - Expected in to be a string" $objectData.shortName $webhookName) -}} + {{- end -}} + {{- end -}} + + {{- if not $webhook.clientConfig -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- with $webhook.clientConfig -}} + {{- if and .url .service -}} + {{- fail (printf "Webhook - Expected either or in to be defined, but got both" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- $service := .service -}} + + {{- if $service -}} + {{- if not $service.name -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not $service.namespace -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- if not $webhook.rules -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not (kindIs "slice" $webhook.rules) -}} + {{- fail (printf "Webhook - Expected in to be a list, but got [%v]" $objectData.shortName $webhookName (kindOf $webhook.rules)) -}} + {{- end -}} + + {{- range $rule := $webhook.rules -}} + {{- if not $rule.apiGroups -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not $rule.apiVersions -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not $rule.operations -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not $rule.resources -}} + {{- fail (printf "Webhook - Expected in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- $scopes := (list "Cluster" "Namespaced" "*") -}} + {{- with $rule.scope -}} + {{- $scope := tpl . $rootCtx -}} + {{- if not (mustHas $scope $scopes) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName $webhookName (join ", " $scopes) $scope) -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- with $webhook.failurePolicy -}} + {{- $policy := tpl . $rootCtx -}} + {{- $failPolicies := (list "Ignore" "Fail") -}} + {{- if not (mustHas $policy $failPolicies) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName $webhookName (join ", " $failPolicies) $policy) -}} + {{- end -}} + {{- end -}} + + {{- with $webhook.matchPolicy -}} + {{- $policy := tpl . $rootCtx -}} + {{- $matchPolicies := (list "Exact" "Equivalent") -}} + {{- if not (mustHas $policy $matchPolicies) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName $webhookName (join ", " $matchPolicies) $policy) -}} + {{- end -}} + {{- end -}} + + {{- if and (eq $type "validating") $webhook.reinvocationPolicy -}} + {{- fail (printf "Webhook - Expected [mutating] type in when is defined" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if and (eq $type "mutating") $webhook.reinvocationPolicy -}} + {{- $policy := tpl $webhook.reinvocationPolicy $rootCtx -}} + {{- $reinvPolicies := (list "Never" "IfNeeded") -}} + {{- if not (mustHas $policy $reinvPolicies) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName $webhookName (join ", " $reinvPolicies) $policy) -}} + {{- end -}} + {{- end -}} + + {{- with $webhook.sideEffects -}} + {{- $effect := tpl . $rootCtx -}} + {{- $sideEffects := (list "None" "NoneOnDryRun") -}} + {{- if not (mustHas $effect $sideEffects) -}} + {{- fail (printf "Webhook - Expected in to be one of [%s], but got [%v]" $objectData.shortName $webhookName (join ", " $sideEffects) $effect) -}} + {{- end -}} + {{- end -}} + + {{- if (hasKey $webhook "timeoutSeconds") -}} + {{- if (kindIs "invalid" $webhook.timeoutSeconds) -}} + {{- fail (printf "Webhook - Expected the defined key in to not be empty" $objectData.shortName $webhookName) -}} + {{- end -}} + + {{- if not (mustHas (kindOf $webhook.timeoutSeconds) (list "int" "int64" "float64")) -}} + {{- fail (printf "Webhook - Expected in to be an integer, but got [%v]" $objectData.shortName $webhookName (kindOf $webhook.timeoutSeconds)) -}} + {{- end -}} + + {{- if (lt (int $webhook.timeoutSeconds) 1) -}} + {{- fail (printf "Webhook - Expected in to be greater than 0, but got [%v]" $objectData.shortName $webhookName $webhook.timeoutSeconds) -}} + {{- end -}} + + {{- if (gt (int $webhook.timeoutSeconds) 30) -}} + {{- fail (printf "Webhook - Expected in to be less than 30, but got [%v]" $objectData.shortName $webhookName $webhook.timeoutSeconds) -}} + {{- end -}} + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/webhook/_webhook.tpl b/helm-charts/dashy/charts/common/templates/lib/webhook/_webhook.tpl new file mode 100644 index 0000000..f49ea21 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/webhook/_webhook.tpl @@ -0,0 +1,31 @@ +{{- define "tc.v1.common.lib.webhook" -}} + {{- $webhook := .webhook -}} + {{- $rootCtx := .rootCtx }} +- name: {{ tpl $webhook.name $rootCtx }} + {{- with $webhook.failurePolicy }} + failurePolicy: {{ tpl . $rootCtx }} + {{- end -}} + {{- with $webhook.matchPolicy }} + matchPolicy: {{ tpl . $rootCtx }} + {{- end -}} + {{- with $webhook.reinvocationPolicy }} + reinvocationPolicy: {{ tpl . $rootCtx }} + {{- end -}} + {{- with $webhook.sideEffects }} + sideEffects: {{ tpl . $rootCtx }} + {{- end -}} + {{- with $webhook.timeoutSeconds }} + timeoutSeconds: {{ . }} + {{- end -}} + {{- include "tc.v1.common.lib.webhook.admissionReviewVersions" (dict "rootCtx" $rootCtx "admissionReviewVersions" $webhook.admissionReviewVersions) | trim | nindent 2 -}} + {{- include "tc.v1.common.lib.webhook.clientConfig" (dict "rootCtx" $rootCtx "clientConfig" $webhook.clientConfig) | trim | nindent 2 -}} + {{- include "tc.v1.common.lib.webhook.rules" (dict "rootCtx" $rootCtx "rules" $webhook.rules) | trim | nindent 2 -}} + {{- with $webhook.namespaceSelector }} + namespaceSelector: + {{- tpl (toYaml $webhook.namespaceSelector) $rootCtx | nindent 2 -}} + {{- end -}} + {{- with $webhook.objectSelector }} + objectSelector: + {{- tpl (toYaml $webhook.objectSelector) $rootCtx | nindent 2 -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_cronjobSpec.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_cronjobSpec.tpl new file mode 100644 index 0000000..cd1f1a0 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_cronjobSpec.tpl @@ -0,0 +1,31 @@ +{{/* CronJob Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.cronjobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + schedule: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + concurrencyPolicy: Allow, Forbid, or Replace. Defaults to Allow. + failedJobsHistoryLimit: The number of failed finished jobs to retain. Defaults to 1. + successfulJobsHistoryLimit: The number of successful finished jobs to retain. Defaults to 3. + startingDeadlineSeconds: Optional deadline in seconds for starting the job if it misses scheduled time for any reason. Defaults to nil. + timezone: The timezone name. Defaults to .Values.TZ + +jobSpec data +*/}} +{{- define "tc.v1.common.lib.workload.cronjobSpec" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $suspend := $objectData.suspend | default false -}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $suspend = true -}} + {{- end }} +timeZone: {{ (tpl ($objectData.timezone | default $rootCtx.Values.TZ) $rootCtx) | quote }} +schedule: {{ (tpl $objectData.schedule $rootCtx) | quote }} +concurrencyPolicy: {{ $objectData.concurrencyPolicy | default "Forbid" }} +failedJobsHistoryLimit: {{ $objectData.failedJobsHistoryLimit | default 1 }} +successfulJobsHistoryLimit: {{ $objectData.successfulJobsHistoryLimit | default 3 }} +startingDeadlineSeconds: {{ $objectData.startingDeadlineSeconds | default 600 }} +suspend: {{ $suspend }} +jobTemplate: + spec: + {{- include "tc.v1.common.lib.workload.jobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) | indent 4 }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_daemonsetSpec.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_daemonsetSpec.tpl new file mode 100644 index 0000000..82e5aba --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_daemonsetSpec.tpl @@ -0,0 +1,27 @@ +{{/* DaemonSet Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.daemonsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + revisionHistoryLimit: The number of old ReplicaSets to retain to allow rollback. + strategy: The daemonset strategy to use to replace existing pods with new ones. +*/}} +{{- define "tc.v1.common.lib.workload.daemonsetSpec" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $strategy := $objectData.strategy | default "RollingUpdate" }} +revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} +updateStrategy: + type: {{ $strategy }} + {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} + {{ if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "maxSurge")) }} + rollingUpdate: + {{- if hasKey $objectData.rollingUpdate "maxUnavailable" }} + maxUnavailable: {{ $objectData.rollingUpdate.maxUnavailable }} + {{- end -}} + {{- if hasKey $objectData.rollingUpdate "maxSurge" }} + maxSurge: {{ $objectData.rollingUpdate.maxSurge }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_deploymentSpec.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_deploymentSpec.tpl new file mode 100644 index 0000000..bae1790 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_deploymentSpec.tpl @@ -0,0 +1,36 @@ +{{/* Deployment Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.deploymentSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + replicas: The number of replicas. + revisionHistoryLimit: The number of old ReplicaSets to retain to allow rollback. + strategy: The deployment strategy to use to replace existing pods with new ones. +*/}} +{{- define "tc.v1.common.lib.workload.deploymentSpec" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $strategy := $objectData.strategy | default "Recreate" -}} + {{- $replicas := 1 -}} + {{- if hasKey $objectData "replicas" -}} + {{- $replicas = $objectData.replicas -}} + {{- end -}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $replicas = 0 -}} + {{- end }} +replicas: {{ $replicas }} +revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} +strategy: + type: {{ $strategy }} + {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} + {{ if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "maxSurge")) }} + rollingUpdate: + {{- if hasKey $objectData.rollingUpdate "maxUnavailable" }} + maxUnavailable: {{ $objectData.rollingUpdate.maxUnavailable }} + {{- end -}} + {{- if hasKey $objectData.rollingUpdate "maxSurge" }} + maxSurge: {{ $objectData.rollingUpdate.maxSurge }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_jobSpec.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_jobSpec.tpl new file mode 100644 index 0000000..bca25f6 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_jobSpec.tpl @@ -0,0 +1,31 @@ +{{/* Job Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.jobSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + backoffLimit: The number of retries before marking this job failed. Defaults to 6. + completions: The desired number of successfully finished pods the job should be run with. Defaults to 1. + parallelism: The maximum desired number of pods the job should run at any given time. Defaults to 1. + activeDeadlineSeconds: Specifies the duration in seconds relative to the startTime that the job may be active before the system tries to terminate it; value must be positive integer. If set to nil, the job is never terminated due to timeout. + ttlSecondsAfterFinished: TTLSecondsAfterFinished limits the lifetime of a Job that has finished execution (either Complete or Failed). If this field is set, ttlSecondsAfterFinished after the Job finishes, it is eligible to be automatically deleted. When the Job is being deleted, its lifecycle guarantees (e.g. finalizers) will be honored. If this field is unset, the Job won't be automatically deleted. If this field is set to zero, the Job becomes eligible to be deleted immediately after it finishes. This field is alpha-level and is only honored by servers that enable the TTLAfterFinished feature. + completionMode: CompletionMode specifies how Pod completions are tracked. It can be `NonIndexed` (default) or `Indexed`. +*/}} +{{- define "tc.v1.common.lib.workload.jobSpec" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $parallelism := 1 -}} + {{- if hasKey $objectData "parallelism" -}} + {{- $parallelism = $objectData.parallelism -}} + {{- end -}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $parallelism = 0 -}} + {{- end }} +backoffLimit: {{ $objectData.backoffLimit | default 5 }} +completionMode: {{ $objectData.completionMode | default "NonIndexed" }} +completions: {{ $objectData.completions | default nil }} +parallelism: {{ $parallelism }} +ttlSecondsAfterFinished: {{ $objectData.ttlSecondsAfterFinished | default 120 }} + {{- with $objectData.activeDeadlineSeconds }} +activeDeadlineSeconds: {{ . }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_pod.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_pod.tpl new file mode 100644 index 0000000..a763267 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_pod.tpl @@ -0,0 +1,65 @@ +{{/* Pod Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.pod" (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.workload.pod" -}} + {{- $rootCtx := .rootCtx -}} + {{- $objectData := .objectData }} +serviceAccountName: {{ include "tc.v1.common.lib.pod.serviceAccountName" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +automountServiceAccountToken: {{ include "tc.v1.common.lib.pod.automountServiceAccountToken" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +runtimeClassName: {{ include "tc.v1.common.lib.pod.runtimeClassName" (dict "rootCtx" $rootCtx "objectData" $objectData) }} + {{- with (include "tc.v1.common.lib.pod.imagePullSecret" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +imagePullSecrets: + {{- . | nindent 2 }} + {{- end }} +hostNetwork: {{ include "tc.v1.common.lib.pod.hostNetwork" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +hostPID: {{ include "tc.v1.common.lib.pod.hostPID" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +shareProcessNamespace: {{ include "tc.v1.common.lib.pod.shareProcessNamespace" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +enableServiceLinks: {{ include "tc.v1.common.lib.pod.enableServiceLinks" (dict "rootCtx" $rootCtx "objectData" $objectData) }} +restartPolicy: {{ include "tc.v1.common.lib.pod.restartPolicy" (dict "rootCtx" $rootCtx "objectData" $objectData) }} + {{- with (include "tc.v1.common.lib.pod.schedulerName" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +schedulerName: {{ . }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.priorityClassName" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +priorityClassName: {{ . }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.nodeSelector" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +nodeSelector: + {{- . | nindent 2 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.topologySpreadConstraints" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +topologySpreadConstraints: + {{- . | nindent 2 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.hostAliases" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +hostAliases: + {{- . | nindent 2 }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.hostname" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +hostname: {{ . }} + {{- end -}} + {{- include "tc.v1.common.lib.pod.dns" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} + {{- with (include "tc.v1.common.lib.pod.terminationGracePeriodSeconds" (dict "rootCtx" $rootCtx "objectData" $objectData)) }} +terminationGracePeriodSeconds: {{ . }} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.tolerations" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +tolerations: + {{- . | nindent 2 }} + {{- end }} +securityContext: + {{- include "tc.v1.common.lib.pod.securityContext" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 }} + {{- if $objectData.podSpec.containers }} +containers: + {{- include "tc.v1.common.lib.pod.containerSpawner" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- end -}} + {{- if $objectData.podSpec.initContainers }} +initContainers: + {{- include "tc.v1.common.lib.pod.initContainerSpawner" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 2 -}} + {{- end -}} + {{- with (include "tc.v1.common.lib.pod.volumes" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }} +volumes: + {{- . | nindent 2 }} +{{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/_statefulsetSpec.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/_statefulsetSpec.tpl new file mode 100644 index 0000000..364376d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/_statefulsetSpec.tpl @@ -0,0 +1,37 @@ +{{/* StatefulSet Spec */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.statefulsetSpec" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + replicas: The number of replicas. + revisionHistoryLimit: The number of old ReplicaSets to retain to allow rollback. + strategy: The statefulset strategy to use to replace existing pods with new ones. +*/}} +{{- define "tc.v1.common.lib.workload.statefulsetSpec" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $strategy := $objectData.strategy | default "RollingUpdate" -}} + {{- $replicas := 1 -}} + {{- if hasKey $objectData "replicas" -}} + {{- $replicas = $objectData.replicas -}} + {{- end -}} + {{- if (include "tc.v1.common.lib.util.stopAll" $rootCtx) -}} + {{- $replicas = 0 -}} + {{- end }} +replicas: {{ $replicas }} +revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} +serviceName: {{ $objectData.name }} +updateStrategy: + type: {{ $strategy }} + {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} + {{- if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "partition")) }} + rollingUpdate: + {{- if hasKey $objectData.rollingUpdate "maxUnavailable" }} + maxUnavailable: {{ $objectData.rollingUpdate.maxUnavailable }} + {{- end -}} + {{- if hasKey $objectData.rollingUpdate "partition" }} + partition: {{ $objectData.rollingUpdate.partition }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_cronjobValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_cronjobValidation.tpl new file mode 100644 index 0000000..3d251bb --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_cronjobValidation.tpl @@ -0,0 +1,29 @@ +{{/* CronJob Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.cronjobValidation" (dict "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + completionMode: The completionMode of the object. + completions: The completions of the object. + parallelism: The parallelism of the object. +*/}} +{{- define "tc.v1.common.lib.workload.cronjobValidation" -}} + {{- $objectData := .objectData -}} + + {{- if $objectData.concurrencyPolicy -}} + {{- $concurrencyPolicy := $objectData.concurrencyPolicy -}} + + {{- $policies := (list "Allow" "Forbid" "Replace") -}} + {{- if not (mustHas $concurrencyPolicy $policies) -}} + {{- fail (printf "CronJob - Expected to be one of [%s], but got [%v]" (join ", " $policies) $concurrencyPolicy) -}} + {{- end -}} + + {{- end -}} + + {{- if not $objectData.schedule -}} + {{- fail "CronJob - Expected non-empty " -}} + {{- end -}} + + {{/* CronJob contains a job inside, so we validate job values too */}} + {{- include "tc.v1.common.lib.workload.jobValidation" (dict "objectData" $objectData) -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_daemonsetValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_daemonsetValidation.tpl new file mode 100644 index 0000000..58fa18e --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_daemonsetValidation.tpl @@ -0,0 +1,30 @@ +{{/* DaemonSet Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.daemonsetValidation" (dict "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + strategy: The strategy of the object. + rollingUpdate: The rollingUpdate of the object. +*/}} +{{- define "tc.v1.common.lib.workload.daemonsetValidation" -}} + {{- $objectData := .objectData -}} + + {{- if $objectData.strategy -}} + {{- $strategy := $objectData.strategy -}} + + {{- $strategies := (list "OnDelete" "RollingUpdate") -}} + {{- if not (mustHas $strategy $strategies) -}} + {{- fail (printf "DaemonSet - Expected to be one of [%s], but got [%v]" (join ", " $strategies) $strategy) -}} + {{- end -}} + + {{- end -}} + + {{- if $objectData.rollingUpdate -}} + {{- $rollUp := $objectData.rollingUpdate -}} + + {{- if and $rollUp (not (kindIs "map" $rollUp)) -}} + {{- fail (printf "DaemonSet - Expected to be a dictionary, but got [%v]" (kindOf $rollUp)) -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_deploymentValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_deploymentValidation.tpl new file mode 100644 index 0000000..40a6dcd --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_deploymentValidation.tpl @@ -0,0 +1,30 @@ +{{/* Deployment Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.deploymentValidation" (dict "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + strategy: The strategy of the object. + rollingUpdate: The rollingUpdate of the object. +*/}} +{{- define "tc.v1.common.lib.workload.deploymentValidation" -}} + {{- $objectData := .objectData -}} + + {{- if $objectData.strategy -}} + {{- $strategy := $objectData.strategy -}} + + {{- $strategies := (list "Recreate" "RollingUpdate") -}} + {{- if not (mustHas $strategy $strategies) -}} + {{- fail (printf "Deployment - Expected to be one of [%s], but got [%v]" (join ", " $strategies) $strategy) -}} + {{- end -}} + + {{- end -}} + + {{- if $objectData.rollingUpdate -}} + {{- $rollUp := $objectData.rollingUpdate -}} + + {{- if and $rollUp (not (kindIs "map" $rollUp)) -}} + {{- fail (printf "Deployment - Expected to be a dictionary, but got [%v]" (kindOf $rollUp)) -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_jobValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_jobValidation.tpl new file mode 100644 index 0000000..bd93ea3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_jobValidation.tpl @@ -0,0 +1,32 @@ +{{/* Job Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.jobValidation" (dict "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + completionMode: The completionMode of the object. + completions: The completions of the object. + parallelism: The parallelism of the object. +*/}} +{{- define "tc.v1.common.lib.workload.jobValidation" -}} + {{- $objectData := .objectData -}} + + {{- if $objectData.completionMode -}} + {{- $completionMode := $objectData.completionMode -}} + + {{- if not (mustHas $completionMode (list "Indexed" "NonIndexed")) -}} + {{- fail (printf "Job - Expected to be one of [Indexed, NonIndexed], but got [%v]" $completionMode) -}} + {{- end -}} + + {{- if eq $completionMode "Indexed" -}} + {{- if not $objectData.completions -}} + {{- fail "Job - Expected to be set when is set to [Indexed]" -}} + {{- end -}} + + {{- if not $objectData.parallelism -}} + {{- fail "Job - Expected to be set when is set to [Indexed]" -}} + {{- end -}} + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_statefusetValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_statefusetValidation.tpl new file mode 100644 index 0000000..6e75b08 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_statefusetValidation.tpl @@ -0,0 +1,30 @@ +{{/* StatefulSet Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.statefulsetValidation" (dict "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + strategy: The strategy of the object. + rollingUpdate: The rollingUpdate of the object. +*/}} +{{- define "tc.v1.common.lib.workload.statefulsetValidation" -}} + {{- $objectData := .objectData -}} + + {{- if $objectData.strategy -}} + {{- $strategy := $objectData.strategy -}} + + {{- $strategies := (list "OnDelete" "RollingUpdate") -}} + {{- if not (mustHas $strategy $strategies) -}} + {{- fail (printf "StatefulSet - Expected to be one of [%s], but got [%v]" (join ", " $strategies) $strategy) -}} + {{- end -}} + + {{- end -}} + + {{- if $objectData.rollingUpdate -}} + {{- $rollUp := $objectData.rollingUpdate -}} + + {{- if and $rollUp (not (kindIs "map" $rollUp)) -}} + {{- fail (printf "StatefulSet - Expected to be a dictionary, but got [%v]" (kindOf $rollUp)) -}} + {{- end -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/lib/workload/validation/_workloadValidation.tpl b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_workloadValidation.tpl new file mode 100644 index 0000000..4a8818f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/lib/workload/validation/_workloadValidation.tpl @@ -0,0 +1,43 @@ +{{/* Workload Basic Validation */}} +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.primaryValidation" $ -}} +*/}} +{{- define "tc.v1.common.lib.workload.primaryValidation" -}} + + {{/* Initialize values */}} + {{- $hasPrimary := false -}} + {{- $hasEnabled := false -}} + + {{/* Go over workload */}} + {{- range $name, $workload := .Values.workload -}} + + {{/* If workload is enabled */}} + {{- if $workload.enabled -}} + + {{- $types := (list "Deployment" "StatefulSet" "DaemonSet" "Job" "CronJob") -}} + {{- if not (mustHas $workload.type $types) -}} + {{- fail (printf "Workload - Expected to be one of [%s], but got [%s]" (join ", " $types) $workload.type) -}} + {{- end -}} + + {{- $hasEnabled = true -}} + + {{/* And workload is primary */}} + {{- if $workload.primary -}} + {{/* Fail if there is already a primary workload */}} + {{- if $hasPrimary -}} + {{- fail "Workload - Only one workload can be primary" -}} + {{- end -}} + + {{- $hasPrimary = true -}} + + {{- end -}} + {{- end -}} + + {{- end -}} + + {{/* Require at one primary workload, if any enabled */}} + {{- if and $hasEnabled (not $hasPrimary) -}} + {{- fail "Workload - One enabled workload must be primary" -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/loader/_all.tpl b/helm-charts/dashy/charts/common/templates/loader/_all.tpl new file mode 100644 index 0000000..2983499 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/loader/_all.tpl @@ -0,0 +1,8 @@ +{{/* Main entrypoint for the library */}} +{{- define "tc.v1.common.loader.all" -}} + + {{- include "tc.v1.common.loader.init" . -}} + + {{- include "tc.v1.common.loader.apply" . -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/loader/_apply.tpl b/helm-charts/dashy/charts/common/templates/loader/_apply.tpl new file mode 100644 index 0000000..3094272 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/loader/_apply.tpl @@ -0,0 +1,70 @@ +{{/* Loads all spawners */}} +{{- define "tc.v1.common.loader.apply" -}} + + {{/* Inject custom tpl files, as defined in values.yaml */}} + {{- include "tc.v1.common.spawner.extraTpl" . | nindent 0 -}} + + {{/* Ensure automatic permissions containers are injected */}} + {{- include "tc.v1.common.lib.util.autoperms.job" $ -}} + + {{/* Make sure there are not any YAML errors */}} + {{- include "tc.v1.common.values.validate" .Values -}} + + {{/* Render ConfigMap(s) */}} + {{- include "tc.v1.common.spawner.configmap" . | nindent 0 -}} + + {{/* Render Certificate(s) */}} + {{- include "tc.v1.common.spawner.scaleCertificate" . | nindent 0 -}} + + {{/* Render Secret(s) */}} + {{- include "tc.v1.common.spawner.secret" . | nindent 0 -}} + + {{/* Render Image Pull Secrets(s) */}} + {{- include "tc.v1.common.spawner.imagePullSecret" . | nindent 0 -}} + + {{/* Render Service Accounts(s) */}} + {{- include "tc.v1.common.spawner.serviceAccount" . | nindent 0 -}} + + {{/* Render RBAC(s) */}} + {{- include "tc.v1.common.spawner.rbac" . | nindent 0 -}} + + {{/* Render External Interface(s) */}} + {{- include "tc.v1.common.spawner.externalInterface" . | nindent 0 -}} + + {{/* Render Workload(s) */}} + {{- include "tc.v1.common.spawner.workload" . | nindent 0 -}} + + {{/* Render Services(s) */}} + {{- include "tc.v1.common.spawner.service" . | nindent 0 -}} + + {{/* Render PVC(s) */}} + {{- include "tc.v1.common.spawner.pvc" . | nindent 0 -}} + + {{/* Render ingress(s) */}} + {{- include "tc.v1.common.spawner.ingress" . | nindent 0 -}} + + {{/* Render Gateway API Route(s) */}} + {{- include "tc.v1.common.spawner.routes" . | nindent 0 -}} + + {{/* Render Horizontal Pod Autoscalers(s) */}} + {{- include "tc.v1.common.spawner.hpa" . | nindent 0 -}} + + {{/* Render Networkpolicy(s) */}} + {{- include "tc.v1.common.spawner.networkpolicy" . | nindent 0 -}} + + {{/* Render podDisruptionBudget(s) */}} + {{- include "tc.v1.common.spawner.podDisruptionBudget" . | nindent 0 -}} + + {{/* Render webhook(s) */}} + {{- include "tc.v1.common.spawner.webhook" . | nindent 0 -}} + + {{/* Render Prometheus Metrics(s) */}} + {{- include "tc.v1.common.spawner.metrics" . | nindent 0 -}} + + {{/* Render Cert-Manager Certificates(s) */}} + {{- include "tc.v1.common.spawner.certificate" . | nindent 0 -}} + + {{/* Render/Set portal configmap, .Values.iXPortals and APPURL */}} + {{- include "tc.v1.common.spawner.portal" . | nindent 0 -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/loader/_init.tpl b/helm-charts/dashy/charts/common/templates/loader/_init.tpl new file mode 100644 index 0000000..aff423a --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/loader/_init.tpl @@ -0,0 +1,55 @@ +{{/* Initialiaze values of the chart */}} +{{- define "tc.v1.common.loader.init" -}} + + {{/* Merge chart values and the common chart defaults */}} + {{- include "tc.v1.common.values.init" . -}} + + {{/* Parse lists and append to values */}} + {{- include "tc.v1.common.loader.lists" . -}} + + {{/* Ensure TrueCharts chart context information is available */}} + {{- include "tc.v1.common.lib.util.chartcontext" . -}} + + {{/* Autogenerate postgresql passwords if needed */}} + {{- include "tc.v1.common.spawner.cnpg" . }} + + {{/* Autogenerate redis passwords if needed */}} + {{- include "tc.v1.common.dependencies.redis.injector" . }} + + {{/* Autogenerate mariadb passwords if needed */}} + {{- include "tc.v1.common.dependencies.mariadb.injector" . }} + + {{/* Autogenerate mongodb passwords if needed */}} + {{- include "tc.v1.common.dependencies.mongodb.injector" . }} + + {{/* Autogenerate clickhouse passwords if needed */}} + {{- include "tc.v1.common.dependencies.clickhouse.injector" . }} + + {{/* Autogenerate solr passwords if needed */}} + {{- include "tc.v1.common.dependencies.solr.injector" . }} + + {{/* Register Operator if needed */}} + {{- include "tc.v1.common.lib.util.operator.register" . }} + + {{/* Verify if required operators are present */}} + {{- include "tc.v1.common.lib.util.operator.verifyAll" . }} + + {{/* Enable code-server add-on if required */}} + {{- if .Values.addons.codeserver.enabled }} + {{- include "tc.v1.common.addon.codeserver" . }} + {{- end -}} + + {{/* Enable VPN add-on if required */}} + {{- if ne "disabled" .Values.addons.vpn.type -}} + {{- include "tc.v1.common.addon.vpn" . }} + {{- end -}} + + {{/* Enable netshoot add-on if required */}} + {{- if .Values.addons.netshoot.enabled }} + {{- include "tc.v1.common.addon.netshoot" . }} + {{- end -}} + + {{/* Append database wait containers to pods */}} + {{- include "tc.v1.common.lib.deps.wait" $ }} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/loader/_lists.tpl b/helm-charts/dashy/charts/common/templates/loader/_lists.tpl new file mode 100644 index 0000000..fc0de77 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/loader/_lists.tpl @@ -0,0 +1,11 @@ +{{- define "tc.v1.common.loader.lists" -}} + + {{- include "tc.v1.common.values.persistenceList" . -}} + + {{- include "tc.v1.common.values.deviceList" . -}} + + {{- include "tc.v1.common.values.serviceList" . -}} + + {{- include "tc.v1.common.values.ingressList" . -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_certificate.tpl b/helm-charts/dashy/charts/common/templates/spawner/_certificate.tpl new file mode 100644 index 0000000..cc20778 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_certificate.tpl @@ -0,0 +1,27 @@ +{{/* Renders the certificate objects required by the chart */}} +{{- define "tc.v1.common.spawner.certificate" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Generate named certs as required */}} + {{- range $name, $cert := .Values.cert -}} + {{- if $cert.enabled -}} + {{- $certValues := $cert -}} + {{- $certName := $fullname -}} + + {{/* set defaults */}} + {{- if and (not $certValues.nameOverride) (ne $name (include "tc.v1.common.lib.util.cert.primary" $)) -}} + {{- $_ := set $certValues "nameOverride" $name -}} + {{- end -}} + + {{- if $certValues.nameOverride -}} + {{- $certName = printf "%v-%v" $certName $certValues.nameOverride -}} + {{- end -}} + + {{- if $certValues.secretTemplate -}} + {{- $certName = printf "%v-%v" "clusterissuer-templated" $name -}} + {{- end -}} + + {{- include "tc.v1.common.class.certificate" (dict "root" $ "name" $certName "certificateIssuer" $cert.certificateIssuer "hosts" $cert.hosts "secretTemplate" $cert.secretTemplate ) -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_cnpg.tpl b/helm-charts/dashy/charts/common/templates/spawner/_cnpg.tpl new file mode 100644 index 0000000..440d761 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_cnpg.tpl @@ -0,0 +1,102 @@ +{{/* Renders the cnpg objects required by the chart */}} +{{- define "tc.v1.common.spawner.cnpg" -}} + {{/* Generate named cnpges as required */}} + {{- range $name, $cnpg := $.Values.cnpg }} + + {{- $enabled := false -}} + {{- if hasKey $cnpg "enabled" -}} + {{- if not (kindIs "invalid" $cnpg.enabled) -}} + {{- $enabled = $cnpg.enabled -}} + {{- else -}} + {{- fail (printf "cnpg - Expected the defined key [enabled] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $ -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + + {{- $cnpgValues := $cnpg }} + {{- $cnpgName := include "tc.v1.common.lib.chart.names.fullname" $ }} + {{- $_ := set $cnpgValues "shortName" $name }} + + {{/* set defaults */}} + {{- $_ := set $cnpgValues "nameOverride" ( printf "cnpg-%v" $name ) }} + + {{- $cnpgName := printf "%v-%v" $cnpgName $cnpgValues.nameOverride }} + + {{- $_ := set $cnpgValues "name" $cnpgName }} + + {{- if $enabled -}} + {{- $_ := set $ "ObjectValues" (dict "cnpg" $cnpgValues) }} + {{- include "tc.v1.common.class.cnpg.cluster" $ }} + + {{- $_ := set $cnpgValues.pooler "type" "rw" }} + {{- if not $cnpgValues.acceptRO }} + {{- include "tc.v1.common.class.cnpg.pooler" $ }} + {{- else }} + {{- include "tc.v1.common.class.cnpg.pooler" $ }} + {{- $_ := set $cnpgValues.pooler "type" "ro" }} + {{- include "tc.v1.common.class.cnpg.pooler" $ }} + {{- end }} + + {{- end }} + + + {{- $dbPass := "" }} + {{- $dbprevious := lookup "v1" "Secret" $.Release.Namespace ( printf "%s-user" $cnpgValues.name ) }} + {{- if or $enabled $dbprevious -}} + {{/* Inject the required secrets */}} + + {{- if $dbprevious }} + {{- $dbPass = ( index $dbprevious.data "password" ) | b64dec }} + {{- else }} + {{- $dbPass = $cnpgValues.password | default ( randAlphaNum 62 ) }} + {{- end }} + + {{- $std := ( ( printf "postgresql://%v:%v@%v-rw:5432/%v" $cnpgValues.user $dbPass $cnpgValues.name $cnpgValues.database ) | quote ) }} + {{- $nossl := ( ( printf "postgresql://%v:%v@%v-rw:5432/%v?sslmode=disable" $cnpgValues.user $dbPass $cnpgValues.name $cnpgValues.database ) | quote ) }} + {{- $porthost := ( ( printf "%s-rw:5432" $cnpgValues.name ) | quote ) }} + {{- $host := ( ( printf "%s-rw" $cnpgValues.name ) | quote ) }} + {{- $jdbc := ( ( printf "jdbc:postgresql://%v-rw:5432/%v" $cnpgValues.name $cnpgValues.database ) | quote ) }} + + {{- $userSecret := include "tc.v1.common.lib.cnpg.secret.user" (dict "values" $cnpgValues "dbPass" $dbPass ) | fromYaml }} + {{- if $userSecret }} + {{- $_ := set $.Values.secret ( printf "cnpg-%s-user" $cnpgValues.shortName ) $userSecret }} + {{- end }} + + {{- $urlSecret := include "tc.v1.common.lib.cnpg.secret.urls" (dict "std" $std "nossl" $nossl "porthost" $porthost "host" $host "jdbc" $jdbc) | fromYaml }} + {{- if $urlSecret }} + {{- $_ := set $.Values.secret ( printf "cnpg-%s-urls" $cnpgValues.shortName ) $urlSecret }} + {{- end }} + + {{- $_ := set $cnpgValues.creds "password" ( $dbPass | quote ) }} + {{- $_ := set $cnpgValues.creds "std" $std }} + {{- $_ := set $cnpgValues.creds "nossl" $nossl }} + {{- $_ := set $cnpgValues.creds "porthost" $porthost }} + {{- $_ := set $cnpgValues.creds "host" $host }} + {{- $_ := set $cnpgValues.creds "jdbc" $jdbc }} + + {{- if $cnpgValues.monitoring }} + {{- if $cnpgValues.monitoring.enablePodMonitor }} + {{- $poolermetrics := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" ( printf "%s-rw" $cnpgValues.name) ) | fromYaml }} + + {{- $_ := set $.Values.metrics ( printf "cnpg-%s-rw" $cnpgValues.shortName ) $poolermetrics }} + {{- if $cnpgValues.acceptRO }} + {{- $poolermetricsRO := include "tc.v1.common.lib.cnpg.metrics.pooler" (dict "poolerName" ( printf "%s-ro" $cnpgValues.name) ) | fromYaml }} + {{- $_ := set $.Values.metrics ( printf "cnpg-%s-ro" $cnpgValues.shortName ) $poolermetricsRO }} + {{- end }} + {{- end }} + {{- end }} + + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_configmap.tpl b/helm-charts/dashy/charts/common/templates/spawner/_configmap.tpl new file mode 100644 index 0000000..8ed2eef --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_configmap.tpl @@ -0,0 +1,60 @@ +{{/* Configmap Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.configmap" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.configmap" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $configmap := .Values.configmap -}} + + {{- $enabled := false -}} + {{- if hasKey $configmap "enabled" -}} + {{- if not (kindIs "invalid" $configmap.enabled) -}} + {{- $enabled = $configmap.enabled -}} + {{- else -}} + {{- fail (printf "ConfigMap - Expected the defined key [enabled] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $ -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + {{- if $enabled -}} + + {{/* Create a copy of the configmap */}} + {{- $objectData := (mustDeepCopy $configmap) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{- if hasKey $objectData "expandObjectName" -}} + {{- if not $objectData.expandObjectName -}} + {{- $objectName = $name -}} + {{- end -}} + {{- end -}} + + {{/* Perform validations */}} {{/* Configmaps have a max name length of 253 */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}} + {{- include "tc.v1.common.lib.configmap.validation" (dict "objectData" $objectData) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "ConfigMap") -}} + + {{/* Set the name of the configmap */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.configmap" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_externalInterface.tpl b/helm-charts/dashy/charts/common/templates/spawner/_externalInterface.tpl new file mode 100644 index 0000000..6fffa24 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_externalInterface.tpl @@ -0,0 +1,32 @@ +{{/* External Interface Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.externalInterface" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.externalInterface" -}} + + {{- range $iface := .Values.scaleExternalInterface -}} + {{- include "tc.v1.common.lib.externalInterface.validation" (dict "objectData" $iface) -}} + {{- end -}} + + {{/* Now we have validated interfaces, render the objects */}} + + {{- range $index, $interface := .Values.ixExternalInterfacesConfiguration -}} + + {{- $objectData := dict -}} + {{/* Create a copy of the interface and put it in objectData.config */}} + {{- $_ := set $objectData "config" (mustDeepCopy $interface) -}} + + {{- $objectName := (printf "ix-%s-%v" $.Release.Name $index) -}} + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + + {{/* Set the name of the object to objectData.name */}} + {{- $_ := set $objectData "name" $objectName -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.networkAttachmentDefinition" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_extraTpl.tpl b/helm-charts/dashy/charts/common/templates/spawner/_extraTpl.tpl new file mode 100644 index 0000000..30b5460 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_extraTpl.tpl @@ -0,0 +1,13 @@ +{{- define "tc.v1.common.spawner.extraTpl" -}} + {{- range $item := .Values.extraTpl }} + {{- if not $item -}} + {{- fail "Extra tpl - Expected non-empty item" -}} + {{- end }} +--- + {{- if kindIs "string" $item }} + {{- tpl $item $ | nindent 0 }} + {{- else }} + {{- tpl ($item | toYaml) $ | nindent 0 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_horizontalPodAutoscaler.tpl b/helm-charts/dashy/charts/common/templates/spawner/_horizontalPodAutoscaler.tpl new file mode 100644 index 0000000..1a14dbc --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_horizontalPodAutoscaler.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the configMap objects required by the chart. +*/}} +{{- define "tc.v1.common.spawner.hpa" -}} + {{/* Generate named configMaps as required */}} + {{- range $name, $hpa := .Values.horizontalPodAutoscaler -}} + {{- if $hpa.enabled -}} + {{- $hpaValues := $hpa -}} + + {{/* set the default nameOverride to the hpa name */}} + {{- if not $hpaValues.nameOverride -}} + {{- $_ := set $hpaValues "nameOverride" $name -}} + {{- end -}} + + {{- $_ := set $ "ObjectValues" (dict "hpa" $hpaValues) -}} + {{- include "tc.v1.common.class.hpa" $ -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_imagePullSecret.tpl b/helm-charts/dashy/charts/common/templates/spawner/_imagePullSecret.tpl new file mode 100644 index 0000000..30c4cc2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_imagePullSecret.tpl @@ -0,0 +1,41 @@ +{{/* Image Pull Secrets Spawner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.imagePullSecret" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.imagePullSecret" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $imgPullSecret := .Values.imagePullSecret -}} + + {{- if $imgPullSecret.enabled -}} + + {{/* Create a copy of the configmap */}} + {{- $objectData := (mustDeepCopy $imgPullSecret) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + + {{/* Perform validations */}} {{/* Secrets have a max name length of 253 */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}} + {{- include "tc.v1.common.lib.imagePullSecret.validation" (dict "objectData" $objectData) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Image Pull Secret") -}} + {{- $data := include "tc.v1.common.lib.imagePullSecret.createData" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{/* Update the data */}} + {{- $_ := set $objectData "data" $data -}} + + {{/* Set the type to Image Pull Secret */}} + {{- $_ := set $objectData "type" "imagePullSecret" -}} + + {{/* Set the name of the image pull secret */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_ingress.tpl b/helm-charts/dashy/charts/common/templates/spawner/_ingress.tpl new file mode 100644 index 0000000..2daaa67 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_ingress.tpl @@ -0,0 +1,62 @@ +{{/* Renders the Ingress objects required by the chart */}} +{{- define "tc.v1.common.spawner.ingress" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Generate named ingresses as required */}} + {{- 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 -}} + {{- end -}} + + {{- if $ingressValues.nameOverride -}} + {{- $ingressName = printf "%v-%v" $ingressName $ingressValues.nameOverride -}} + {{- end -}} + + {{- $_ := set $ingressValues "name" $ingressName -}} + + {{- $_ := 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 ) -}} + + {{/* 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) -}} + + {{- end -}} + {{- end -}} + {{- end -}} + {{- else if $ingress.required -}} + {{- fail (printf "Ingress - is set to be [required] and cannot be disabled" $name) -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_metrics.tpl b/helm-charts/dashy/charts/common/templates/spawner/_metrics.tpl new file mode 100644 index 0000000..7d72777 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_metrics.tpl @@ -0,0 +1,28 @@ +{{/* Renders the Ingress objects required by the chart */}} +{{- define "tc.v1.common.spawner.metrics" -}} + {{/* Generate named metricses as required */}} + {{- range $name, $metrics := .Values.metrics -}} + {{- if $metrics.enabled -}} + {{- $metricsValues := $metrics -}} + + {{/* set defaults */}} + {{- if and (not $metricsValues.nameOverride) (ne $name (include "tc.v1.common.lib.util.metrics.primary" $)) -}} + {{- $_ := set $metricsValues "nameOverride" $name -}} + {{- end -}} + + {{- $_ := set $ "ObjectValues" (dict "metrics" $metricsValues) -}} + {{- if eq $metricsValues.type "podmonitor" -}} + {{- include "tc.v1.common.class.podmonitor" $ -}} + {{- else if eq $metricsValues.type "servicemonitor" -}} + {{- include "tc.v1.common.class.servicemonitor" $ -}} + {{- else -}} + {{/* TODO: Add Fail case */}} + {{- end -}} + + {{- if $metricsValues.PrometheusRule -}} + {{- include "tc.v1.common.class.prometheusrule" $ -}} + {{- end -}} + + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_networkPolicy.tpl b/helm-charts/dashy/charts/common/templates/spawner/_networkPolicy.tpl new file mode 100644 index 0000000..46e4ea2 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_networkPolicy.tpl @@ -0,0 +1,19 @@ +{{/* +Renders the networkPolicy objects required by the chart. +*/}} +{{- define "tc.v1.common.spawner.networkpolicy" -}} + {{/* Generate named networkpolicy as required */}} + {{- range $name, $networkPolicy := .Values.networkPolicy -}} + {{- if $networkPolicy.enabled -}} + {{- $networkPolicyValues := $networkPolicy -}} + + {{/* set the default nameOverride to the networkpolicy name */}} + {{- if not $networkPolicyValues.nameOverride -}} + {{- $_ := set $networkPolicyValues "nameOverride" $name -}} + {{- end -}} + + {{- $_ := set $ "ObjectValues" (dict "networkPolicy" $networkPolicyValues) -}} + {{- include "tc.v1.common.class.networkpolicy" $ -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_podDisruptionBudget.tpl b/helm-charts/dashy/charts/common/templates/spawner/_podDisruptionBudget.tpl new file mode 100644 index 0000000..3aa8340 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_podDisruptionBudget.tpl @@ -0,0 +1,59 @@ +{{/* poddisruptionbudget Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.podDisruptionBudget" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.podDisruptionBudget" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $pdb := .Values.podDisruptionBudget -}} + {{- $enabled := false -}} + {{- if hasKey $pdb "enabled" -}} + {{- if not (kindIs "invalid" $pdb.enabled) -}} + {{- $enabled = $pdb.enabled -}} + {{- else -}} + {{- fail (printf "Pod Disruption Budget - Expected the defined key [enabled] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $ -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + {{- if $enabled -}} + + {{/* Create a copy of the poddisruptionbudget */}} + {{- $objectData := (mustDeepCopy $pdb) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{- if hasKey $objectData "expandObjectName" -}} + {{- if not $objectData.expandObjectName -}} + {{- $objectName = $name -}} + {{- end -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Pod Disruption Budget") -}} + + {{/* Set the name of the poddisruptionbudget */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{- include "tc.v1.common.lib.podDisruptionBudget.validation" (dict "objectData" $objectData "rootCtx" $) -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.podDisruptionBudget" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_portal.tpl b/helm-charts/dashy/charts/common/templates/spawner/_portal.tpl new file mode 100644 index 0000000..e7e58e3 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_portal.tpl @@ -0,0 +1,176 @@ +{{/* Portal Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.portal" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.portal" -}} + {{- range $name, $portal := .Values.portal -}} + {{- if $portal.enabled -}} + + {{/* Create a copy of the portal */}} + {{- $objectData := (mustDeepCopy $portal) -}} + {{- $override := $objectData.override -}} + {{- $targetSelector := $objectData.targetSelector -}} + + {{/* Create defaults */}} + {{- $protocol := "http" -}} + {{- $host := "$node_ip" -}} + {{- $port := "443" -}} + {{- $path := $objectData.path | default "/" -}} + {{- $url := "" -}} + + + {{/* Get service, default to primary */}} + {{- $serviceData := dict "targetSelector" $targetSelector.service -}} + {{- $selectedService := fromYaml ( include "tc.v1.common.lib.helpers.getSelectedServiceValues" (dict "rootCtx" $ "objectData" $serviceData)) }} + + {{/* read loadbalancer IPs for metallb */}} + {{- if eq $selectedService.type "LoadBalancer" -}} + {{- with $selectedService.loadBalancerIP -}} + {{- $host = toString . -}} + {{- end -}} + + {{/* set temporary storage for port name and port */}} + {{- $targetPort := "" -}} + {{- $selectedPort := "" -}} + + {{/* Fetch port values */}} + {{- if $targetSelector.port -}} + {{- $targetPort = $targetSelector.port -}} + {{- else -}} + {{- $targetPort = include "tc.v1.common.lib.util.service.ports.primary" (dict "svcName" $selectedService.shortName "svcValues" $selectedService ) -}} + {{- end -}} + + + {{- $selectedPort = get $selectedService.ports $targetPort -}} + + {{/* store port number */}} + {{- $port = $selectedPort.port -}} + {{- end -}} + + + {{/* set temporary storage for ingress name and port */}} + {{- $targetIngress := "" -}} + {{- $selectedIngress := "" -}} + + {{/* Fetch ingress values */}} + {{- if $targetSelector.ingress -}} + {{- $targetIngress = $targetSelector.ingress -}} + {{- else -}} + {{- $targetIngress = ( include "tc.v1.common.lib.util.ingress.primary" $ ) -}} + {{- end -}} + + {{- $selectedIngress = get $.Values.ingress $targetIngress -}} + + {{/* store host from ingress number */}} + {{- if $selectedIngress -}} + {{- if $selectedIngress.enabled -}} + {{- with (index $selectedIngress.hosts 0) }} + {{- $host = .host -}} + {{- end }} + + {{/* Get the port for the ingress entrypoint */}} + + + {{- $traefikNamespace := "tc-system" -}} + {{- if $.Values.operator.traefik -}} + {{- if $.Values.operator.traefik.namespace -}} + {{- $traefikNamespace := $.Values.operator.traefik.namespace -}} + {{- end -}} + {{- end -}} + {{- if $selectedIngress.ingressClassName }} + {{- if $.Values.global.ixChartContext -}} + {{- $traefikNamespace = (printf "ix-%s" $selectedIngress.ingressClassName) -}} + {{- else -}} + {{- $traefikNamespace = $selectedIngress.ingressClassName -}} + {{- end -}} + {{- end -}} + + {{- $traefikportalhook := lookup "v1" "ConfigMap" $traefikNamespace "portalhook" }} + + {{- $entrypoint := "websecure" }} + {{- $protocol = "https" -}} + {{- if $selectedIngress.entrypoint }} + {{- $entrypoint = $selectedIngress.entrypoint }} + {{- end }} + + {{- if $traefikportalhook }} + {{- if ( index $traefikportalhook.data $entrypoint ) }} + {{- $port = ( index $traefikportalhook.data $entrypoint ) }} + {{- end }} + {{- end }} + + {{- end }} + {{- end }} + + + {{- $port = ( toString $port ) -}} + + {{/* Apply overrides */}} + {{- if $override.protocol -}} + {{- $protocol = $override.protocol -}} + {{- end -}} + + {{- if $override.host -}} + {{- $host = $override.host -}} + {{- end -}} + + {{- if $override.port -}} + {{- $port = $override.port -}} + {{- end -}} + + {{/* sanitise */}} + {{- if eq $port "443" -}} + {{- $protocol = "https" -}} + {{- end -}} + + {{- if eq $port "80" -}} + {{- $protocol = "http" -}} + {{- end -}} + + {{/* TODO: Reenable when iX fixes bugs crashing GUI on empty port */}} + {{/* + {{- if or ( and ( eq $protocol "https" ) ( eq $port "443" ) ) ( and ( eq $protocol "http" ) ( eq $port "80" ) ) -}} + {{- $port = "" -}} + {{- end -}} + */}} + + {{- $port = toString $port -}} + + {{/* Construct URL*/}} + {{- if $port -}} + {{- $url = printf "%s://%s:%s%s" $protocol $host $port $path -}} + {{- else -}} + {{- $url = printf "%s://%s%s" $protocol $host $path -}} + {{- end -}} + + {{/* create configmap entry*/}} + {{- $portalData := dict "protocol" $protocol "host" $host "port" $port "path" $path "url" $url -}} + + {{/* construct configmap */}} + {{- $objectName := ( printf "tcportal-%s" $name ) -}} + {{- $configMap := dict "enabled" true "name" $objectName "shortName" $objectName "data" $portalData -}} + + {{/* Perform validations */}} {{/* Configmaps have a max name length of 253 */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}} + {{- include "tc.v1.common.lib.configmap.validation" (dict "objectData" $configMap) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $configMap "caller" "ConfigMap") -}} + + {{- if $.Values.global.ixChartContext -}} + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.configmap" (dict "rootCtx" $ "objectData" $configMap) -}} + + {{/* iXportals */}} + {{- $useNodeIP := false -}} + {{- if eq $host "$node_ip" -}} + {{- $useNodeIP = true -}} + {{- end -}} + + {{- $iXPortalData := dict "portalName" $name "useNodeIP" $useNodeIP "protocol" $protocol "host" $host "port" $port "path" $path "url" $url -}} + {{- $iXPortals := append $.Values.iXPortals $iXPortalData -}} + {{- $_ := set $.Values "iXPortals" $iXPortals -}} + + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_pvc.tpl b/helm-charts/dashy/charts/common/templates/spawner/_pvc.tpl new file mode 100644 index 0000000..14b1197 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_pvc.tpl @@ -0,0 +1,41 @@ +{{/* PVC Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.pvc" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.pvc" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $persistence := .Values.persistence -}} + + {{- if $persistence.enabled -}} + + {{/* Create a copy of the persistence */}} + {{- $objectData := (mustDeepCopy $persistence) -}} + + {{- $_ := set $objectData "type" ($objectData.type | default $.Values.fallbackDefaults.persistenceType) -}} + + {{/* Perform general validations */}} + {{- include "tc.v1.common.lib.persistence.validation" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Persistence") -}} + + {{/* Only spawn PVC if its enabled and type of "pvc" */}} + {{- if and (eq "pvc" $objectData.type) (not $objectData.existingClaim) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + + {{/* Set the name of the secret */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.pvc" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_rbac.tpl b/helm-charts/dashy/charts/common/templates/spawner/_rbac.tpl new file mode 100644 index 0000000..255f11c --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_rbac.tpl @@ -0,0 +1,44 @@ +{{/* RBAC Spawner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.rbac" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.rbac" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Primary validation for enabled rbacs. */}} + {{- include "tc.v1.common.lib.rbac.primaryValidation" $ -}} + + {{- range $name, $rbac := .Values.rbac -}} + + {{- if $rbac.enabled -}} + + {{/* Create a copy of the configmap */}} + {{- $objectData := (mustDeepCopy $rbac) -}} + + {{- $objectName := $fullname -}} + {{- if not $objectData.primary -}} + {{- $objectName = (printf "%s-%s" $fullname $name) -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "RBAC") -}} + + {{/* Set the name of the rbac */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* If clusteWide key does not exist, assume false */}} + {{- if not (hasKey $objectData "clusterWide") -}} + {{- $_ := set $objectData "clusterWide" false -}} + {{- end -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.rbac" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_route.tpl b/helm-charts/dashy/charts/common/templates/spawner/_route.tpl new file mode 100644 index 0000000..5ecf210 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_route.tpl @@ -0,0 +1,18 @@ +{{/* Renders the Route objects required by the chart */}} +{{- define "tc.v1.common.spawner.routes" -}} + {{- /* Generate named routes as required */ -}} + {{- range $name, $route := .Values.route }} + {{- if $route.enabled -}} + {{- $routeValues := $route -}} + + {{/* set defaults */}} + {{- if and (not $routeValues.nameOverride) (ne $name (include "tc.v1.common.lib.util.route.primary" $)) -}} + {{- $_ := set $routeValues "nameOverride" $name -}} + {{- end -}} + + {{- $_ := set $ "ObjectValues" (dict "route" $routeValues) -}} + {{- include "tc.v1.common.class.route" $ | nindent 0 -}} + {{- $_ := unset $.ObjectValues "route" -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_scaleCertificate.tpl b/helm-charts/dashy/charts/common/templates/spawner/_scaleCertificate.tpl new file mode 100644 index 0000000..6285959 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_scaleCertificate.tpl @@ -0,0 +1,40 @@ +{{/* Certificate Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.scaleCertificate" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.scaleCertificate" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $certificate := .Values.scaleCertificate -}} + + {{- if $certificate.enabled -}} + + {{/* Create a copy of the certificate */}} + {{- $objectData := (mustDeepCopy $certificate) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{/* Perform validations */}} {{/* Secrets have a max name length of 253 */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}} + {{- 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) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_secret.tpl b/helm-charts/dashy/charts/common/templates/spawner/_secret.tpl new file mode 100644 index 0000000..4d2f401 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_secret.tpl @@ -0,0 +1,59 @@ +{{/* Secret Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.secret" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.secret" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $secret := .Values.secret -}} + + {{- $enabled := false -}} + {{- if hasKey $secret "enabled" -}} + {{- if not (kindIs "invalid" $secret.enabled) -}} + {{- $enabled = $secret.enabled -}} + {{- else -}} + {{- fail (printf "Secret - Expected the defined key [enabled] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $ -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + {{- if $enabled -}} + + {{/* Create a copy of the secret */}} + {{- $objectData := (mustDeepCopy $secret) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{- if hasKey $objectData "expandObjectName" -}} + {{- if not $objectData.expandObjectName -}} + {{- $objectName = $name -}} + {{- end -}} + {{- end -}} + + {{/* Perform validations */}} {{/* Secrets have a max name length of 253 */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName "length" 253) -}} + {{- include "tc.v1.common.lib.secret.validation" (dict "objectData" $objectData) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Secret") -}} + + {{/* Set the name of the secret */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_service.tpl b/helm-charts/dashy/charts/common/templates/spawner/_service.tpl new file mode 100644 index 0000000..34ed847 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_service.tpl @@ -0,0 +1,58 @@ +{{/* Service Spawner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.service" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.service" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Primary validation for enabled service. */}} + {{- include "tc.v1.common.lib.service.primaryValidation" $ -}} + + {{- range $name, $service := .Values.service -}} + + {{- if $service.enabled -}} + + {{/* Create a copy of the configmap */}} + {{- $objectData := (mustDeepCopy $service) -}} + + {{/* Init object name */}} + {{- $objectName := $name -}} + + {{/* Default expandName to true */}} + {{- $expandName := true -}} + {{- if (hasKey $objectData "expandObjectName") -}} + {{- if not (kindIs "invalid" $objectData.expandObjectName) -}} + {{- $expandName = $objectData.expandName -}} + {{- else -}} + {{- fail (printf "Service - Expected the defined key [expandObjectName] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + {{- if $expandName -}} + {{/* Expand the name of the service if expandName resolves to true */}} + {{- $objectName = $fullname -}} + {{- end -}} + + {{- if and $expandName (not $objectData.primary) -}} + {{/* If the service is not primary append its name to fullname */}} + {{- $objectName = (printf "%s-%s" $fullname $name) -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- 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 $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.service" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_serviceAccount.tpl b/helm-charts/dashy/charts/common/templates/spawner/_serviceAccount.tpl new file mode 100644 index 0000000..c15aff4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_serviceAccount.tpl @@ -0,0 +1,39 @@ +{{/* Service Account Spawner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.serviceAccount" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.serviceAccount" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Primary validation for enabled service accounts. */}} + {{- include "tc.v1.common.lib.serviceAccount.primaryValidation" $ -}} + + {{- range $name, $serviceAccount := .Values.serviceAccount -}} + + {{- if $serviceAccount.enabled -}} + + {{/* Create a copy of the configmap */}} + {{- $objectData := (mustDeepCopy $serviceAccount) -}} + + {{- $objectName := $fullname -}} + {{- if not $objectData.primary -}} + {{- $objectName = (printf "%s-%s" $fullname $name) -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Service Account") -}} + + {{/* Set the name of the service account */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Call class to create the object */}} + {{- include "tc.v1.common.class.serviceAccount" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_webhook.tpl b/helm-charts/dashy/charts/common/templates/spawner/_webhook.tpl new file mode 100644 index 0000000..302e83f --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_webhook.tpl @@ -0,0 +1,65 @@ +{{/* MutatingWebhookConfiguration Spawwner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.webhook" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.webhook" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{- range $name, $mutatingWebhookConfiguration := .Values.webhook -}} + + {{- $enabled := false -}} + {{- if hasKey $mutatingWebhookConfiguration "enabled" -}} + {{- if not (kindIs "invalid" $mutatingWebhookConfiguration.enabled) -}} + {{- $enabled = $mutatingWebhookConfiguration.enabled -}} + {{- else -}} + {{- fail (printf "Webhook - Expected the defined key [enabled] in to not be empty" $name) -}} + {{- end -}} + {{- end -}} + + {{- if kindIs "string" $enabled -}} + {{- $enabled = tpl $enabled $ -}} + + {{/* After tpl it becomes a string, not a bool */}} + {{- if eq $enabled "true" -}} + {{- $enabled = true -}} + {{- else if eq $enabled "false" -}} + {{- $enabled = false -}} + {{- end -}} + {{- end -}} + + {{- if $enabled -}} + + {{/* Create a copy of the mutatingWebhookConfiguration */}} + {{- $objectData := (mustDeepCopy $mutatingWebhookConfiguration) -}} + + {{- $objectName := (printf "%s-%s" $fullname $name) -}} + {{- if hasKey $objectData "expandObjectName" -}} + {{- if not $objectData.expandObjectName -}} + {{- $objectName = $name -}} + {{- end -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Webhook") -}} + + {{/* Set the name of the MutatingWebhookConfiguration */}} + {{- $_ := set $objectData "name" $objectName -}} + {{- $_ := set $objectData "shortName" $name -}} + + {{- include "tc.v1.common.lib.webhook.validation" (dict "rootCtx" $ "objectData" $objectData) -}} + + {{- $type := tpl $objectData.type $ -}} + {{/* Call class to create the object */}} + {{- if eq $type "validating" -}} + {{- include "tc.v1.common.class.validatingWebhookconfiguration" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- else if eq $type "mutating" -}} + {{- include "tc.v1.common.class.mutatingWebhookConfiguration" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- end -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/spawner/_workload.tpl b/helm-charts/dashy/charts/common/templates/spawner/_workload.tpl new file mode 100644 index 0000000..92c87bc --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/spawner/_workload.tpl @@ -0,0 +1,57 @@ +{{/* Workload Spawner */}} +{{/* Call this template: +{{ include "tc.v1.common.spawner.workload" $ -}} +*/}} + +{{- define "tc.v1.common.spawner.workload" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + + {{/* Primary validation for enabled workload. */}} + {{- include "tc.v1.common.lib.workload.primaryValidation" $ -}} + + {{- range $name, $workload := .Values.workload -}} + + {{- if $workload.enabled -}} + + {{/* Create a copy of the workload */}} + {{- $objectData := (mustDeepCopy $workload) -}} + + {{/* Generate the name of the workload */}} + {{- $objectName := $fullname -}} + {{- if not $objectData.primary -}} + {{- $objectName = printf "%s-%s" $fullname $name -}} + {{- end -}} + + {{/* Perform validations */}} + {{- include "tc.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}} + {{- include "tc.v1.common.lib.metadata.validation" (dict "objectData" $objectData "caller" "Workload") -}} + + {{/* Set the name of the workload */}} + {{- $_ := set $objectData "name" $objectName -}} + + {{/* Short name is the one that defined on the chart, used on selectors */}} + {{- $_ := set $objectData "shortName" $name -}} + + {{/* Set the podSpec so it doesn't fail on nil pointer */}} + {{- if not (hasKey $objectData "podSpec") -}} + {{- fail "Workload - Expected key to exist" -}} + {{- end -}} + + {{/* Call class to create the object */}} + {{- if eq $objectData.type "Deployment" -}} + {{- include "tc.v1.common.class.deployment" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- else if eq $objectData.type "StatefulSet" -}} + {{- include "tc.v1.common.class.statefulset" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- else if eq $objectData.type "DaemonSet" -}} + {{- include "tc.v1.common.class.daemonset" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- else if eq $objectData.type "Job" -}} + {{- include "tc.v1.common.class.job" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- else if eq $objectData.type "CronJob" -}} + {{- include "tc.v1.common.class.cronjob" (dict "rootCtx" $ "objectData" $objectData) -}} + {{- end -}} + + {{- end -}} + + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/_init.tpl b/helm-charts/dashy/charts/common/templates/values/_init.tpl new file mode 100644 index 0000000..154742d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/_init.tpl @@ -0,0 +1,14 @@ +{{/* Merge chart values and the common chart defaults */}} +{{/* The ".common" is the name of the library */}} +{{/* Call this template: +{{ include "tc.v1.common.values.init" $ }} +*/}} + +{{- define "tc.v1.common.values.init" -}} + {{- if .Values.common -}} + {{- $commonValues := mustDeepCopy .Values.common -}} + {{- $chartValues := mustDeepCopy (omit .Values "common") -}} + {{- $mergedValues := mustMergeOverwrite $commonValues $chartValues -}} + {{- $_ := set . "Values" (mustDeepCopy $mergedValues) -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/_validate.tpl b/helm-charts/dashy/charts/common/templates/values/_validate.tpl new file mode 100644 index 0000000..a6edc07 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/_validate.tpl @@ -0,0 +1,18 @@ +{{/* Validates any object that it does not contain helm errors */}} +{{/* This usually can happen after merging values from an include that did not render correcly */}} +{{/* Any object will be passed to "toYaml" */}} +{{/* Call this template: +{{ include "tc.v1.common.values.validate" . }} +*/}} +{{- define "tc.v1.common.values.validate" -}} + {{- $allValues := (toYaml .) -}} + + {{- if contains "error converting YAML to JSON" $allValues -}} + {{/* Print values to show values with the error included. */}} + {{/* Ideally we would want to extract the error only, but because it usually contains ":", + It gets parsed as dict and it cant regex matched it afterwards */}} + + {{- fail (printf "Chart - Values contain an error that may be a result of merging. Values containing the error: \n\n %v \n\n See error above values." $allValues) -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/lists/_deviceList.tpl b/helm-charts/dashy/charts/common/templates/values/lists/_deviceList.tpl new file mode 100644 index 0000000..e48330d --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/lists/_deviceList.tpl @@ -0,0 +1,21 @@ +{{- define "tc.v1.common.values.deviceList" -}} + {{- $rootCtx := . -}} + + {{- range $idx, $deviceValues := $rootCtx.Values.deviceList -}} + {{- if eq $deviceValues.type "device" -}} + {{- $name := (printf "device-%s" (toString $idx)) -}} + + {{- with $deviceValues.name -}} + {{- $name = . -}} + {{- end -}} + + {{- if not (hasKey $rootCtx.Values "persistence") -}} + {{- $_ := set $rootCtx.Values "persistence" dict -}} + {{- end -}} + + {{- $_ := set $rootCtx.Values.persistence $name $deviceValues -}} + {{- else -}} + {{- fail (printf "Device List - Only [device] type can be defined in deviceList, but got [%s]" $deviceValues.type) -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/lists/_ingressList.tpl b/helm-charts/dashy/charts/common/templates/values/lists/_ingressList.tpl new file mode 100644 index 0000000..54ba216 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/lists/_ingressList.tpl @@ -0,0 +1,17 @@ +{{- define "tc.v1.common.values.ingressList" -}} + {{- $rootCtx := . -}} + + {{- range $idx, $ingressValues := $rootCtx.Values.ingressList -}} + {{- $name := (printf "ingress-list-%s" (toString $idx)) -}} + + {{- with $ingressValues.name -}} + {{- $name = . -}} + {{- end -}} + + {{- if not (hasKey $rootCtx.Values "ingress") -}} + {{- $_ := set $rootCtx.Values "ingress" dict -}} + {{- end -}} + + {{- $_ := set $rootCtx.Values.ingress $name $ingressValues -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/lists/_persistenceList.tpl b/helm-charts/dashy/charts/common/templates/values/lists/_persistenceList.tpl new file mode 100644 index 0000000..7f30716 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/lists/_persistenceList.tpl @@ -0,0 +1,21 @@ +{{- define "tc.v1.common.values.persistenceList" -}} + {{- $rootCtx := . -}} + + {{- range $idx, $persistenceValues := $rootCtx.Values.persistenceList -}} + {{- if ne $persistenceValues.type "device" -}} + {{- $name := (printf "persist-list-%s" (toString $idx)) -}} + + {{- with $persistenceValues.name -}} + {{- $name = . -}} + {{- end -}} + + {{- if not (hasKey $rootCtx.Values "persistence") -}} + {{- $_ := set $rootCtx.Values "persistence" dict -}} + {{- end -}} + + {{- $_ := set $rootCtx.Values.persistence $name $persistenceValues -}} + {{- else -}} + {{- fail "Persistence List - type [device] should be defined in deviceList only" -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/lists/_portList.tpl b/helm-charts/dashy/charts/common/templates/values/lists/_portList.tpl new file mode 100644 index 0000000..4cfd4d4 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/lists/_portList.tpl @@ -0,0 +1,34 @@ +{{- define "tc.v1.common.values.portList" -}} + {{- $rootCtx := . -}} + {{- $svcValues := .svcValues -}} + + {{- $hasPrimaryPort := false -}} + {{- range $portName, $portValues := $svcValues.ports -}} + {{- if $portValues.enabled -}} + {{- if $portValues.primary -}} + {{- $hasPrimaryPort = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + + {{- range $portIdx, $portValues := $svcValues.portsList -}} + {{- $portName := (printf "port-list-%s" (toString $portIdx)) -}} + + {{- if eq $portIdx 0 -}} + {{- if not $hasPrimaryPort -}} + {{- $_ := set $portValues "primary" true -}} + {{- end -}} + {{- end -}} + + {{- with $portValues.name -}} + {{- $portName = . -}} + {{- end -}} + + {{- if not (hasKey $svcValues "ports") -}} + {{- $_ := set $svcValues "ports" dict -}} + {{- end -}} + + {{- $_ := set $svcValues.ports $portName $portValues -}} + {{- end -}} + +{{- end -}} diff --git a/helm-charts/dashy/charts/common/templates/values/lists/_serviceList.tpl b/helm-charts/dashy/charts/common/templates/values/lists/_serviceList.tpl new file mode 100644 index 0000000..448a9f1 --- /dev/null +++ b/helm-charts/dashy/charts/common/templates/values/lists/_serviceList.tpl @@ -0,0 +1,36 @@ +{{- define "tc.v1.common.values.serviceList" -}} + {{- $rootCtx := . -}} + + {{- $hasPrimary := false -}} + {{- range $svcName, $svcValues := $rootCtx.Values.service -}} + {{- if $svcValues.enabled -}} + {{- if $svcValues.primary -}} + {{- $hasPrimary = true -}} + {{- end -}} {{/* Check if "service" has a portList. */}} + {{- include "tc.v1.common.values.portList" (dict "rootCtx" $rootCtx "svcValues" $svcValues) -}} + {{- end -}} + {{- end -}} + + {{- range $svcIdx, $svcValues := $rootCtx.Values.serviceList -}} + {{- $svcName := (printf "svc-list-%s" (toString $svcIdx)) -}} + + {{- if eq $svcIdx 0 -}} + {{- if not $hasPrimary -}} + {{- $_ := set $svcValues "primary" true -}} + {{- end -}} + {{- end -}} + + {{- with $svcValues.name -}} + {{- $svcName = . -}} + {{- end -}} + + {{- if not (hasKey $rootCtx.Values "service") -}} + {{- $_ := set $rootCtx.Values "service" dict -}} + {{- end -}} + + {{- include "tc.v1.common.values.portList" (dict "rootCtx" $rootCtx "svcValues" $svcValues) -}} + + {{- $_ := set $rootCtx.Values.service $svcName $svcValues -}} + + {{- end -}} +{{- end -}} diff --git a/helm-charts/dashy/charts/common/values.yaml b/helm-charts/dashy/charts/common/values.yaml new file mode 100644 index 0000000..b82c4ef --- /dev/null +++ b/helm-charts/dashy/charts/common/values.yaml @@ -0,0 +1,860 @@ +# -- Global values +global: + # -- Set additional global labels + labels: {} + # -- Set additional global annotations + annotations: {} + # -- 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 + # -- Minimum nodePort value + minNodePort: 9000 + # -- Enable to stop most pods and containers including cnpg + # does not include stand-alone pods + stopAll: false + +fallbackDefaults: + # -- Define a storageClassName that will be used for all PVCs + # Can be overruled per PVC + storageClass: + # -- Default probe type + probeType: http + # -- Default Service Protocol + serviceProtocol: tcp + # -- Default Service Type + serviceType: ClusterIP + # -- Default persistence type + persistenceType: pvc + # -- Default Retain PVC + pvcRetain: false + # -- Default PVC Size + pvcSize: 100Gi + # -- Default VCT Size + vctSize: 100Gi + # -- Default PVC/VCT Access Modes + accessModes: + - ReadWriteOnce + # -- Default probe timeouts + probeTimeouts: + liveness: + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 5 + successThreshold: 1 + readiness: + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 5 + successThreshold: 2 + startup: + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 2 + failureThreshold: 60 + successThreshold: 1 + +# -- Explicitly set a namespace for this chart only +namespace: "" + +# -- Image values +image: + # -- Image repository + repository: tccr.io/truecharts/whoami + # -- Image tag + tag: v1.10.1@sha256:36d22e4b8a154919b819bd7283531783eca9076972e8fc631649bb7eade770d9 + # -- Image pull policy + pullPolicy: IfNotPresent + +chartContext: + APPURL: "" + podCIDR: "" + svcCIDR: "" + +# -- Security Context +securityContext: + # -- Container security context for all containers + # Can be overruled per container + container: + runAsUser: 568 + runAsGroup: 568 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + seccompProfile: + type: RuntimeDefault + capabilities: + add: [] + drop: + - ALL + # When set to false, it will automatically + # add CHOWN, SETUID, SETGID, FOWNER, DAC_OVERRIDE + # capabilities ONLY when container runs as ROOT + disableS6Caps: false + # -- PUID for all containers + # Can be overruled per container + PUID: 568 + # -- UMASK for all containers + # Can be overruled per container + UMASK: "0022" + # -- Pod security context for all pods + # Can be overruled per pod + pod: + fsGroup: 568 + fsGroupChangePolicy: OnRootMismatch + supplementalGroups: [] + sysctls: [] + +# -- Resources +# Can be overruled per container +resources: + limits: + cpu: 4000m + memory: 8Gi + requests: + cpu: 10m + memory: 50Mi + +containerOptions: + NVIDIA_CAPS: + - all + +# -- Options for all pods +# Can be overruled per pod +podOptions: + enableServiceLinks: false + hostNetwork: false + hostPID: false + shareProcessNamespace: false + restartPolicy: Always + dnsPolicy: ClusterFirst + dnsConfig: + options: + - name: ndots + value: "1" + hostAliases: [] + nodeSelector: + kubernetes.io/arch: "amd64" + # -- Used to enforce a good spread for Deployments and StatefulSets by default + defaultSpread: true + topologySpreadConstraints: [] + tolerations: [] + schedulerName: "" + priorityClassName: "" + runtimeClassName: "" + automountServiceAccountToken: false + terminationGracePeriodSeconds: 60 + +# -- (docs/workload/README.md) +workload: + main: + enabled: true + primary: true + type: Deployment + dbWait: true + podSpec: + containers: + main: + enabled: true + primary: true + imageSelector: image + probes: + liveness: + enabled: true + type: "{{ .Values.service.main.ports.main.protocol }}" + port: "{{ $.Values.service.main.ports.main.targetPort | default .Values.service.main.ports.main.port }}" + readiness: + enabled: true + type: "{{ .Values.service.main.ports.main.protocol }}" + port: "{{ $.Values.service.main.ports.main.targetPort | default .Values.service.main.ports.main.port }}" + startup: + enabled: true + type: "tcp" + port: "{{ $.Values.service.main.ports.main.targetPort | default .Values.service.main.ports.main.port }}" + +# -- Timezone used everywhere applicable +TZ: UTC + +# -- (docs/service/README.md) +service: + main: + enabled: true + primary: true + ports: + main: + enabled: true + primary: true + protocol: http + +serviceList: [] + +# -- (docs/persistence/README.md) +persistence: + shared: + enabled: true + type: emptyDir + mountPath: /shared + targetSelectAll: true + varlogs: + enabled: true + type: emptyDir + mountPath: /var/logs + targetSelectAll: true + varrun: + enabled: true + type: emptyDir + mountPath: /var/run + medium: Memory + targetSelectAll: true + tmp: + enabled: true + type: emptyDir + mountPath: /tmp + targetSelectAll: true + devshm: + enabled: true + type: emptyDir + mountPath: /dev/shm + medium: Memory + targetSelectAll: true + +persistenceList: [] + +deviceList: [] + +# -- Injected from SCALE middleware +# Only for reference here +ixExternalInterfacesConfiguration: [] +# -- Injected from SCALE middleware +# Only for reference here +ixExternalInterfacesConfigurationNames: [] +# -- Injected from SCALE middleware +# Only for reference here +ixCertificates: [] +# -- Injected from SCALE middleware +# Only for reference here +ixVolumes: [] + +# -- (docs/imagePullSecrets.md) +imagePullSecret: [] + +# -- (docs/configmap.md) +configmap: {} + +# -- (docs/secret.md) +secret: {} + +# -- (docs/serviceAccount.md) +serviceAccount: {} + +# -- (docs/rbac.md) +rbac: {} + +# -- (docs/volumeClaimTemplates) (StatefulSet only) +volumeClaimTemplates: {} + +# -- (docs/scaleExternalInterface.md) +scaleExternalInterface: [] + +# -- (docs/scaleCertificate.md) +scaleCertificate: {} + +# -- (docs/scaleGPU.md) +scaleGPU: [] + +# NOTES.txt +notes: + header: | + # Thank you for installing [{{ .Chart.Name }}] by TrueCharts. + # custom: "{{ toYaml $.Values }}" + custom: | + {{- if .Values.iXPortals }} + ## Connecting externally + You can use this Chart by opening one of the following links in your browser: + + {{- range .Values.iXPortals }} + - {{ toYaml . }} + {{- end -}} + {{- end }} + + ## [{{ .Chart.Name }}] Sources + + {{- range .Chart.Sources }} + - {{ . }} + {{- end -}} + + {{- $link := .Chart.Annotations.docs -}} + {{- if not $link -}} + {{- $link = .Chart.Home -}} + {{- end }} + [See more for [{{ $.Chart.Name }}] at [{{ $link }}] + footer: | + ## Documentation + Please check out the TrueCharts documentation on: + https://truecharts.org + + OpenSource can only exist with your help, please consider supporting TrueCharts: + https://truecharts.org/sponsor + +# -- iXsystems prototype values.yaml based portals +iXPortals: [] + +#### +## +## TrueCharts Specific Root Objects +## +#### + +# -- Defines the portals for which config needs to be generated +portal: + open: + enabled: false + override: + protocol: + host: + port: + path: "" + targetSelector: + ingress: "" + service: "" + port: "" + +# -- Set by "open" portal, used for some applications internally. +APPURL: "" + +gluetunImage: + repository: tccr.io/truecharts/gluetun + tag: v3.36.0@sha256:0cd36b27fcfc21b9ab738a594a8e477e94e42fd7c2a52539615bb2c8cac2d75e + pullPolicy: IfNotPresent + +netshootImage: + repository: tccr.io/truecharts/netshoot + tag: v0.11.0@sha256:e6a26284531b240865a0b31d1c8835e8ee1862799c816014e4c59c1401abe1c5 + pullPolicy: IfNotPresent + +tailscaleImage: + repository: tccr.io/truecharts/tailscale + tag: v1.52.0@sha256:806efacf7c05d3fd2c8ac3ca9606f58469022f56e62f20a3e9ad136174d0e27f + pullPolicy: IfNotPresent + +codeserverImage: + repository: tccr.io/truecharts/code-server + tag: v4.18.0@sha256:e59861c2753490910c08bc3db5ea09234c9a80a3fcbac810621084c7178ce4b0 + pullPolicy: IfNotPresent + +alpineImage: + repository: tccr.io/truecharts/alpine + tag: v3.18.4@sha256:17cd77e25d3fa829d168caec4db7bb5b52ceeb935d8ca0d1180de6f615553dc4 + pullPolicy: IfNotPresent + +scratchImage: + repository: tccr.io/truecharts/scratch + tag: latest@sha256:7f821eeb99d04ac248c47f79cfbcc2482651fea48aff9ec5d2ba0ba34f1f5531 + pullPolicy: IfNotPresent + +kubectlImage: + repository: tccr.io/truecharts/kubectl + tag: v1.26.0@sha256:323ab7aa3e7ce84c024df79d0f364282c1135499298f54be2ade46508a116c4b + pullPolicy: IfNotPresent + +wgetImage: + repository: tccr.io/truecharts/wget + tag: 1.0.0@sha256:1764b1bb79b5d33edeb65b0bd5452b0a9622f8602f53a77e6a516261cfe7aa3d + pullPolicy: IfNotPresent + +postgresClientImage: + repository: tccr.io/truecharts/db-wait-postgres + tag: 1.1.0@sha256:a163c7836d7bb436a428f5d55bbba0eb73bcdb9bc202047e2523bbb539c113e6 + pullPolicy: IfNotPresent + +mariadbClientImage: + repository: tccr.io/truecharts/db-wait-mariadb + tag: 1.1.0@sha256:492a9659511d3288ba9b6536fb17d1cb037fb3876f402dffa5dbcb040acbb85a + pullPolicy: IfNotPresent + +redisClientImage: + repository: tccr.io/truecharts/db-wait-redis + tag: 1.1.0@sha256:8affa086d097b948f62b0433d70f4219a22ec29843ebd5479391869341bdb638 + pullPolicy: IfNotPresent + +mongodbClientImage: + repository: tccr.io/truecharts/db-wait-mongodb + tag: 1.1.0@sha256:502f70a653a905ad23576e208d0e5241e9cc8aeed63bb923e6da8563bdc3c1e7 + pullPolicy: IfNotPresent + +# -- OpenVPN specific configuration +# @default -- See below +openvpnImage: + # -- Specify the openvpn client image + repository: tccr.io/truecharts/openvpn-client + # -- Specify the openvpn client image tag + tag: latest@sha256:1f83decdf614cbf48e2429921b6f0efa0e825f447f5c510b65bc90f660227688 + # -- Specify the openvpn client image pull policy + pullPolicy: IfNotPresent + +# -- WireGuard specific configuration +# @default -- See below +wireguardImage: + # -- Specify the WireGuard image + repository: tccr.io/truecharts/wireguard + # -- Specify the WireGuard image tag + tag: v1.0.20210914@sha256:9f56e5660e8df8d4d38521ed73a4cc29fa24bf578007bfbe633e00184e2ebfbc + # -- 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 +ingress: + main: + # -- Enables or disables the ingress + enabled: false + + # -- Make this the primary ingress (used in probes, notes, etc...). + # If there is more than 1 ingress, make sure that only 1 ingress is marked as primary. + primary: true + + # -- 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. + # -- Provide additional labels which may be required. + labels: {} + + # -- 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 + + ## Configure the hosts for the ingress + hosts: + - # -- Host address. Helm template can be passed. + host: chart-example.local + ## Configure the paths for the host + paths: + - # -- Path. Helm template can be passed. + path: / + # -- Ignored if not kubeVersion >= 1.14-0 + pathType: Prefix + service: + # -- Overrides the service name reference for this path + name: + # -- Overrides the service port reference for this path + port: + + # -- Configure TLS for the ingress. Both secretName and hosts can process a Helm template. + # Gets ignored when clusterIssuer is filled + tls: [] + # - secretName: chart-example-tls + # # Cannot be combined with scaleCert + # clusterIssuer: "" + # # Cannot be combined with clusterIssuer + # scaleCert: "" + # hosts: + # - chart-example.local + +# -- BETA: Configure the gateway routes for the chart here. +# Additional routes can be added by adding a dictionary key similar to the 'main' route. +# Please be aware that this is an early beta of this feature, TrueCharts does not guarantee this actually works. +# Being BETA this can/will change in the future without notice, please do not use unless you want to take that risk +# [[ref]](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1alpha2) +# @default -- See below +route: + main: + # -- Enables or disables the route + enabled: false + # -- Set the route kind + # Valid options are GRPCRoute, HTTPRoute, TCPRoute, TLSRoute, UDPRoute + kind: HTTPRoute + # -- Provide additional annotations which may be required. + annotations: {} + # -- Provide additional labels which may be required. + labels: {} + # -- Configure the resource the route attaches to. + parentRefs: + - # Group of the referent resource. + group: gateway.networking.k8s.io + # Kind of the referent resource. + kind: Gateway + # Name of the referent resource + name: + # Namespace of the referent resource + namespace: + # Name of the section within the target resource. + sectionName: + # -- Host addresses + hostnames: [] + # -- Configure rules for routing. Defaults to the primary service. + rules: + - # -- Configure backends where matching requests should be sent. + backendRefs: + - group: "" + kind: Service + name: + namespace: + port: + weight: 1 + ## Configure conditions used for matching incoming requests. Only for HTTPRoutes + matches: + - path: + type: PathPrefix + value: / + +podDisruptionBudget: + main: + enabled: false + # -- Custom Selector Labels + # customLabels: + # customKey: customValue + targetSelector: main + minAvailable: 1 + maxUnavailable: 1 + +webhook: + validating: + enabled: false + type: validating + webhooks: [] + mutating: + enabled: false + type: mutating + webhooks: [] + +metrics: + main: + enabled: false + primary: true + # options: servicemonitor, podmonitor + type: "servicemonitor" + # defaults to selectorLabels + selector: {} + endpoints: + - port: main + interval: 5s + scrapeTimeout: 5s + path: / + honorLabels: false + prometheusRule: + enabled: false + groups: {} + # somegroup: + # # list of rules + # rules: [] + # # list to support adding rules via the SCALE GUI without overwrithing the rules + # additionalrules: [] + # List to support adding groups using the SCALE GUI + additionalgroups: + #- name: "somegroup" + # # list of rules + # rules: [] + # # list to support adding rules via the SCALE GUI without overwrithing the rules + # additionalrules: [] + +# -- Contains specific settings for helm charts containing or using operators +operator: + # -- Adds a configmap to the operator to register this chart as an operator + register: false + # -- Verified wether required operators for this chart are actually installed and registered + verify: + enabled: true + # -- Makes non-found operators hard-failing + failOnError: true + # -- a list of extra operators to check for + additionalOperators: [] + ## -- used as a datastore when a metallb operator is found. + # metallb: {} + ## -- used as a datastore when a traefik operator is found. + # traefik: {} + ## -- used as a datastore when a prometheus operator is found. + # prometheus: {} + ## -- used as a datastore when a cloudnative-pg operator is found. + # cloudnative-pg: {} + ## -- used as a datastore when a cert-manager operator is found. + # cert-manager: {} + +# -- The common chart supports several add-ons. These can be configured under this key. +# @default -- See below +addons: + # -- The common chart supports adding a VPN add-on. It can be configured under this key. + # @default -- See values.yaml + vpn: + # -- Specify the VPN type. Valid options are disabled, gluetun, openvpn, wireguard or tailscale + # OpenVPN and Wireguard are considered deprecated + type: disabled + + # -- Tailscale specific configuration + # @default -- See below + # See more info for the configuration + # https://github.com/tailscale/tailscale/blob/main/docs/k8s/run.sh + tailscale: + # -- Auth key to connect to the VPN Service + authkey: "" + # As a sidecar, it should only need to run in userspace + userspace: true + auth_once: true + accept_dns: false + routes: "" + dest_ip: "" + sock5_server: "" + extra_args: "" + daemon_extra_args: "" + outbound_http_proxy_listen: "" + # -- Annotations for tailscale sidecar + annotations: {} + + # -- OpenVPN specific configuration + # @default -- See below + openvpn: + # -- Credentials to connect to the VPN Service (used with -a) + # Only using password is enough + username: "" + password: "" + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + env: {} + # TZ: UTC + + # -- All variables specified here will be added to the vpn sidecar container + # See the documentation of the VPN image for all config values + envList: [] + # - name: someenv + # value: somevalue + + + # -- you can directly specify the config file here + config: "" + + scripts: + # -- you can directly specify the upscript here + up: "" + # some script + + # -- you can directly specify the downscript here + down: "" + # some script + + # -- Provide a customized vpn configuration file location to be used by the VPN. + configFile: "" + + # -- Provide a customized vpn configuration folder location to be added to the VPN container + # The config file needs to be mounted seperately + # the upscript and downscript need to be named: upscript.sh and downscript.sh respectively + configFolder: "" + + # -- Provide an existing secret for vpn config storage + existingSecret: "" + + # -- select pods to bind vpn addon to + # Add "codeserver" to also add the codeserver pod to VPN + targetSelector: + - main + + ## Only for Wireguard and OpenVPN + killSwitch: true + excludedNetworks_IPv4: [] + excludedNetworks_IPv6: [] + + + # -- The common library supports adding a code-server add-on to access files. It can be configured under this key. + # @default -- See values.yaml + codeserver: + # -- Enable running a code-server container in the pod + enabled: false + + # -- Set any environment variables for code-server here + env: {} + + # -- All variables specified here will be added to the codeserver sidecar container + # See the documentation of the codeserver image for all config values + envList: [] + # - name: someenv + # value: somevalue + # -- Set codeserver command line arguments. + # Consider setting --user-data-dir to a persistent location to preserve code-server setting changes + args: + - --auth + - none + # - --user-data-dir + # - "/config/.vscode" + + # -- Specify the working dir that will be opened when code-server starts + # If not given, the app will default to the mountpah of the first specified volumeMount + workingDir: "/" + + service: + # -- Enable a service for the code-server add-on. + enabled: true + type: ClusterIP + # Specify the default port information + ports: + codeserver: + enabled: true + primary: true + protocol: http + port: 12321 + + ingress: + # -- Enable an ingress for the code-server add-on. + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + labels: {} + hosts: + - host: code.chart-example.local + paths: + - path: / + # Ignored if not kubeVersion >= 1.14-0 + pathType: Prefix + tls: [] + + # -- Select a container to add the addon to + targetSelector: "" + + + netshoot: + # -- Enable running a netshoot container in the pod + enabled: false + + # -- Set any environment variables for netshoot here + env: {} + + +## +# This section contains some-preconfig for frequently used dependencies +## + +cnpg: + main: + enabled: false + primary: true + # -- Puts the cnpg cluster in hibernation mode + hibernate: false + # -- number of instances for both postgres and pgbouncer + instances: 2 + database: "app" + user: "app" + # password: + # superUserPassword: + # -- change to supervised to disable unsupervised updates + # Example of rolling update strategy: + # - unsupervised: automated update of the primary once all + # replicas have been upgraded (default) + # - supervised: requires manual supervision to perform + # the switchover of the primary + primaryUpdateStrategy: unsupervised + # -- enable to create extra pgbouncer for readonly access + acceptRO: false + # -- storage size for the two pvc's per instance + storage: + size: "256Gi" + walsize: "256Gi" + # -- Gets scaled to 0 if hibernation is true + pooler: + instances: 2 + # -- set to enable prometheus metrics + monitoring: + enablePodMonitor: true + # -- contains credentials and urls output by generator + creds: {} + # -- contains postgresql settings + # ref: https://cloudnative-pg.io/documentation/1.19/postgresql_conf/#the-postgresql-section + postgresql: {} + +# -- Redis dependency configuration +# @default -- See below +redis: + enabled: false + # -- can be used to make an easy accessable note which URLS to use to access the DB. + creds: {} + manifestManager: + enabled: false + secret: + credentials: + enabled: false + +# -- mariadb dependency configuration +# @default -- See below +mariadb: + enabled: false + existingSecret: "mariadbcreds" + # -- can be used to make an easy accessable note which URLS to use to access the DB. + creds: {} + manifestManager: + enabled: false + +# -- mongodb dependency configuration +# @default -- See below +mongodb: + enabled: false + existingSecret: "mongodbcreds" + # -- can be used to make an easy accessable note which URLS to use to access the DB. + creds: {} + manifestManager: + enabled: false + +# -- clickhouse dependency configuration +# @default -- See below +clickhouse: + enabled: false + existingSecret: "clickhousecreds" + # -- can be used to make an easy accessable note which URLS to use to access the DB. + creds: {} + manifestManager: + enabled: false + +# -- solr dependency configuration +# @default -- See below +solr: + enabled: false + solrCores: 1 + solrEnableAuthentication: "no" + existingSecret: "solrcreds" + # -- can be used to make an easy accessable note which URLS to use to access the DB. + creds: {} + manifestManager: + enabled: false + +# -- List of extra objects to deploy with the release +extraTpl: [] diff --git a/helm-charts/dashy/ci/direct-values.yaml b/helm-charts/dashy/ci/direct-values.yaml new file mode 100644 index 0000000..23168e5 --- /dev/null +++ b/helm-charts/dashy/ci/direct-values.yaml @@ -0,0 +1,3 @@ +dashyConfig: + pageInfo: + title: Home Lab diff --git a/helm-charts/dashy/ci/standalone-values.yaml b/helm-charts/dashy/ci/standalone-values.yaml new file mode 100644 index 0000000..e69de29 diff --git a/helm-charts/dashy/questions.yaml b/helm-charts/dashy/questions.yaml new file mode 100644 index 0000000..3c1133d --- /dev/null +++ b/helm-charts/dashy/questions.yaml @@ -0,0 +1,123 @@ +# Include{groups} +portals: + open: +# Include{portalLink} +questions: +# Include{global} +# Include{workload} +# Include{workloadDeployment} + +# Include{replicas1} +# Include{podSpec} +# Include{containerMain} +# Include{containerBasic} +# Include{containerAdvanced} + + - variable: dashy + group: App Configuration + label: Dashy Configuration + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable Config File Mount + description: Mounts a config file from the given host path + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: configFileHostPath + label: Config File Host Path + description: Absolute host path of the config file + schema: + type: string + default: "" + - variable: configFileHostReadOnly + label: Config File Read Only + description: Mount config file as read Only + schema: + type: boolean + default: true +# Include{containerConfig} +# Include{podOptions} +# Include{serviceRoot} + - variable: main + label: Main Service + description: The Primary service on which the healthcheck runs, often the webUI + schema: + additional_attrs: true + type: dict + attrs: +# Include{serviceSelectorLoadBalancer} +# Include{serviceSelectorExtras} + - variable: main + label: Main Service Port Configuration + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: Port + description: This port exposes the container port on the service + schema: + type: int + default: 10310 + required: true +# Include{serviceExpertRoot} +# Include{serviceExpert} +# Include{serviceList} +# Include{persistenceRoot} + - variable: icons + label: App Icons Storage + description: Stores the Application Icons. + schema: + additional_attrs: true + type: dict + attrs: +# Include{persistenceBasic} +# Include{persistenceList} +# Include{ingressRoot} + - variable: main + label: Main Ingress + schema: + additional_attrs: true + type: dict + attrs: +# Include{ingressDefault} +# Include{ingressTLS} +# Include{ingressTraefik} +# Include{ingressAdvanced} +# Include{ingressList} +# Include{securityContextRoot} + - variable: runAsUser + label: runAsUser + description: The UserID of the user running the application + schema: + type: int + default: 0 + - variable: runAsGroup + label: runAsGroup + description: The groupID of the user running the application + schema: + type: int + default: 0 + +# Include{securityContextContainer} +# Include{securityContextAdvanced} +# Include{securityContextPod} + - variable: fsGroup + label: fsGroup + description: The group that should own ALL storage. + schema: + type: int + default: 568 + +# Include{resources} +# Include{advanced} +# Include{addons} +# Include{codeserver} +# Include{netshoot} +# Include{vpn} +# Include{documentation} diff --git a/helm-charts/dashy/templates/NOTES.txt b/helm-charts/dashy/templates/NOTES.txt new file mode 100644 index 0000000..efcb74c --- /dev/null +++ b/helm-charts/dashy/templates/NOTES.txt @@ -0,0 +1 @@ +{{- include "tc.v1.common.lib.chart.notes" $ -}} diff --git a/helm-charts/dashy/templates/_configmap.tpl b/helm-charts/dashy/templates/_configmap.tpl new file mode 100644 index 0000000..a9ec4b6 --- /dev/null +++ b/helm-charts/dashy/templates/_configmap.tpl @@ -0,0 +1,9 @@ +{{/* Define the secrets */}} +{{- define "dashy.config" -}} +configmap: + dashy-config: + enabled: true + data: + conf.yml: | + {{- .Values.dashyConfig | toYaml | nindent 8 }} +{{- end -}} diff --git a/helm-charts/dashy/templates/common.yaml b/helm-charts/dashy/templates/common.yaml new file mode 100644 index 0000000..eaeaf9b --- /dev/null +++ b/helm-charts/dashy/templates/common.yaml @@ -0,0 +1,37 @@ +{{/* Make sure all variables are set properly */}} +{{- include "tc.v1.common.loader.init" . }} + +{{- define "dashy.configvolume" -}} +enabled: true +type: configmap +objectName: dashy-config +readOnly: true +defaultMode: "0755" +mountPath: /app/public +items: +- key: conf.yml + path: conf.yml +{{- end -}} + +{{- define "dashy.confighostpath" -}} +enabled: true +type: hostPath +readOnly: {{ .Values.dashy.configFileHostReadOnly }} +hostPathType: File +hostPath: {{ .Values.dashy.configFileHostPath }} +mountPath: /app/public/conf.yml +{{- end -}} + +{{- if .Values.dashyConfig -}} + {{/* Render config for dashy */}} + {{- $config := include "dashy.config" . | fromYaml -}} + {{- if $config -}} + {{- $_ := mustMergeOverwrite .Values $config -}} + {{- end -}} + {{- $_ := set .Values.persistence "dashy-config" (include "dashy.configvolume" . | fromYaml) -}} +{{- else if .Values.dashy.enabled -}} + {{- $_ := set .Values.persistence "dashy-config" (include "dashy.confighostpath" . | fromYaml) -}} +{{- end -}} + +{{/* Render the templates */}} +{{ include "tc.v1.common.loader.apply" . }} diff --git a/helm-charts/dashy/values.yaml b/helm-charts/dashy/values.yaml new file mode 100644 index 0000000..6a5c7fc --- /dev/null +++ b/helm-charts/dashy/values.yaml @@ -0,0 +1,204 @@ +image: + repository: tccr.io/truecharts/dashy + tag: v2.1.1@sha256:6e96a896d292b6e84cbdc265b18a2884e7b2528b7cae06f0eb6f6ec8d228afb9 + pullPolicy: IfNotPresent + +securityContext: + container: + readOnlyRootFilesystem: false + runAsNonRoot: false + runAsUser: 0 + runAsGroup: 0 + +service: + main: + ports: + main: + port: 10310 + protocol: http + targetPort: 80 + +dashy: + # Enable config file mount from host path + enabled: false + configFileHostPath: "" + configFileHostReadOnly: true + +# Leave empty if you plan to use config file from host path +dashyConfig: + pageInfo: + title: guaranteedstruggle.host + sections: # An array of sections + + + - name: Fun stuff + items: + - title: Тупица + icon: hl-telegram + description: бот с фаллометрией и чатгпт + url: https://t.me/alarmingtest_bot + - title: vdk2ch + description: борда (мы её починим) + icon: favicon-iconhorse + url: https://www.vdk2ch.ru/ + - title: 3d-realm + description: что-то на webgl-ном + icon: favicon-iconhorse + url: https://3d-realm.guaranteedstruggle.host/ + - title: Dashy + description: вот эта дурацкая панель + icon: hl-dashy + url: https://dashy.guaranteedstruggle.host/ + - title: youtrack + description: не у нас поднято, но нами юзается + icon: hl-jetbrains-youtrack + url: https://mightydick.youtrack.cloud/issues + - title: Pleroma + description: общественный твиттор + icon: hl-pleroma + url: https://social.guaranteedstruggle.host/ + - title: Funkwhale + description: mine mediateque + icon: hl-funkwhale + url: https://music.guaranteedstruggle.host/ + - title: Pixelfed + description: pictures of wut + icon: hl-pixelfed + url: https://pixels.guaranteedstruggle.host/ + - title: Writefreely + description: kind of microblogging + icon: favicon-iconhorse + url: https://blog.guaranteedstruggle.host/ + + + + - name: Infra Stuff + icon: far fa-rocket + items: + - title: Gitea + description: source code and whatever + #icon: fab fa-git-alt + icon: favicon-iconhorse + url: https://git.guaranteedstruggle.host/ + - title: Drone + description: ci/cd jobs + icon: favicon-iconhorse + url: https://drone.guaranteedstruggle.host/ + - title: minikube + description: мама я кубирнетер + icon: hl-kubernetes-dashboard + url: https://minikube.guaranteedstruggle.host/ + - title: Consul + description: service reg and whatever + icon: favicon-iconhorse + url: https://consul.guaranteedstruggle.host/ + - title: Vault + description: secrets and whatever + icon: favicon-iconhorse + url: https://vault.guaranteedstruggle.host/ + - title: ArangoDB + description: графовая няша + icon: si-arangodb + url: https://arango.guaranteedstruggle.host/ + - title: Minio + description: статика всякая + icon: hl-minio + url: https://minio.guaranteedstruggle.host/ + + + + - name: it's all on server (без веб-морд) + items: + - title: Docker + icon: si-docker + description: ..containers! + - title: Nginx + icon: si-nginx + description: reverse-proxy, yes + # - title: Postgres + # icon: si-postgresql + - title: PuppetServer + icon: si-puppet + description: IaC on few computers + widgets: + - type: clock + options: + timeZone: Asia/Vladivostok + format: en-GB + hideDate: false + + + + - name: мониторинговое + items: + - title: Prometheus + description: сюда льются метрики + icon: hl-prometheus + url: https://prom.guaranteedstruggle.host/ + - title: Alertmanager + description: отсюда можно чутка управлять алертами + icon: hl-alertmanager + url: https://alertmanager.guaranteedstruggle.host/ + - title: Grafana + description: графики этих ваших метрик + icon: hl-grafana + url: https://grafana.guaranteedstruggle.host/ + - title: Loki + description: сбор этих ваших логов для дальнейших графан + icon: hl-loki + - title: NodeExporter + description: метрики машины + - title: PipisaExporter + description: метрики фаллометрии + + + appConfig: + theme: adventure + language: en + layout: auto + iconSize: large + #{} + # pageInfo: + # title: Home Lab + +workload: + main: + podSpec: + containers: + main: + env: + NODE_ENV: production + probes: + liveness: + enabled: true + custom: true + spec: + exec: + command: + - node + - /app/services/healthcheck + readiness: + enabled: true + custom: true + spec: + exec: + command: + - node + - /app/services/healthcheck + startup: + enabled: true + custom: true + spec: + exec: + command: + - node + - /app/services/healthcheck + +persistence: + icons: + enabled: true + mountPath: /app/public/item-icons + +portal: + open: + enabled: true diff --git a/helm-charts/harbor/.helmignore b/helm-charts/harbor/.helmignore new file mode 100644 index 0000000..b4424fd --- /dev/null +++ b/helm-charts/harbor/.helmignore @@ -0,0 +1,6 @@ +.github/* +docs/* +.git/* +.gitignore +CONTRIBUTING.md +test/* \ No newline at end of file diff --git a/helm-charts/harbor/Chart.yaml b/helm-charts/harbor/Chart.yaml new file mode 100644 index 0000000..9261e59 --- /dev/null +++ b/helm-charts/harbor/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +appVersion: 2.9.1 +description: An open source trusted cloud native registry that stores, signs, and scans content +home: https://goharbor.io +icon: https://raw.githubusercontent.com/goharbor/website/main/static/img/logos/harbor-icon-color.png +keywords: +- docker +- registry +- harbor +maintainers: +- email: yinw@vmware.com + name: Wenkai Yin +- email: hweiwei@vmware.com + name: Weiwei He +- email: yshengwen@vmware.com + name: Shengwen Yu +name: harbor +sources: +- https://github.com/goharbor/harbor +- https://github.com/goharbor/harbor-helm +version: 1.13.1 diff --git a/helm-charts/harbor/LICENSE b/helm-charts/harbor/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/helm-charts/harbor/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/helm-charts/harbor/README.md b/helm-charts/harbor/README.md new file mode 100644 index 0000000..f30598c --- /dev/null +++ b/helm-charts/harbor/README.md @@ -0,0 +1,407 @@ +# Helm Chart for Harbor + +**Notes:** The master branch is in heavy development, please use the other stable versions instead. A highly available solution for Harbor based on chart can be found [here](docs/High%20Availability.md). And refer to the [guide](docs/Upgrade.md) to upgrade the existing deployment. + +This repository, including the issues, focuses on deploying Harbor chart via helm. For functionality issues or Harbor questions, please open issues on [goharbor/harbor](https://github.com/goharbor/harbor) + +## Introduction + +This [Helm](https://github.com/kubernetes/helm) chart installs [Harbor](https://github.com/goharbor/harbor) in a Kubernetes cluster. Welcome to [contribute](CONTRIBUTING.md) to Helm Chart for Harbor. + +## Prerequisites + +- Kubernetes cluster 1.20+ +- Helm v3.2.0+ + +## Installation + +### Add Helm repository + +```bash +helm repo add harbor https://helm.goharbor.io +``` + +### Configure the chart + +The following items can be set via `--set` flag during installation or configured by editing the `values.yaml` directly (need to download the chart first). + +#### Configure how to expose Harbor service + +- **Ingress**: The ingress controller must be installed in the Kubernetes cluster. + **Notes:** if TLS is disabled, the port must be included in the command when pulling/pushing images. Refer to issue [#5291](https://github.com/goharbor/harbor/issues/5291) for details. +- **ClusterIP**: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. +- **NodePort**: Exposes the service on each Node’s IP at a static port (the NodePort). You’ll be able to contact the NodePort service, from outside the cluster, by requesting `NodeIP:NodePort`. +- **LoadBalancer**: Exposes the service externally using a cloud provider’s load balancer. + +#### Configure the external URL + +The external URL for Harbor core service is used to: + +1. populate the docker/helm commands showed on portal +2. populate the token service URL returned to docker client + +Format: `protocol://domain[:port]`. Usually: + +- if service exposed via `Ingress`, the `domain` should be the value of `expose.ingress.hosts.core` +- if service exposed via `ClusterIP`, the `domain` should be the value of `expose.clusterIP.name` +- if service exposed via `NodePort`, the `domain` should be the IP address of one Kubernetes node +- if service exposed via `LoadBalancer`, set the `domain` as your own domain name and add a CNAME record to map the domain name to the one you got from the cloud provider + +If Harbor is deployed behind the proxy, set it as the URL of proxy. + +#### Configure how to persist data + +- **Disable**: The data does not survive the termination of a pod. +- **Persistent Volume Claim(default)**: A default `StorageClass` is needed in the Kubernetes cluster to dynamically provision the volumes. Specify another StorageClass in the `storageClass` or set `existingClaim` if you already have existing persistent volumes to use. +- **External Storage(only for images and charts)**: For images and charts, the external storages are supported: `azure`, `gcs`, `s3` `swift` and `oss`. + +#### Configure the other items listed in [configuration](#configuration) section + +### Install the chart + +Install the Harbor helm chart with a release name `my-release`: +```bash +helm install my-release harbor/harbor +``` + +## Uninstallation + +To uninstall/delete the `my-release` deployment: +```bash +helm uninstall my-release +``` + +## Configuration + +The following table lists the configurable parameters of the Harbor chart and the default values. + +| Parameter | Description | Default | +| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | +| **Expose** | | | +| `expose.type` | How to expose the service: `ingress`, `clusterIP`, `nodePort` or `loadBalancer`, other values will be ignored and the creation of service will be skipped. | `ingress` | +| `expose.tls.enabled` | Enable TLS or not. Delete the `ssl-redirect` annotations in `expose.ingress.annotations` when TLS is disabled and `expose.type` is `ingress`. Note: if the `expose.type` is `ingress` and TLS is disabled, the port must be included in the command when pulling/pushing images. Refer to https://github.com/goharbor/harbor/issues/5291 for details. | `true` | +| `expose.tls.certSource` | The source of the TLS certificate. Set as `auto`, `secret` or `none` and fill the information in the corresponding section: 1) auto: generate the TLS certificate automatically 2) secret: read the TLS certificate from the specified secret. The TLS certificate can be generated manually or by cert manager 3) none: configure no TLS certificate for the ingress. If the default TLS certificate is configured in the ingress controller, choose this option | `auto` | +| `expose.tls.auto.commonName` | The common name used to generate the certificate, it's necessary when the type isn't `ingress` | | +| `expose.tls.secret.secretName` | The name of secret which contains keys named: `tls.crt` - the certificate; `tls.key` - the private key | | +| `expose.ingress.hosts.core` | The host of Harbor core service in ingress rule | `core.harbor.domain` | +| `expose.ingress.controller` | The ingress controller type. Currently supports `default`, `gce`, `alb`, `f5-bigip` and `ncp` | `default` | +| `expose.ingress.kubeVersionOverride` | Allows the ability to override the kubernetes version used while templating the ingress | | +| `expose.ingress.annotations` | The annotations used commonly for ingresses | | +| `expose.ingress.harbor.annotations` | The annotations specific to harbor ingress | {} | +| `expose.ingress.harbor.labels` | The labels specific to harbor ingress | {} | +| `expose.clusterIP.name` | The name of ClusterIP service | `harbor` | +| `expose.clusterIP.annotations` | The annotations attached to the ClusterIP service | {} | +| `expose.clusterIP.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.clusterIP.ports.httpsPort` | The service port Harbor listens on when serving HTTPS | `443` | +| `expose.nodePort.name` | The name of NodePort service | `harbor` | +| `expose.nodePort.ports.http.port` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.nodePort.ports.http.nodePort` | The node port Harbor listens on when serving HTTP | `30002` | +| `expose.nodePort.ports.https.port` | The service port Harbor listens on when serving HTTPS | `443` | +| `expose.nodePort.ports.https.nodePort` | The node port Harbor listens on when serving HTTPS | `30003` | +| `expose.loadBalancer.name` | The name of service | `harbor` | +| `expose.loadBalancer.IP` | The IP of the loadBalancer. It only works when loadBalancer supports assigning IP | `""` | +| `expose.loadBalancer.ports.httpPort` | The service port Harbor listens on when serving HTTP | `80` | +| `expose.loadBalancer.ports.httpsPort` | The service port Harbor listens on when serving HTTPS | `30002` | +| `expose.loadBalancer.annotations` | The annotations attached to the loadBalancer service | {} | +| `expose.loadBalancer.sourceRanges` | List of IP address ranges to assign to loadBalancerSourceRanges | [] | +| **Internal TLS** | | | +| `internalTLS.enabled` | Enable TLS for the components (core, jobservice, portal, registry, trivy) | `false` | +| `internalTLS.strong_ssl_ciphers` | Enable strong ssl ciphers for nginx and portal | `false` +| `internalTLS.certSource` | Method to provide TLS for the components, options are `auto`, `manual`, `secret`. | `auto` | +| `internalTLS.trustCa` | The content of trust CA, only available when `certSource` is `manual`. **Note**: all the internal certificates of the components must be issued by this CA | | +| `internalTLS.core.secretName` | The secret name for core component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.core.crt` | Content of core's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.core.key` | Content of core's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.jobservice.secretName` | The secret name for jobservice component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.jobservice.crt` | Content of jobservice's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.jobservice.key` | Content of jobservice's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.registry.secretName` | The secret name for registry component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.registry.crt` | Content of registry's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.registry.key` | Content of registry's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.portal.secretName` | The secret name for portal component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.portal.crt` | Content of portal's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.portal.key` | Content of portal's TLS key file, only available when `certSource` is `manual` | | +| `internalTLS.trivy.secretName` | The secret name for trivy component, only available when `certSource` is `secret`. The secret must contain keys named: `ca.crt` - the CA certificate which is used to issue internal key and crt pair for components and all Harbor components must be issued by the same CA, `tls.crt` - the content of the TLS cert file, `tls.key` - the content of the TLS key file. | | +| `internalTLS.trivy.crt` | Content of trivy's TLS cert file, only available when `certSource` is `manual` | | +| `internalTLS.trivy.key` | Content of trivy's TLS key file, only available when `certSource` is `manual` | | +| **IPFamily** | | | +| `ipFamily.ipv4.enabled` | if cluster is ipv4 enabled, all ipv4 related configs will set correspondingly, but currently it only affects the nginx related components | `true` | +| `ipFamily.ipv6.enabled` | if cluster is ipv6 enabled, all ipv6 related configs will set correspondingly, but currently it only affects the nginx related components | `true` | +| **Persistence** | | | +| `persistence.enabled` | Enable the data persistence or not | `true` | +| `persistence.resourcePolicy` | Setting it to `keep` to avoid removing PVCs during a helm delete operation. Leaving it empty will delete PVCs after the chart deleted. Does not affect PVCs created for internal database and redis components. | `keep` | +| `persistence.persistentVolumeClaim.registry.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components | | +| `persistence.persistentVolumeClaim.registry.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.registry.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.registry.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.registry.size` | The size of the volume | `5Gi` | +| `persistence.persistentVolumeClaim.registry.annotations` | The annotations of the volume | | +|`persistence.persistentVolumeClaim.jobservice.jobLog.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.jobservice.jobLog.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.jobservice.jobLog.size` | The size of the volume | `1Gi` | +| `persistence.persistentVolumeClaim.jobservice.jobLog.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.database.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.subPath` | The sub path used in the volume. If external database is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.database.accessMode` | The access mode of the volume. If external database is used, the setting will be ignored | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.database.size` | The size of the volume. If external database is used, the setting will be ignored | `1Gi` | +| `persistence.persistentVolumeClaim.database.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.redis.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.subPath` | The sub path used in the volume. If external Redis is used, the setting will be ignored | | +| `persistence.persistentVolumeClaim.redis.accessMode` | The access mode of the volume. If external Redis is used, the setting will be ignored | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.redis.size` | The size of the volume. If external Redis is used, the setting will be ignored | `1Gi` | +| `persistence.persistentVolumeClaim.redis.annotations` | The annotations of the volume | | +| `persistence.persistentVolumeClaim.trivy.existingClaim` | Use the existing PVC which must be created manually before bound, and specify the `subPath` if the PVC is shared with other components | | +| `persistence.persistentVolumeClaim.trivy.storageClass` | Specify the `storageClass` used to provision the volume. Or the default StorageClass will be used (the default). Set it to `-` to disable dynamic provisioning | | +| `persistence.persistentVolumeClaim.trivy.subPath` | The sub path used in the volume | | +| `persistence.persistentVolumeClaim.trivy.accessMode` | The access mode of the volume | `ReadWriteOnce` | +| `persistence.persistentVolumeClaim.trivy.size` | The size of the volume | `1Gi` | +| `persistence.persistentVolumeClaim.trivy.annotations` | The annotations of the volume | | +| `persistence.imageChartStorage.disableredirect` | The configuration for managing redirects from content backends. For backends which not supported it (such as using minio for `s3` storage type), please set it to `true` to disable redirects. Refer to the [guide](https://github.com/docker/distribution/blob/master/docs/configuration.md#redirect) for more details | `false` | +| `persistence.imageChartStorage.caBundleSecretName` | Specify the `caBundleSecretName` if the storage service uses a self-signed certificate. The secret must contain keys named `ca.crt` which will be injected into the trust store of registry's and containers. | | +| `persistence.imageChartStorage.type` | The type of storage for images and charts: `filesystem`, `azure`, `gcs`, `s3`, `swift` or `oss`. The type must be `filesystem` if you want to use persistent volumes for registry. Refer to the [guide](https://github.com/docker/distribution/blob/master/docs/configuration.md#storage) for more details | `filesystem` | +| `persistence.imageChartStorage.gcs.existingSecret` | An existing secret containing the gcs service account json key. The key must be gcs-key.json. | `""` | +| `persistence.imageChartStorage.gcs.useWorkloadIdentity` | A boolean to allow the use of workloadidentity in a GKE cluster. To use it, create a kubernetes service account and set the name in the key `serviceAccountName` of each component, then allow automounting the service account. | `false` | +| **General** | | | +| `externalURL` | The external URL for Harbor core service | `https://core.harbor.domain` | +| `caBundleSecretName` | The custom CA bundle secret name, the secret must contain key named "ca.crt" which will be injected into the trust store for core, jobservice, registry, trivy components. | | +| `uaaSecretName` | If using external UAA auth which has a self signed cert, you can provide a pre-created secret containing it under the key `ca.crt`. | | +| `imagePullPolicy` | The image pull policy | | +| `imagePullSecrets` | The imagePullSecrets names for all deployments | | +| `updateStrategy.type` | The update strategy for deployments with persistent volumes(jobservice, registry): `RollingUpdate` or `Recreate`. Set it as `Recreate` when `RWM` for volumes isn't supported | `RollingUpdate` | +| `logLevel` | The log level: `debug`, `info`, `warning`, `error` or `fatal` | `info` | +| `harborAdminPassword` | The initial password of Harbor admin. Change it from portal after launching Harbor | `Harbor12345` | +| `existingSecretAdminPassword` | The name of secret where admin password can be found. | | +| `existingSecretAdminPasswordKey` | The name of the key in the secret where to find harbor admin password Harbor | `HARBOR_ADMIN_PASSWORD` | +| `caSecretName` | The name of the secret which contains key named `ca.crt`. Setting this enables the download link on portal to download the CA certificate when the certificate isn't generated automatically | | +| `secretKey` | The key used for encryption. Must be a string of 16 chars | `not-a-secure-key` | +| `existingSecretSecretKey` | An existing secret containing the encoding secretKey | `""` | +| `proxy.httpProxy` | The URL of the HTTP proxy server | | +| `proxy.httpsProxy` | The URL of the HTTPS proxy server | | +| `proxy.noProxy` | The URLs that the proxy settings not apply to | 127.0.0.1,localhost,.local,.internal | +| `proxy.components` | The component list that the proxy settings apply to | core, jobservice, trivy | +| `enableMigrateHelmHook` | Run the migration job via helm hook, if it is true, the database migration will be separated from harbor-core, run with a preupgrade job migration-job | `false` | +| **Nginx** (if service exposed via `ingress`, Nginx will not be used) | | | +| `nginx.image.repository` | Image repository | `goharbor/nginx-photon` | +| `nginx.image.tag` | Image tag | `dev` | +| `nginx.replicas` | The replica count | `1` | +| `nginx.revisionHistoryLimit` | The revision history limit | `10` | +| `nginx.resources` | The [resources] to allocate for container | undefined | +| `nginx.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `nginx.nodeSelector` | Node labels for pod assignment | `{}` | +| `nginx.tolerations` | Tolerations for pod assignment | `[]` | +| `nginx.affinity` | Node/Pod affinities | `{}` | +| `nginx.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `nginx.podAnnotations` | Annotations to add to the nginx pod | `{}` | +| `nginx.priorityClassName` | The priority class to run the pod as | | +| **Portal** | | | +| `portal.image.repository` | Repository for portal image | `goharbor/harbor-portal` | +| `portal.image.tag` | Tag for portal image | `dev` | +| `portal.replicas` | The replica count | `1` | +| `portal.revisionHistoryLimit` | The revision history limit | `10` | +| `portal.resources` | The [resources] to allocate for container | undefined | +| `portal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `portal.nodeSelector` | Node labels for pod assignment | `{}` | +| `portal.tolerations` | Tolerations for pod assignment | `[]` | +| `portal.affinity` | Node/Pod affinities | `{}` | +| `portal.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `portal.podAnnotations` | Annotations to add to the portal pod | `{}` | +| `portal.priorityClassName` | The priority class to run the pod as | | +| **Core** | | | +| `core.image.repository` | Repository for Harbor core image | `goharbor/harbor-core` | +| `core.image.tag` | Tag for Harbor core image | `dev` | +| `core.replicas` | The replica count | `1` | +| `core.revisionHistoryLimit` | The revision history limit | `10` | +| `core.startupProbe.initialDelaySeconds` | The initial delay in seconds for the startup probe | `10` | +| `core.resources` | The [resources] to allocate for container | undefined | +| `core.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `core.nodeSelector` | Node labels for pod assignment | `{}` | +| `core.tolerations` | Tolerations for pod assignment | `[]` | +| `core.affinity` | Node/Pod affinities | `{}` | +| `core.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `core.podAnnotations` | Annotations to add to the core pod | `{}` | +| `core.serviceAnnotations` | Annotations to add to the core service | `{}` | +| `core.configureUserSettings` | A JSON string to set in the environment variable `CONFIG_OVERWRITE_JSON` to configure user settings. See the [official docs](https://goharbor.io/docs/latest/install-config/configure-user-settings-cli/#configure-users-settings-using-an-environment-variable). | | +| `core.quotaUpdateProvider` | The provider for updating project quota(usage), there are 2 options, redis or db. By default it is implemented by db but you can configure it to redis which can improve the performance of high concurrent pushing to the same project, and reduce the database connections spike and occupies. Using redis will bring up some delay for quota usage updation for display, so only suggest switch provider to redis if you were ran into the db connections spike around the scenario of high concurrent pushing to same project, no improvment for other scenes. | `db` | +| `core.secret` | Secret is used when core server communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| `core.secretName` | Fill the name of a kubernetes secret if you want to use your own TLS certificate and private key for token encryption/decryption. The secret must contain keys named: `tls.crt` - the certificate and `tls.key` - the private key. The default key pair will be used if it isn't set | | +| `core.tokenKey` | PEM-formatted RSA private key used to sign service tokens. Only used if `core.secretName` is unset. If set, `core.tokenCert` MUST also be set. | | +| `core.tokenCert` | PEM-formatted certificate signed by `core.tokenKey` used to validate service tokens. Only used if `core.secretName` is unset. If set, `core.tokenKey` MUST also be set. | | +| `core.xsrfKey` | The XSRF key. Will be generated automatically if it isn't specified | | +| `core.priorityClassName` | The priority class to run the pod as | | +| `core.artifactPullAsyncFlushDuration` | The time duration for async update artifact pull_time and repository pull_count | | +| `core.gdpr.deleteUser` | Enable GDPR compliant user delete | `false` | +| **Jobservice** | | | +| `jobservice.image.repository` | Repository for jobservice image | `goharbor/harbor-jobservice` | +| `jobservice.image.tag` | Tag for jobservice image | `dev` | +| `jobservice.replicas` | The replica count | `1` | +| `jobservice.revisionHistoryLimit` | The revision history limit | `10` | +| `jobservice.maxJobWorkers` | The max job workers | `10` | +| `jobservice.jobLoggers` | The loggers for jobs: `file`, `database` or `stdout` | `[file]` | +| `jobservice.loggerSweeperDuration` | The jobLogger sweeper duration in days (ignored if `jobLoggers` is set to `stdout`) | `14` | +| `jobservice.notification.webhook_job_max_retry` | The maximum retry of webhook sending notifications | `3` | +| `jobservice.notification.webhook_job_http_client_timeout` | The http client timeout value of webhook sending notifications | `3` | +| `jobservice.reaper.max_update_hours` | the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 | `24` | +| `jobservice.reaper.max_dangling_hours` | the max time for execution in running state without new task created | `168` | +| `jobservice.resources` | The [resources] to allocate for container | undefined | +| `jobservice.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `jobservice.nodeSelector` | Node labels for pod assignment | `{}` | +| `jobservice.tolerations` | Tolerations for pod assignment | `[]` | +| `jobservice.affinity` | Node/Pod affinities | `{}` | +| `jobservice.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `jobservice.podAnnotations` | Annotations to add to the jobservice pod | `{}` | +| `jobservice.priorityClassName` | The priority class to run the pod as | | +| `jobservice.secret` | Secret is used when job service communicates with other components. If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| **Registry** | | | +| `registry.registry.image.repository` | Repository for registry image | `goharbor/registry-photon` | +| `registry.registry.image.tag` | Tag for registry image | `dev` | +| `registry.registry.resources` | The [resources] to allocate for container | undefined | +| `registry.controller.image.repository` | Repository for registry controller image | `goharbor/harbor-registryctl` | +| `registry.controller.image.tag` | Tag for registry controller image | `dev` | +| `registry.controller.resources` | The [resources] to allocate for container | undefined | +| `registry.replicas` | The replica count | `1` | +| `registry.revisionHistoryLimit` | The revision history limit | `10` | +| `registry.nodeSelector` | Node labels for pod assignment | `{}` | +| `registry.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `registry.tolerations` | Tolerations for pod assignment | `[]` | +| `registry.affinity` | Node/Pod affinities | `{}` | +| `registry.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `registry.middleware` | Middleware is used to add support for a CDN between backend storage and `docker pull` recipient. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#middleware). | | +| `registry.podAnnotations` | Annotations to add to the registry pod | `{}` | +| `registry.priorityClassName` | The priority class to run the pod as | | +| `registry.secret` | Secret is used to secure the upload state from client and registry storage backend. See [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#http). If a secret key is not specified, Helm will generate one. Must be a string of 16 chars. | | +| `registry.credentials.username` | The username that harbor core uses internally to access the registry instance. Together with the `registry.credentials.password`, a htpasswd  is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). | `harbor_registry_user` | +| `registry.credentials.password` | The password that harbor core uses internally to access the registry instance. Together with the `registry.credentials.username`, a htpasswd  is created. This is an alternative to providing `registry.credentials.htpasswdString`. For more details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). It is suggested you update this value before installation. | `harbor_registry_password` | +| `registry.credentials.existingSecret` | An existing secret containing the password for accessing the registry instance, which is hosted by htpasswd auth mode. More details see [official docs](https://github.com/docker/distribution/blob/master/docs/configuration.md#htpasswd). The key must be `REGISTRY_PASSWD` | `""` | +| `registry.credentials.htpasswdString` | Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.credentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which generates different lines each time because of the salt. | undefined | +| `registry.relativeurls` | If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. Needed if harbor is behind a reverse proxy | `false` | +| `registry.upload_purging.enabled` | If true, enable purge _upload directories | `true` | +| `registry.upload_purging.age` | Remove files in _upload directories which exist for a period of time, default is one week. | `168h` | +| `registry.upload_purging.interval` | The interval of the purge operations | `24h` | +| `registry.upload_purging.dryrun` | If true, enable dryrun for purging _upload, default false | `false` | +| **[Trivy][trivy]** | | | +| `trivy.enabled` | The flag to enable Trivy scanner | `true` | +| `trivy.image.repository` | Repository for Trivy adapter image | `goharbor/trivy-adapter-photon` | +| `trivy.image.tag` | Tag for Trivy adapter image | `dev` | +| `trivy.resources` | The [resources] to allocate for Trivy adapter container | | +| `trivy.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `trivy.replicas` | The number of Pod replicas | `1` | +| `trivy.debugMode` | The flag to enable Trivy debug mode | `false` | +| `trivy.vulnType` | Comma-separated list of vulnerability types. Possible values `os` and `library`. | `os,library` | +| `trivy.severity` | Comma-separated list of severities to be checked | `UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL` | +| `trivy.ignoreUnfixed` | The flag to display only fixed vulnerabilities | `false` | +| `trivy.insecure` | The flag to skip verifying registry certificate | `false` | +| `trivy.skipUpdate` | The flag to disable [Trivy DB][trivy-db] downloads from GitHub | `false` | +| `trivy.offlineScan` | The flag prevents Trivy from sending API requests to identify dependencies. | `false` | +| `trivy.securityCheck` | Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. | `vuln` | +| `trivy.timeout` | The duration to wait for scan completion | `5m0s` | +| `trivy.gitHubToken` | The GitHub access token to download [Trivy DB][trivy-db] (see [GitHub rate limiting][trivy-rate-limiting]) | | +| `trivy.priorityClassName` | The priority class to run the pod as | | +| `trivy.topologySpreadConstraints` | The priority class to run the pod as | | +| **Database** | | | +| `database.type` | If external database is used, set it to `external` | `internal` | +| `database.internal.image.repository` | Repository for database image | `goharbor/harbor-db` | +| `database.internal.image.tag` | Tag for database image | `dev` | +| `database.internal.password` | The password for database | `changeit` | +| `database.internal.shmSizeLimit` | The limit for the size of shared memory for internal PostgreSQL, conventionally it's around 50% of the memory limit of the container | `512Mi` | +| `database.internal.resources` | The [resources] to allocate for container | undefined | +| `database.internal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `database.internal.initContainer.migrator.resources` | The [resources] to allocate for the database migrator initContainer | undefined | +| `database.internal.initContainer.permissions.resources` | The [resources] to allocate for the database permissions initContainer | undefined | +| `database.internal.nodeSelector` | Node labels for pod assignment | `{}` | +| `database.internal.tolerations` | Tolerations for pod assignment | `[]` | +| `database.internal.affinity` | Node/Pod affinities | `{}` | +| `database.internal.priorityClassName` | The priority class to run the pod as | | +| `database.internal.livenessProbe.timeoutSeconds` | The timeout used in liveness probe; 1 to 5 seconds | 1 | +| `database.internal.readinessProbe.timeoutSeconds` | The timeout used in readiness probe; 1 to 5 seconds | 1 | +| `database.external.host` | The hostname of external database | `192.168.0.1` | +| `database.external.port` | The port of external database | `5432` | +| `database.external.username` | The username of external database | `user` | +| `database.external.password` | The password of external database | `password` | +| `database.external.coreDatabase` | The database used by core service | `registry` | +| `database.external.existingSecret` | An existing password containing the database password. the key must be `password`. | `""` | +| `database.external.sslmode` | Connection method of external database (require, verify-full, verify-ca, disable) | `disable` | +| `database.maxIdleConns` | The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained. | `50` | +| `database.maxOpenConns` | The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections. | `100` | +| `database.podAnnotations` | Annotations to add to the database pod | `{}` | +| **Redis** | | | +| `redis.type` | If external redis is used, set it to `external` | `internal` | +| `redis.internal.image.repository` | Repository for redis image | `goharbor/redis-photon` | +| `redis.internal.image.tag` | Tag for redis image | `dev` | +| `redis.internal.resources` | The [resources] to allocate for container | undefined | +| `redis.internal.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `redis.internal.nodeSelector` | Node labels for pod assignment | `{}` | +| `redis.internal.tolerations` | Tolerations for pod assignment | `[]` | +| `redis.internal.affinity` | Node/Pod affinities | `{}` | +| `redis.internal.priorityClassName` | The priority class to run the pod as | | +| `redis.internal.jobserviceDatabaseIndex` | The database index for jobservice | `1` | +| `redis.internal.registryDatabaseIndex` | The database index for registry | `2` | +| `redis.internal.trivyAdapterIndex` | The database index for trivy adapter | `5` | +| `redis.internal.harborDatabaseIndex` | The database index for harbor miscellaneous business logic | `0` | +| `redis.internal.cacheLayerDatabaseIndex` | The database index for harbor cache layer | `0` | +| `redis.external.addr` | The addr of external Redis: :. When using sentinel, it should be :,:,: | `192.168.0.2:6379` | +| `redis.external.sentinelMasterSet` | The name of the set of Redis instances to monitor | | +| `redis.external.coreDatabaseIndex` | The database index for core | `0` | +| `redis.external.jobserviceDatabaseIndex` | The database index for jobservice | `1` | +| `redis.external.registryDatabaseIndex` | The database index for registry | `2` | +| `redis.external.trivyAdapterIndex` | The database index for trivy adapter | `5` | +| `redis.external.harborDatabaseIndex` | The database index for harbor miscellaneous business logic | `0` | +| `redis.external.cacheLayerDatabaseIndex` | The database index for harbor cache layer | `0` | +| `redis.external.username` | The username of external Redis | | +| `redis.external.password` | The password of external Redis | | +| `redis.external.existingSecret` | Use an existing secret to connect to redis. The key must be `REDIS_PASSWORD`. | `""` | +| `redis.podAnnotations` | Annotations to add to the redis pod | `{}` | +| **Exporter** | | | +| `exporter.replicas` | The replica count | `1` | +| `exporter.revisionHistoryLimit` | The revision history limit | `10` | +| `exporter.podAnnotations` | Annotations to add to the exporter pod | `{}` | +| `exporter.image.repository` | Repository for redis image | `goharbor/harbor-exporter` | +| `exporter.image.tag` | Tag for exporter image | `dev` | +| `exporter.nodeSelector` | Node labels for pod assignment | `{}` | +| `exporter.tolerations` | Tolerations for pod assignment | `[]` | +| `exporter.affinity` | Node/Pod affinities | `{}` | +| `exporter.topologySpreadConstraints` | Constraints that define how Pods are spread across failure-domains like regions or availability zones | `[]` | +| `exporter.automountServiceAccountToken` | Mount serviceAccountToken? | `false` | +| `exporter.cacheDuration` | the cache duration for information that exporter collected from Harbor | `30` | +| `exporter.cacheCleanInterval` | cache clean interval for information that exporter collected from Harbor | `14400` | +| `exporter.priorityClassName` | The priority class to run the pod as | | +| **Metrics** | | | +| `metrics.enabled` | if enable harbor metrics | `false` | +| `metrics.core.path` | the url path for core metrics | `/metrics` | +| `metrics.core.port` | the port for core metrics | `8001` | +| `metrics.registry.path` | the url path for registry metrics | `/metrics` | +| `metrics.registry.port` | the port for registry metrics | `8001` | +| `metrics.exporter.path` | the url path for exporter metrics | `/metrics` | +| `metrics.exporter.port` | the port for exporter metrics | `8001` | +| `metrics.serviceMonitor.enabled` | create prometheus serviceMonitor. Requires prometheus CRD's | `false` | +| `metrics.serviceMonitor.additionalLabels` | additional labels to upsert to the manifest | `""` | +| `metrics.serviceMonitor.interval` | scrape period for harbor metrics | `""` | +| `metrics.serviceMonitor.metricRelabelings` | metrics relabel to add/mod/del before ingestion | `[]` | +| `metrics.serviceMonitor.relabelings` | relabels to add/mod/del to sample before scrape | `[]` | +| **Trace** | | | +| `trace.enabled` | Enable tracing or not | `false` | +| `trace.provider` | The tracing provider: `jaeger` or `otel`. `jaeger` should be 1.26+ | `jaeger` | +| `trace.sample_rate` | Set `sample_rate` to 1 if you want sampling 100% of trace data; set 0.5 if you want sampling 50% of trace data, and so forth | `1` | +| `trace.namespace` | Namespace used to differentiate different harbor services | | +| `trace.attributes` | `attributes` is a key value dict contains user defined attributes used to initialize trace provider | | +| `trace.jaeger.endpoint` | The endpoint of jaeger | `http://hostname:14268/api/traces` | +| `trace.jaeger.username` | The username of jaeger | | +| `trace.jaeger.password` | The password of jaeger | | +| `trace.jaeger.agent_host` | The agent host of jaeger | | +| `trace.jaeger.agent_port` | The agent port of jaeger | `6831` | +| `trace.otel.endpoint` | The endpoint of otel | `hostname:4318` | +| `trace.otel.url_path` | The URL path of otel | `/v1/traces` | +| `trace.otel.compression` | Whether enable compression or not for otel | `false` | +| `trace.otel.insecure` | Whether establish insecure connection or not for otel | `true` | +| `trace.otel.timeout` | The timeout in seconds of otel | `10` | +| **Cache** | | | +| `cache.enabled` | Enable cache layer or not | `false` | +| `cache.expireHours` | The expire hours of cache layer | `24` | + +[resources]: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +[trivy]: https://github.com/aquasecurity/trivy +[trivy-db]: https://github.com/aquasecurity/trivy-db +[trivy-rate-limiting]: https://github.com/aquasecurity/trivy#github-rate-limiting diff --git a/helm-charts/harbor/templates/NOTES.txt b/helm-charts/harbor/templates/NOTES.txt new file mode 100644 index 0000000..0980c08 --- /dev/null +++ b/helm-charts/harbor/templates/NOTES.txt @@ -0,0 +1,3 @@ +Please wait for several minutes for Harbor deployment to complete. +Then you should be able to visit the Harbor portal at {{ .Values.externalURL }} +For more details, please visit https://github.com/goharbor/harbor diff --git a/helm-charts/harbor/templates/_helpers.tpl b/helm-charts/harbor/templates/_helpers.tpl new file mode 100644 index 0000000..6ee24fe --- /dev/null +++ b/helm-charts/harbor/templates/_helpers.tpl @@ -0,0 +1,554 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "harbor.name" -}} +{{- default "harbor" .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "harbor.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default "harbor" .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* Helm required labels */}} +{{- define "harbor.labels" -}} +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +chart: {{ .Chart.Name }} +app: "{{ template "harbor.name" . }}" +{{- end -}} + +{{/* matchLabels */}} +{{- define "harbor.matchLabels" -}} +release: {{ .Release.Name }} +app: "{{ template "harbor.name" . }}" +{{- end -}} + +{{- define "harbor.autoGenCert" -}} + {{- if and .Values.expose.tls.enabled (eq .Values.expose.tls.certSource "auto") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.autoGenCertForIngress" -}} + {{- if and (eq (include "harbor.autoGenCert" .) "true") (eq .Values.expose.type "ingress") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.autoGenCertForNginx" -}} + {{- if and (eq (include "harbor.autoGenCert" .) "true") (ne .Values.expose.type "ingress") -}} + {{- printf "true" -}} + {{- else -}} + {{- printf "false" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.host" -}} + {{- if eq .Values.database.type "internal" -}} + {{- template "harbor.database" . }} + {{- else -}} + {{- .Values.database.external.host -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.port" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "5432" -}} + {{- else -}} + {{- .Values.database.external.port -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.username" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "postgres" -}} + {{- else -}} + {{- .Values.database.external.username -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.rawPassword" -}} + {{- if eq .Values.database.type "internal" -}} + {{- .Values.database.internal.password -}} + {{- else -}} + {{- .Values.database.external.password -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.escapedRawPassword" -}} + {{- include "harbor.database.rawPassword" . | urlquery | replace "+" "%20" -}} +{{- end -}} + +{{- define "harbor.database.encryptedPassword" -}} + {{- include "harbor.database.rawPassword" . | b64enc | quote -}} +{{- end -}} + +{{- define "harbor.database.coreDatabase" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "registry" -}} + {{- else -}} + {{- .Values.database.external.coreDatabase -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.database.sslmode" -}} + {{- if eq .Values.database.type "internal" -}} + {{- printf "%s" "disable" -}} + {{- else -}} + {{- .Values.database.external.sslmode -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.redis.scheme" -}} + {{- with .Values.redis }} + {{- ternary "redis+sentinel" "redis" (and (eq .type "external" ) (not (not .external.sentinelMasterSet))) }} + {{- end }} +{{- end -}} + +/*host:port*/ +{{- define "harbor.redis.addr" -}} + {{- with .Values.redis }} + {{- ternary (printf "%s:6379" (include "harbor.redis" $ )) .external.addr (eq .type "internal") }} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.masterSet" -}} + {{- with .Values.redis }} + {{- ternary .external.sentinelMasterSet "" (eq "redis+sentinel" (include "harbor.redis.scheme" $)) }} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.password" -}} + {{- with .Values.redis }} + {{- ternary "" .external.password (eq .type "internal") }} + {{- end }} +{{- end -}} + + +{{- define "harbor.redis.pwdfromsecret" -}} + {{- (lookup "v1" "Secret" .Release.Namespace (.Values.redis.external.existingSecret)).data.REDIS_PASSWORD | b64dec }} +{{- end -}} + +{{- define "harbor.redis.cred" -}} + {{- with .Values.redis }} + {{- if (and (eq .type "external" ) (.external.existingSecret)) }} + {{- printf ":%s@" (include "harbor.redis.pwdfromsecret" $) }} + {{- else }} + {{- ternary (printf "%s:%s@" (.external.username | urlquery) (.external.password | urlquery)) "" (and (eq .type "external" ) (not (not .external.password))) }} + {{- end }} + {{- end }} +{{- end -}} + +/*scheme://[:password@]host:port[/master_set]*/ +{{- define "harbor.redis.url" -}} + {{- with .Values.redis }} + {{- $path := ternary "" (printf "/%s" (include "harbor.redis.masterSet" $)) (not (include "harbor.redis.masterSet" $)) }} + {{- printf "%s://%s%s%s" (include "harbor.redis.scheme" $) (include "harbor.redis.cred" $) (include "harbor.redis.addr" $) $path -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForCore" -}} + {{- with .Values.redis }} + {{- $index := ternary "0" .external.coreDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index*/ +{{- define "harbor.redis.urlForJobservice" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.jobserviceDatabaseIndex .external.jobserviceDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForRegistry" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.registryDatabaseIndex .external.registryDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForTrivy" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.trivyAdapterIndex .external.trivyAdapterIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForHarbor" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.harborDatabaseIndex .external.harborDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +/*scheme://[:password@]addr/db_index?idle_timeout_seconds=30*/ +{{- define "harbor.redis.urlForCache" -}} + {{- with .Values.redis }} + {{- $index := ternary .internal.cacheLayerDatabaseIndex .external.cacheLayerDatabaseIndex (eq .type "internal") }} + {{- printf "%s/%s?idle_timeout_seconds=30" (include "harbor.redis.url" $) $index -}} + {{- end }} +{{- end -}} + +{{- define "harbor.redis.dbForRegistry" -}} + {{- with .Values.redis }} + {{- ternary .internal.registryDatabaseIndex .external.registryDatabaseIndex (eq .type "internal") }} + {{- end }} +{{- end -}} + +{{- define "harbor.portal" -}} + {{- printf "%s-portal" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.core" -}} + {{- printf "%s-core" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.redis" -}} + {{- printf "%s-redis" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.jobservice" -}} + {{- printf "%s-jobservice" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.registry" -}} + {{- printf "%s-registry" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.registryCtl" -}} + {{- printf "%s-registryctl" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.database" -}} + {{- printf "%s-database" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.trivy" -}} + {{- printf "%s-trivy" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.nginx" -}} + {{- printf "%s-nginx" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.exporter" -}} + {{- printf "%s-exporter" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.ingress" -}} + {{- printf "%s-ingress" (include "harbor.fullname" .) -}} +{{- end -}} + +{{- define "harbor.noProxy" -}} + {{- printf "%s,%s,%s,%s,%s,%s,%s,%s" (include "harbor.core" .) (include "harbor.jobservice" .) (include "harbor.database" .) (include "harbor.registry" .) (include "harbor.portal" .) (include "harbor.trivy" .) (include "harbor.exporter" .) .Values.proxy.noProxy -}} +{{- end -}} + +{{- define "harbor.caBundleVolume" -}} +- name: ca-bundle-certs + secret: + secretName: {{ .Values.caBundleSecretName }} +{{- end -}} + +{{- define "harbor.caBundleVolumeMount" -}} +- name: ca-bundle-certs + mountPath: /harbor_cust_cert/custom-ca.crt + subPath: ca.crt +{{- end -}} + +{{/* scheme for all components because it only support http mode */}} +{{- define "harbor.component.scheme" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "https" -}} + {{- else -}} + {{- printf "http" -}} + {{- end -}} +{{- end -}} + +{{/* core component container port */}} +{{- define "harbor.core.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* core component service port */}} +{{- define "harbor.core.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* jobservice component container port */}} +{{- define "harbor.jobservice.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* jobservice component service port */}} +{{- define "harbor.jobservice.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* portal component container port */}} +{{- define "harbor.portal.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* portal component service port */}} +{{- define "harbor.portal.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "443" -}} + {{- else -}} + {{- printf "80" -}} + {{- end -}} +{{- end -}} + +{{/* registry component container port */}} +{{- define "harbor.registry.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "5443" -}} + {{- else -}} + {{- printf "5000" -}} + {{- end -}} +{{- end -}} + +{{/* registry component service port */}} +{{- define "harbor.registry.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "5443" -}} + {{- else -}} + {{- printf "5000" -}} + {{- end -}} +{{- end -}} + +{{/* registryctl component container port */}} +{{- define "harbor.registryctl.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* registryctl component service port */}} +{{- define "harbor.registryctl.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* trivy component container port */}} +{{- define "harbor.trivy.containerPort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* trivy component service port */}} +{{- define "harbor.trivy.servicePort" -}} + {{- if .Values.internalTLS.enabled -}} + {{- printf "8443" -}} + {{- else -}} + {{- printf "8080" -}} + {{- end -}} +{{- end -}} + +{{/* CORE_URL */}} +{{/* port is included in this url as a workaround for issue https://github.com/aquasecurity/harbor-scanner-trivy/issues/108 */}} +{{- define "harbor.coreURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.core" .) (include "harbor.core.servicePort" .) -}} +{{- end -}} + +{{/* JOBSERVICE_URL */}} +{{- define "harbor.jobserviceURL" -}} + {{- printf "%s://%s-jobservice" (include "harbor.component.scheme" .) (include "harbor.fullname" .) -}} +{{- end -}} + +{{/* PORTAL_URL */}} +{{- define "harbor.portalURL" -}} + {{- printf "%s://%s" (include "harbor.component.scheme" .) (include "harbor.portal" .) -}} +{{- end -}} + +{{/* REGISTRY_URL */}} +{{- define "harbor.registryURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registry.servicePort" .) -}} +{{- end -}} + +{{/* REGISTRY_CONTROLLER_URL */}} +{{- define "harbor.registryControllerURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.registry" .) (include "harbor.registryctl.servicePort" .) -}} +{{- end -}} + +{{/* TOKEN_SERVICE_URL */}} +{{- define "harbor.tokenServiceURL" -}} + {{- printf "%s/service/token" (include "harbor.coreURL" .) -}} +{{- end -}} + +{{/* TRIVY_ADAPTER_URL */}} +{{- define "harbor.trivyAdapterURL" -}} + {{- printf "%s://%s:%s" (include "harbor.component.scheme" .) (include "harbor.trivy" .) (include "harbor.trivy.servicePort" .) -}} +{{- end -}} + +{{- define "harbor.internalTLS.core.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.core.secretName -}} + {{- else -}} + {{- printf "%s-core-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.jobservice.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.jobservice.secretName -}} + {{- else -}} + {{- printf "%s-jobservice-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.portal.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.portal.secretName -}} + {{- else -}} + {{- printf "%s-portal-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.registry.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.registry.secretName -}} + {{- else -}} + {{- printf "%s-registry-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.internalTLS.trivy.secretName" -}} + {{- if eq .Values.internalTLS.certSource "secret" -}} + {{- .Values.internalTLS.trivy.secretName -}} + {{- else -}} + {{- printf "%s-trivy-internal-tls" (include "harbor.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.tlsCoreSecretForIngress" -}} + {{- if eq .Values.expose.tls.certSource "none" -}} + {{- printf "" -}} + {{- else if eq .Values.expose.tls.certSource "secret" -}} + {{- .Values.expose.tls.secret.secretName -}} + {{- else -}} + {{- include "harbor.ingress" . -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.tlsSecretForNginx" -}} + {{- if eq .Values.expose.tls.certSource "secret" -}} + {{- .Values.expose.tls.secret.secretName -}} + {{- else -}} + {{- include "harbor.nginx" . -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.metricsPortName" -}} + {{- if .Values.internalTLS.enabled }} + {{- printf "https-metrics" -}} + {{- else -}} + {{- printf "http-metrics" -}} + {{- end -}} +{{- end -}} + +{{- define "harbor.traceEnvs" -}} + TRACE_ENABLED: "{{ .Values.trace.enabled }}" + TRACE_SAMPLE_RATE: "{{ .Values.trace.sample_rate }}" + TRACE_NAMESPACE: "{{ .Values.trace.namespace }}" + {{- if .Values.trace.attributes }} + TRACE_ATTRIBUTES: {{ .Values.trace.attributes | toJson | squote }} + {{- end }} + {{- if eq .Values.trace.provider "jaeger" }} + TRACE_JAEGER_ENDPOINT: "{{ .Values.trace.jaeger.endpoint }}" + TRACE_JAEGER_USERNAME: "{{ .Values.trace.jaeger.username }}" + TRACE_JAEGER_AGENT_HOSTNAME: "{{ .Values.trace.jaeger.agent_host }}" + TRACE_JAEGER_AGENT_PORT: "{{ .Values.trace.jaeger.agent_port }}" + {{- else }} + TRACE_OTEL_ENDPOINT: "{{ .Values.trace.otel.endpoint }}" + TRACE_OTEL_URL_PATH: "{{ .Values.trace.otel.url_path }}" + TRACE_OTEL_COMPRESSION: "{{ .Values.trace.otel.compression }}" + TRACE_OTEL_INSECURE: "{{ .Values.trace.otel.insecure }}" + TRACE_OTEL_TIMEOUT: "{{ .Values.trace.otel.timeout }}" + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForCore" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-core" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForJobservice" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-jobservice" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceEnvsForRegistryCtl" -}} + {{- if .Values.trace.enabled }} + TRACE_SERVICE_NAME: "harbor-registryctl" + {{ include "harbor.traceEnvs" . }} + {{- end }} +{{- end -}} + +{{- define "harbor.traceJaegerPassword" -}} + {{- if and .Values.trace.enabled (eq .Values.trace.provider "jaeger") }} + TRACE_JAEGER_PASSWORD: "{{ .Values.trace.jaeger.password | default "" | b64enc }}" + {{- end }} +{{- end -}} + +{{/* Allow KubeVersion to be overridden. */}} +{{- define "harbor.ingress.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.expose.ingress.kubeVersionOverride -}} +{{- end -}} \ No newline at end of file diff --git a/helm-charts/harbor/templates/core/core-cm.yaml b/helm-charts/harbor/templates/core/core-cm.yaml new file mode 100644 index 0000000..7d284c8 --- /dev/null +++ b/helm-charts/harbor/templates/core/core-cm.yaml @@ -0,0 +1,87 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + app.conf: |+ + appname = Harbor + runmode = prod + enablegzip = true + + [prod] + httpport = {{ ternary "8443" "8080" .Values.internalTLS.enabled }} + PORT: "{{ ternary "8443" "8080" .Values.internalTLS.enabled }}" + DATABASE_TYPE: "postgresql" + POSTGRESQL_HOST: "{{ template "harbor.database.host" . }}" + POSTGRESQL_PORT: "{{ template "harbor.database.port" . }}" + POSTGRESQL_USERNAME: "{{ template "harbor.database.username" . }}" + POSTGRESQL_DATABASE: "{{ template "harbor.database.coreDatabase" . }}" + POSTGRESQL_SSLMODE: "{{ template "harbor.database.sslmode" . }}" + POSTGRESQL_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}" + POSTGRESQL_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}" + EXT_ENDPOINT: "{{ .Values.externalURL }}" + CORE_URL: "{{ template "harbor.coreURL" . }}" + JOBSERVICE_URL: "{{ template "harbor.jobserviceURL" . }}" + REGISTRY_URL: "{{ template "harbor.registryURL" . }}" + TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" + CORE_LOCAL_URL: "{{ ternary "https://127.0.0.1:8443" "http://127.0.0.1:8080" .Values.internalTLS.enabled }}" + WITH_TRIVY: {{ .Values.trivy.enabled | quote }} + TRIVY_ADAPTER_URL: "{{ template "harbor.trivyAdapterURL" . }}" + REGISTRY_STORAGE_PROVIDER_NAME: "{{ .Values.persistence.imageChartStorage.type }}" + LOG_LEVEL: "{{ .Values.logLevel }}" + CONFIG_PATH: "/etc/core/app.conf" + CHART_CACHE_DRIVER: "redis" + _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}" + _REDIS_URL_REG: "{{ template "harbor.redis.urlForRegistry" . }}" + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.harborDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.harborDatabaseIndex) }} + _REDIS_URL_HARBOR: "{{ template "harbor.redis.urlForHarbor" . }}" + {{- end }} + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.cacheLayerDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.cacheLayerDatabaseIndex) }} + _REDIS_URL_CACHE_LAYER: "{{ template "harbor.redis.urlForCache" . }}" + {{- end }} + PORTAL_URL: "{{ template "harbor.portalURL" . }}" + REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" + REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" + {{- if .Values.uaaSecretName }} + UAA_CA_ROOT: "/etc/core/auth-ca/auth-ca.crt" + {{- end }} + {{- if has "core" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE: "docker-hub,harbor,azure-acr,aws-ecr,google-gcr,quay,docker-registry,github-ghcr,jfrog-artifactory" + {{- if .Values.metrics.enabled}} + METRIC_ENABLE: "true" + METRIC_PATH: "{{ .Values.metrics.core.path }}" + METRIC_PORT: "{{ .Values.metrics.core.port }}" + METRIC_NAMESPACE: harbor + METRIC_SUBSYSTEM: core + {{- end }} + + {{- if hasKey .Values.core "gcTimeWindowHours" }} + #make the GC time window configurable for testing + GC_TIME_WINDOW_HOURS: "{{ .Values.core.gcTimeWindowHours }}" + {{- end }} + {{- template "harbor.traceEnvsForCore" . }} + + {{- if .Values.core.artifactPullAsyncFlushDuration | quote }} + ARTIFACT_PULL_ASYNC_FLUSH_DURATION: {{ .Values.core.artifactPullAsyncFlushDuration }} + {{- end }} + + {{- if .Values.core.gdpr}} + {{- if .Values.core.gdpr.deleteUser}} + GDPR_DELETE_USER: "true" + {{- end }} + {{- end }} + + {{- if .Values.cache.enabled }} + CACHE_ENABLED: "true" + CACHE_EXPIRE_HOURS: "{{ .Values.cache.expireHours }}" + {{- end }} + + {{- if .Values.core.quotaUpdateProvider }} + QUOTA_UPDATE_PROVIDER: "{{ .Values.core.quotaUpdateProvider }}" + {{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/core/core-dpl.yaml b/helm-charts/harbor/templates/core/core-dpl.yaml new file mode 100644 index 0000000..8d20249 --- /dev/null +++ b/helm-charts/harbor/templates/core/core-dpl.yaml @@ -0,0 +1,237 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: core +spec: + replicas: {{ .Values.core.replicas }} + revisionHistoryLimit: {{ .Values.core.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: core + template: + metadata: + labels: +{{ include "harbor.matchLabels" . | indent 8 }} + component: core +{{- if .Values.core.podLabels }} +{{ toYaml .Values.core.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/core/core-cm.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} + checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.core.podAnnotations }} +{{ toYaml .Values.core.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.core.serviceAccountName }} + serviceAccountName: {{ .Values.core.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.core.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.core.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: core +{{- end }} +{{- end }} + containers: + - name: core + image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + {{- if .Values.core.startupProbe.enabled }} + startupProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 360 + initialDelaySeconds: {{ .Values.core.startupProbe.initialDelaySeconds }} + periodSeconds: 10 + {{- end }} + livenessProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 2 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/v2.0/ping + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.core.containerPort" . }} + failureThreshold: 2 + periodSeconds: 10 + envFrom: + - configMapRef: + name: "{{ template "harbor.core" . }}" + - secretRef: + name: "{{ template "harbor.core" . }}" + env: + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "harbor.core" . }} + key: secret + - name: JOBSERVICE_SECRET + valueFrom: + secretKeyRef: + name: "{{ template "harbor.jobservice" . }}" + key: JOBSERVICE_SECRET + {{- if .Values.existingSecretAdminPassword }} + - name: HARBOR_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.existingSecretAdminPassword }} + key: {{ .Values.existingSecretAdminPasswordKey }} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/core/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/core/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/core/ca.crt + {{- end }} + {{- if .Values.database.external.existingSecret }} + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + {{- if .Values.registry.credentials.existingSecret }} + - name: REGISTRY_CREDENTIAL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.registry.credentials.existingSecret }} + key: REGISTRY_PASSWD + {{- end }} +{{- with .Values.core.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.core.containerPort" . }} + volumeMounts: + - name: config + mountPath: /etc/core/app.conf + subPath: app.conf + - name: secret-key + mountPath: /etc/core/key + subPath: key + - name: token-service-private-key + mountPath: /etc/core/private_key.pem + subPath: tls.key + {{- if .Values.expose.tls.enabled }} + - name: ca-download + mountPath: /etc/core/ca + {{- end }} + {{- if .Values.uaaSecretName }} + - name: auth-ca-cert + mountPath: /etc/core/auth-ca/auth-ca.crt + subPath: auth-ca.crt + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + mountPath: /etc/harbor/ssl/core + {{- end }} + - name: psc + mountPath: /etc/core/token + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} +{{- if .Values.core.resources }} + resources: +{{ toYaml .Values.core.resources | indent 10 }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ template "harbor.core" . }} + items: + - key: app.conf + path: app.conf + - name: secret-key + secret: + {{- if .Values.existingSecretSecretKey }} + secretName: {{ .Values.existingSecretSecretKey }} + {{- else }} + secretName: {{ template "harbor.core" . }} + {{- end }} + items: + - key: secretKey + path: key + - name: token-service-private-key + secret: + {{- if .Values.core.secretName }} + secretName: {{ .Values.core.secretName }} + {{- else }} + secretName: {{ template "harbor.core" . }} + {{- end }} + {{- if .Values.expose.tls.enabled }} + - name: ca-download + secret: + {{- if .Values.caSecretName }} + secretName: {{ .Values.caSecretName }} + {{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }} + secretName: "{{ template "harbor.ingress" . }}" + {{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }} + secretName: {{ template "harbor.tlsSecretForNginx" . }} + {{- end }} + {{- end }} + {{- if .Values.uaaSecretName }} + - name: auth-ca-cert + secret: + secretName: {{ .Values.uaaSecretName }} + items: + - key: ca.crt + path: auth-ca.crt + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.core.secretName" . }} + {{- end }} + - name: psc + emptyDir: {} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.core.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.core.priorityClassName }} + priorityClassName: {{ .Values.core.priorityClassName }} + {{- end }} diff --git a/helm-charts/harbor/templates/core/core-pre-upgrade-job.yaml b/helm-charts/harbor/templates/core/core-pre-upgrade-job.yaml new file mode 100644 index 0000000..43c9d35 --- /dev/null +++ b/helm-charts/harbor/templates/core/core-pre-upgrade-job.yaml @@ -0,0 +1,74 @@ +{{- if .Values.enableMigrateHelmHook }} +apiVersion: batch/v1 +kind: Job +metadata: + name: migration-job + labels: +{{ include "harbor.labels" . | indent 4 }} + component: migrator + annotations: + # This is what defines this resource as a hook. Without this line, the + # job is considered part of the release. + "helm.sh/hook": pre-upgrade + "helm.sh/hook-weight": "-5" +spec: + template: + metadata: + labels: +{{ include "harbor.matchLabels" . | indent 8 }} + component: migrator + spec: + restartPolicy: Never + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.core.serviceAccountName }} + serviceAccountName: {{ .Values.core.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 120 + containers: + - name: core-job + image: {{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/harbor/harbor_core", "-mode=migrate"] + envFrom: + - configMapRef: + name: "{{ template "harbor.core" . }}" + - secretRef: + name: "{{ template "harbor.core" . }}" + {{- if .Values.database.external.existingSecret }} + env: + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/core/app.conf + subPath: app.conf + volumes: + - name: config + configMap: + name: {{ template "harbor.core" . }} + items: + - key: app.conf + path: app.conf + {{- with .Values.core.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.core.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/core/core-secret.yaml b/helm-charts/harbor/templates/core/core-secret.yaml new file mode 100644 index 0000000..23b352b --- /dev/null +++ b/helm-charts/harbor/templates/core/core-secret.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if not .Values.existingSecretSecretKey }} + secretKey: {{ .Values.secretKey | b64enc | quote }} + {{- end }} + secret: {{ .Values.core.secret | default (randAlphaNum 16) | b64enc | quote }} + {{- if not .Values.core.secretName }} + {{- $ca := genCA "harbor-token-ca" 365 }} + tls.key: {{ .Values.core.tokenKey | default $ca.Key | b64enc | quote }} + tls.crt: {{ .Values.core.tokenCert | default $ca.Cert | b64enc | quote }} + {{- end }} + {{- if not .Values.existingSecretAdminPassword }} + HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} + {{- end }} + {{- if not .Values.database.external.existingSecret }} + POSTGRESQL_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} + {{- end }} + {{- if not .Values.registry.credentials.existingSecret }} + REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} + {{- end }} + CSRF_KEY: {{ .Values.core.xsrfKey | default (randAlphaNum 32) | b64enc | quote }} +{{- if .Values.core.configureUserSettings }} + CONFIG_OVERWRITE_JSON: {{ .Values.core.configureUserSettings | b64enc | quote }} +{{- end }} + {{- template "harbor.traceJaegerPassword" . }} diff --git a/helm-charts/harbor/templates/core/core-svc.yaml b/helm-charts/harbor/templates/core/core-svc.yaml new file mode 100644 index 0000000..0d2cfb2 --- /dev/null +++ b/helm-charts/harbor/templates/core/core-svc.yaml @@ -0,0 +1,25 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "harbor.core" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- with .Values.core.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if or (eq .Values.expose.ingress.controller "gce") (eq .Values.expose.ingress.controller "alb") (eq .Values.expose.ingress.controller "f5-bigip") }} + type: NodePort +{{- end }} + ports: + - name: {{ ternary "https-web" "http-web" .Values.internalTLS.enabled }} + port: {{ template "harbor.core.servicePort" . }} + targetPort: {{ template "harbor.core.containerPort" . }} +{{- if .Values.metrics.enabled}} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.core.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: core diff --git a/helm-charts/harbor/templates/core/core-tls.yaml b/helm-charts/harbor/templates/core/core-tls.yaml new file mode 100644 index 0000000..c52148f --- /dev/null +++ b/helm-charts/harbor/templates/core/core-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.core.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} + tls.crt: {{ (required "The \"internalTLS.core.crt\" is required!" .Values.internalTLS.core.crt) | b64enc | quote }} + tls.key: {{ (required "The \"internalTLS.core.key\" is required!" .Values.internalTLS.core.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/database/database-secret.yaml b/helm-charts/harbor/templates/database/database-secret.yaml new file mode 100644 index 0000000..864aff4 --- /dev/null +++ b/helm-charts/harbor/templates/database/database-secret.yaml @@ -0,0 +1,11 @@ +{{- if eq .Values.database.type "internal" -}} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + POSTGRES_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} +{{- end -}} diff --git a/helm-charts/harbor/templates/database/database-ss.yaml b/helm-charts/harbor/templates/database/database-ss.yaml new file mode 100644 index 0000000..3b08b07 --- /dev/null +++ b/helm-charts/harbor/templates/database/database-ss.yaml @@ -0,0 +1,168 @@ +{{- if eq .Values.database.type "internal" -}} +{{- $database := .Values.persistence.persistentVolumeClaim.database -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: database +spec: + replicas: 1 + serviceName: "{{ template "harbor.database" . }}" + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: database + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: database +{{- if .Values.database.podLabels }} +{{ toYaml .Values.database.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/database/database-secret.yaml") . | sha256sum }} +{{- if .Values.database.podAnnotations }} +{{ toYaml .Values.database.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 999 + fsGroup: 999 +{{- if .Values.database.internal.serviceAccountName }} + serviceAccountName: {{ .Values.database.internal.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.database.internal.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 + initContainers: + # as we change the data directory to a sub folder to support psp, the init container here + # is used to migrate the existing data. See https://github.com/goharbor/harbor-helm/issues/756 + # for more detail. + # we may remove it after several releases + - name: "data-migrator" + image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: ["-c", "[ -e /var/lib/postgresql/data/postgresql.conf ] && [ ! -d /var/lib/postgresql/data/pgdata ] && mkdir -m 0700 /var/lib/postgresql/data/pgdata && mv /var/lib/postgresql/data/* /var/lib/postgresql/data/pgdata/ || true"] +{{- if .Values.database.internal.initContainer.migrator.resources }} + resources: +{{ toYaml .Values.database.internal.initContainer.migrator.resources | indent 10 }} +{{- end }} + volumeMounts: + - name: database-data + mountPath: /var/lib/postgresql/data + subPath: {{ $database.subPath }} + # with "fsGroup" set, each time a volume is mounted, Kubernetes must recursively chown() and chmod() all the files and directories inside the volume + # this causes the postgresql reports the "data directory /var/lib/postgresql/data/pgdata has group or world access" issue when using some CSIs e.g. Ceph + # use this init container to correct the permission + # as "fsGroup" applied before the init container running, the container has enough permission to execute the command + - name: "data-permissions-ensurer" + image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + command: ["/bin/sh"] + args: ["-c", "chmod -R 700 /var/lib/postgresql/data/pgdata || true"] +{{- if .Values.database.internal.initContainer.permissions.resources }} + resources: +{{ toYaml .Values.database.internal.initContainer.permissions.resources | indent 10 }} +{{- end }} + volumeMounts: + - name: database-data + mountPath: /var/lib/postgresql/data + subPath: {{ $database.subPath }} + containers: + - name: database + image: {{ .Values.database.internal.image.repository }}:{{ .Values.database.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + exec: + command: + - /docker-healthcheck.sh + initialDelaySeconds: 300 + periodSeconds: 10 + timeoutSeconds: {{ .Values.database.internal.livenessProbe.timeoutSeconds }} + readinessProbe: + exec: + command: + - /docker-healthcheck.sh + initialDelaySeconds: 1 + periodSeconds: 10 + timeoutSeconds: {{ .Values.database.internal.readinessProbe.timeoutSeconds }} +{{- if .Values.database.internal.resources }} + resources: +{{ toYaml .Values.database.internal.resources | indent 10 }} +{{- end }} + envFrom: + - secretRef: + name: "{{ template "harbor.database" . }}" + env: + # put the data into a sub directory to avoid the permission issue in k8s with restricted psp enabled + # more detail refer to https://github.com/goharbor/harbor-helm/issues/756 + - name: PGDATA + value: "/var/lib/postgresql/data/pgdata" +{{- with .Values.database.internal.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + volumeMounts: + - name: database-data + mountPath: /var/lib/postgresql/data + subPath: {{ $database.subPath }} + - name: shm-volume + mountPath: /dev/shm + volumes: + - name: shm-volume + emptyDir: + medium: Memory + sizeLimit: {{ .Values.database.internal.shmSizeLimit }} + {{- if not .Values.persistence.enabled }} + - name: "database-data" + emptyDir: {} + {{- else if $database.existingClaim }} + - name: "database-data" + persistentVolumeClaim: + claimName: {{ $database.existingClaim }} + {{- end -}} + {{- with .Values.database.internal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.database.internal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.database.internal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.database.internal.priorityClassName }} + priorityClassName: {{ .Values.database.internal.priorityClassName }} + {{- end }} + {{- if and .Values.persistence.enabled (not $database.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: "database-data" + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $database.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $database.accessMode | quote }}] + {{- if $database.storageClass }} + {{- if (eq "-" $database.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $database.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $database.size | quote }} + {{- end -}} + {{- end -}} diff --git a/helm-charts/harbor/templates/database/database-svc.yaml b/helm-charts/harbor/templates/database/database-svc.yaml new file mode 100644 index 0000000..6475048 --- /dev/null +++ b/helm-charts/harbor/templates/database/database-svc.yaml @@ -0,0 +1,14 @@ +{{- if eq .Values.database.type "internal" -}} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.database" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - port: 5432 + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: database +{{- end -}} \ No newline at end of file diff --git a/helm-charts/harbor/templates/exporter/exporter-cm-env.yaml b/helm-charts/harbor/templates/exporter/exporter-cm-env.yaml new file mode 100644 index 0000000..0bf4e7d --- /dev/null +++ b/helm-charts/harbor/templates/exporter/exporter-cm-env.yaml @@ -0,0 +1,35 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.exporter" . }}-env" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + {{- if has "jobservice" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + LOG_LEVEL: "{{ .Values.logLevel }}" + HARBOR_EXPORTER_PORT: "{{ .Values.metrics.exporter.port }}" + HARBOR_EXPORTER_METRICS_PATH: "{{ .Values.metrics.exporter.path }}" + HARBOR_EXPORTER_METRICS_ENABLED: "{{ .Values.metrics.enabled }}" + HARBOR_EXPORTER_CACHE_TIME: "{{ .Values.exporter.cacheDuration }}" + HARBOR_EXPORTER_CACHE_CLEAN_INTERVAL: "{{ .Values.exporter.cacheCleanInterval }}" + HARBOR_METRIC_NAMESPACE: harbor + HARBOR_METRIC_SUBSYSTEM: exporter + HARBOR_REDIS_URL: "{{ template "harbor.redis.urlForJobservice" . }}" + HARBOR_REDIS_NAMESPACE: harbor_job_service_namespace + HARBOR_REDIS_TIMEOUT: "3600" + HARBOR_SERVICE_SCHEME: "{{ template "harbor.component.scheme" . }}" + HARBOR_SERVICE_HOST: "{{ template "harbor.core" . }}" + HARBOR_SERVICE_PORT: "{{ template "harbor.core.servicePort" . }}" + HARBOR_DATABASE_HOST: "{{ template "harbor.database.host" . }}" + HARBOR_DATABASE_PORT: "{{ template "harbor.database.port" . }}" + HARBOR_DATABASE_USERNAME: "{{ template "harbor.database.username" . }}" + HARBOR_DATABASE_DBNAME: "{{ template "harbor.database.coreDatabase" . }}" + HARBOR_DATABASE_SSLMODE: "{{ template "harbor.database.sslmode" . }}" + HARBOR_DATABASE_MAX_IDLE_CONNS: "{{ .Values.database.maxIdleConns }}" + HARBOR_DATABASE_MAX_OPEN_CONNS: "{{ .Values.database.maxOpenConns }}" +{{- end}} \ No newline at end of file diff --git a/helm-charts/harbor/templates/exporter/exporter-dpl.yaml b/helm-charts/harbor/templates/exporter/exporter-dpl.yaml new file mode 100644 index 0000000..6d2e1f5 --- /dev/null +++ b/helm-charts/harbor/templates/exporter/exporter-dpl.yaml @@ -0,0 +1,139 @@ +{{- if .Values.metrics.enabled}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.exporter" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: exporter +spec: + replicas: {{ .Values.exporter.replicas }} + revisionHistoryLimit: {{ .Values.exporter.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: exporter + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: exporter +{{- if .Values.exporter.podLabels }} +{{ toYaml .Values.exporter.podLabels | indent 8 }} +{{- end }} + annotations: +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/core/core-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.exporter.podAnnotations }} +{{ toYaml .Values.exporter.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.exporter.serviceAccountName }} + serviceAccountName: {{ .Values.exporter.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.exporter.automountServiceAccountToken | default false }} +{{- with .Values.exporter.topologySpreadConstraints }} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: exporter +{{- end }} +{{- end }} + containers: + - name: exporter + image: {{ .Values.exporter.image.repository }}:{{ .Values.exporter.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: / + port: {{ .Values.metrics.exporter.port }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: {{ .Values.metrics.exporter.port }} + initialDelaySeconds: 30 + periodSeconds: 10 + args: ["-log-level", "{{ .Values.logLevel }}"] + envFrom: + - configMapRef: + name: "{{ template "harbor.exporter" . }}-env" + - secretRef: + name: "{{ template "harbor.exporter" . }}" + env: + {{- if .Values.database.external.existingSecret }} + - name: HARBOR_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.database.external.existingSecret }} + key: password + {{- end }} + {{- if .Values.existingSecretAdminPassword }} + - name: HARBOR_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.existingSecretAdminPassword }} + key: {{ .Values.existingSecretAdminPasswordKey }} + {{- end }} +{{- if .Values.exporter.resources }} + resources: +{{ toYaml .Values.exporter.resources | indent 10 }} +{{- end }} +{{- with .Values.exporter.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.core.containerPort" . }} + volumeMounts: + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + mountPath: /etc/harbor/ssl/core + # There are some metric data are collectd from harbor core. + # When internal TLS is enabled, the Exporter need the CA file to collect these data. + {{- end }} + volumes: + - name: config + secret: + secretName: "{{ template "harbor.exporter" . }}" + {{- if .Values.internalTLS.enabled }} + - name: core-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.core.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.exporter.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.exporter.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.exporter.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.exporter.priorityClassName }} + priorityClassName: {{ .Values.exporter.priorityClassName }} + {{- end }} +{{ end }} diff --git a/helm-charts/harbor/templates/exporter/exporter-secret.yaml b/helm-charts/harbor/templates/exporter/exporter-secret.yaml new file mode 100644 index 0000000..434a1bf --- /dev/null +++ b/helm-charts/harbor/templates/exporter/exporter-secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.exporter" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: +{{- if not .Values.existingSecretAdminPassword }} + HARBOR_ADMIN_PASSWORD: {{ .Values.harborAdminPassword | b64enc | quote }} +{{- end }} +{{- if not .Values.database.external.existingSecret }} + HARBOR_DATABASE_PASSWORD: {{ template "harbor.database.encryptedPassword" . }} +{{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/exporter/exporter-svc.yaml b/helm-charts/harbor/templates/exporter/exporter-svc.yaml new file mode 100644 index 0000000..4a6f3fd --- /dev/null +++ b/helm-charts/harbor/templates/exporter/exporter-svc.yaml @@ -0,0 +1,15 @@ +{{- if .Values.metrics.enabled}} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.exporter" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.exporter.port }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: exporter +{{ end }} diff --git a/helm-charts/harbor/templates/ingress/ingress.yaml b/helm-charts/harbor/templates/ingress/ingress.yaml new file mode 100644 index 0000000..e4c0693 --- /dev/null +++ b/helm-charts/harbor/templates/ingress/ingress.yaml @@ -0,0 +1,145 @@ +{{- if eq .Values.expose.type "ingress" }} +{{- $ingress := .Values.expose.ingress -}} +{{- $tls := .Values.expose.tls -}} +{{- if eq .Values.expose.ingress.controller "gce" }} + {{- $_ := set . "portal_path" "/*" -}} + {{- $_ := set . "api_path" "/api/*" -}} + {{- $_ := set . "service_path" "/service/*" -}} + {{- $_ := set . "v2_path" "/v2/*" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/*" -}} + {{- $_ := set . "controller_path" "/c/*" -}} +{{- else if eq .Values.expose.ingress.controller "ncp" }} + {{- $_ := set . "portal_path" "/.*" -}} + {{- $_ := set . "api_path" "/api/.*" -}} + {{- $_ := set . "service_path" "/service/.*" -}} + {{- $_ := set . "v2_path" "/v2/.*" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/.*" -}} + {{- $_ := set . "controller_path" "/c/.*" -}} +{{- else }} + {{- $_ := set . "portal_path" "/" -}} + {{- $_ := set . "api_path" "/api/" -}} + {{- $_ := set . "service_path" "/service/" -}} + {{- $_ := set . "v2_path" "/v2/" -}} + {{- $_ := set . "chartrepo_path" "/chartrepo/" -}} + {{- $_ := set . "controller_path" "/c/" -}} +{{- end }} + +--- +{{- if semverCompare "<1.14-0" (include "harbor.ingress.kubeVersion" .) }} +apiVersion: extensions/v1beta1 +{{- else if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: networking.k8s.io/v1 +{{- end }} +kind: Ingress +metadata: + name: "{{ template "harbor.ingress" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- if $ingress.harbor.labels }} +{{ toYaml $ingress.harbor.labels | indent 4 }} +{{- end }} + annotations: +{{ toYaml $ingress.annotations | indent 4 }} +{{- if .Values.internalTLS.enabled }} + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" +{{- end }} +{{- if eq .Values.expose.ingress.controller "ncp" }} + ncp/use-regex: "true" + {{- if $tls.enabled }} + ncp/http-redirect: "true" + {{- end }} +{{- end }} +{{- if $ingress.harbor.annotations }} +{{ toYaml $ingress.harbor.annotations | indent 4 }} +{{- end }} +spec: + {{- if $ingress.className }} + ingressClassName: {{ $ingress.className }} + {{- end }} + {{- if $tls.enabled }} + tls: + - secretName: {{ template "harbor.tlsCoreSecretForIngress" . }} + {{- if $ingress.hosts.core }} + hosts: + - {{ $ingress.hosts.core }} + {{- end }} + {{- end }} + rules: + - http: + paths: +{{- if semverCompare "<1.19-0" (include "harbor.ingress.kubeVersion" .) }} + - path: {{ .api_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .service_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .v2_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .chartrepo_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .controller_path }} + backend: + serviceName: {{ template "harbor.core" . }} + servicePort: {{ template "harbor.core.servicePort" . }} + - path: {{ .portal_path }} + backend: + serviceName: {{ template "harbor.portal" . }} + servicePort: {{ template "harbor.portal.servicePort" . }} +{{- else }} + - path: {{ .api_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .service_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .v2_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .chartrepo_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .controller_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.core" . }} + port: + number: {{ template "harbor.core.servicePort" . }} + - path: {{ .portal_path }} + pathType: Prefix + backend: + service: + name: {{ template "harbor.portal" . }} + port: + number: {{ template "harbor.portal.servicePort" . }} +{{- end }} + {{- if $ingress.hosts.core }} + host: {{ $ingress.hosts.core }} + {{- end }} + +{{- end }} diff --git a/helm-charts/harbor/templates/ingress/secret.yaml b/helm-charts/harbor/templates/ingress/secret.yaml new file mode 100644 index 0000000..41507b3 --- /dev/null +++ b/helm-charts/harbor/templates/ingress/secret.yaml @@ -0,0 +1,15 @@ +{{- if eq (include "harbor.autoGenCertForIngress" .) "true" }} +{{- $ca := genCA "harbor-ca" 365 }} +{{- $cert := genSignedCert .Values.expose.ingress.hosts.core nil (list .Values.expose.ingress.hosts.core) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.ingress" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/internal/auto-tls.yaml b/helm-charts/harbor/templates/internal/auto-tls.yaml new file mode 100644 index 0000000..da5f5e2 --- /dev/null +++ b/helm-charts/harbor/templates/internal/auto-tls.yaml @@ -0,0 +1,81 @@ +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} +{{- $ca := genCA "harbor-internal-ca" 365 }} +{{- $coreCN := (include "harbor.core" .) }} +{{- $coreCrt := genSignedCert $coreCN (list "127.0.0.1") (list "localhost" $coreCN) 365 $ca }} +{{- $jsCN := (include "harbor.jobservice" .) }} +{{- $jsCrt := genSignedCert $jsCN nil (list $jsCN) 365 $ca }} +{{- $regCN := (include "harbor.registry" .) }} +{{- $regCrt := genSignedCert $regCN nil (list $regCN) 365 $ca }} +{{- $portalCN := (include "harbor.portal" .) }} +{{- $portalCrt := genSignedCert $portalCN nil (list $portalCN) 365 $ca }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.core.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $coreCrt.Cert | b64enc | quote }} + tls.key: {{ $coreCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $jsCrt.Cert | b64enc | quote }} + tls.key: {{ $jsCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.registry.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $regCrt.Cert | b64enc | quote }} + tls.key: {{ $regCrt.Key | b64enc | quote }} + +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.portal.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $portalCrt.Cert | b64enc | quote }} + tls.key: {{ $portalCrt.Key | b64enc | quote }} + +{{- if and .Values.trivy.enabled}} +--- +{{- $trivyCN := (include "harbor.trivy" .) }} +{{- $trivyCrt := genSignedCert $trivyCN nil (list $trivyCN) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $trivyCrt.Cert | b64enc | quote }} + tls.key: {{ $trivyCrt.Key | b64enc | quote }} +{{- end }} + +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/jobservice/jobservice-cm-env.yaml b/helm-charts/harbor/templates/jobservice/jobservice-cm-env.yaml new file mode 100644 index 0000000..8411c7a --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-cm-env.yaml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.jobservice" . }}-env" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + CORE_URL: "{{ template "harbor.coreURL" . }}" + TOKEN_SERVICE_URL: "{{ template "harbor.tokenServiceURL" . }}" + REGISTRY_URL: "{{ template "harbor.registryURL" . }}" + REGISTRY_CONTROLLER_URL: "{{ template "harbor.registryControllerURL" . }}" + REGISTRY_CREDENTIAL_USERNAME: "{{ .Values.registry.credentials.username }}" + + JOBSERVICE_WEBHOOK_JOB_MAX_RETRY: "{{ .Values.jobservice.notification.webhook_job_max_retry }}" + JOBSERVICE_WEBHOOK_JOB_HTTP_CLIENT_TIMEOUT: "{{ .Values.jobservice.notification.webhook_job_http_client_timeout }}" + + {{- if has "jobservice" .Values.proxy.components }} + HTTP_PROXY: "{{ .Values.proxy.httpProxy }}" + HTTPS_PROXY: "{{ .Values.proxy.httpsProxy }}" + NO_PROXY: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.metrics.enabled}} + METRIC_NAMESPACE: harbor + METRIC_SUBSYSTEM: jobservice + {{- end }} + {{- template "harbor.traceEnvsForJobservice" . }} + {{- if .Values.cache.enabled }} + _REDIS_URL_CORE: "{{ template "harbor.redis.urlForCore" . }}" + CACHE_ENABLED: "true" + CACHE_EXPIRE_HOURS: "{{ .Values.cache.expireHours }}" + {{- end }} + {{- if or (and (eq .Values.redis.type "internal") .Values.redis.internal.cacheLayerDatabaseIndex) (and (eq .Values.redis.type "external") .Values.redis.external.cacheLayerDatabaseIndex) }} + _REDIS_URL_CACHE_LAYER: "{{ template "harbor.redis.urlForCache" . }}" + {{- end }} diff --git a/helm-charts/harbor/templates/jobservice/jobservice-cm.yaml b/helm-charts/harbor/templates/jobservice/jobservice-cm.yaml new file mode 100644 index 0000000..8211c62 --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-cm.yaml @@ -0,0 +1,57 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + config.yml: |+ + #Server listening port + protocol: "{{ template "harbor.component.scheme" . }}" + port: {{ template "harbor.jobservice.containerPort". }} + {{- if .Values.internalTLS.enabled }} + https_config: + cert: "/etc/harbor/ssl/jobservice/tls.crt" + key: "/etc/harbor/ssl/jobservice/tls.key" + {{- end }} + worker_pool: + workers: {{ .Values.jobservice.maxJobWorkers }} + backend: "redis" + redis_pool: + redis_url: "{{ template "harbor.redis.urlForJobservice" . }}" + namespace: "harbor_job_service_namespace" + idle_timeout_second: 3600 + job_loggers: + {{- if has "file" .Values.jobservice.jobLoggers }} + - name: "FILE" + level: {{ .Values.logLevel | upper }} + settings: # Customized settings of logger + base_dir: "/var/log/jobs" + sweeper: + duration: {{ .Values.jobservice.loggerSweeperDuration }} #days + settings: # Customized settings of sweeper + work_dir: "/var/log/jobs" + {{- end }} + {{- if has "database" .Values.jobservice.jobLoggers }} + - name: "DB" + level: {{ .Values.logLevel | upper }} + sweeper: + duration: {{ .Values.jobservice.loggerSweeperDuration }} #days + {{- end }} + {{- if has "stdout" .Values.jobservice.jobLoggers }} + - name: "STD_OUTPUT" + level: {{ .Values.logLevel | upper }} + {{- end }} + metric: + enabled: {{ .Values.metrics.enabled }} + path: {{ .Values.metrics.jobservice.path }} + port: {{ .Values.metrics.jobservice.port }} + #Loggers for the job service + loggers: + - name: "STD_OUTPUT" + level: {{ .Values.logLevel | upper }} + reaper: + # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 + max_update_hours: {{ .Values.jobservice.reaper.max_update_hours }} + # the max time for execution in running state without new task created + max_dangling_hours: {{ .Values.jobservice.reaper.max_dangling_hours }} diff --git a/helm-charts/harbor/templates/jobservice/jobservice-dpl.yaml b/helm-charts/harbor/templates/jobservice/jobservice-dpl.yaml new file mode 100644 index 0000000..32df97d --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-dpl.yaml @@ -0,0 +1,166 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: jobservice +spec: + replicas: {{ .Values.jobservice.replicas }} + revisionHistoryLimit: {{ .Values.jobservice.revisionHistoryLimit }} + strategy: + type: {{ .Values.updateStrategy.type }} + {{- if eq .Values.updateStrategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: jobservice + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: jobservice +{{- if .Values.jobservice.podLabels }} +{{ toYaml .Values.jobservice.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm.yaml") . | sha256sum }} + checksum/configmap-env: {{ include (print $.Template.BasePath "/jobservice/jobservice-cm-env.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} + checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/jobservice/jobservice-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.jobservice.podAnnotations }} +{{ toYaml .Values.jobservice.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 +{{- if .Values.jobservice.serviceAccountName }} + serviceAccountName: {{ .Values.jobservice.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.jobservice.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.jobservice.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: jobservice +{{- end }} +{{- end }} + containers: + - name: jobservice + image: {{ .Values.jobservice.image.repository }}:{{ .Values.jobservice.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: /api/v1/stats + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.jobservice.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/v1/stats + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.jobservice.containerPort" . }} + initialDelaySeconds: 20 + periodSeconds: 10 +{{- if .Values.jobservice.resources }} + resources: +{{ toYaml .Values.jobservice.resources | indent 10 }} +{{- end }} + env: + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "harbor.core" . }} + key: secret + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/jobservice/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/jobservice/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/jobservice/ca.crt + {{- end }} + {{- if .Values.registry.credentials.existingSecret }} + - name: REGISTRY_CREDENTIAL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.registry.credentials.existingSecret }} + key: REGISTRY_PASSWD + {{- end }} +{{- with .Values.jobservice.extraEnvVars }} +{{- toYaml . | nindent 10 }} +{{- end }} + envFrom: + - configMapRef: + name: "{{ template "harbor.jobservice" . }}-env" + - secretRef: + name: "{{ template "harbor.jobservice" . }}" + ports: + - containerPort: {{ template "harbor.jobservice.containerPort" . }} + volumeMounts: + - name: jobservice-config + mountPath: /etc/jobservice/config.yml + subPath: config.yml + - name: job-logs + mountPath: /var/log/jobs + subPath: {{ .Values.persistence.persistentVolumeClaim.jobservice.jobLog.subPath }} + {{- if .Values.internalTLS.enabled }} + - name: jobservice-internal-certs + mountPath: /etc/harbor/ssl/jobservice + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + volumes: + - name: jobservice-config + configMap: + name: "{{ template "harbor.jobservice" . }}" + - name: job-logs + {{- if and .Values.persistence.enabled (has "file" .Values.jobservice.jobLoggers) }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.persistentVolumeClaim.jobservice.jobLog.existingClaim | default (include "harbor.jobservice" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: jobservice-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.jobservice.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.jobservice.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.jobservice.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.jobservice.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.jobservice.priorityClassName }} + priorityClassName: {{ .Values.jobservice.priorityClassName }} + {{- end }} diff --git a/helm-charts/harbor/templates/jobservice/jobservice-pvc.yaml b/helm-charts/harbor/templates/jobservice/jobservice-pvc.yaml new file mode 100644 index 0000000..a6b8b8b --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-pvc.yaml @@ -0,0 +1,30 @@ +{{- $jobLog := .Values.persistence.persistentVolumeClaim.jobservice.jobLog -}} +{{- if and .Values.persistence.enabled (not $jobLog.existingClaim) (has "file" .Values.jobservice.jobLoggers) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "harbor.jobservice" . }} + annotations: + {{- range $key, $value := $jobLog.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if eq .Values.persistence.resourcePolicy "keep" }} + helm.sh/resource-policy: keep + {{- end }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: jobservice +spec: + accessModes: + - {{ $jobLog.accessMode }} + resources: + requests: + storage: {{ $jobLog.size }} + {{- if $jobLog.storageClass }} + {{- if eq "-" $jobLog.storageClass }} + storageClassName: "" + {{- else }} + storageClassName: {{ $jobLog.storageClass }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/jobservice/jobservice-secrets.yaml b/helm-charts/harbor/templates/jobservice/jobservice-secrets.yaml new file mode 100644 index 0000000..3dfa6bd --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-secrets.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + JOBSERVICE_SECRET: {{ .Values.jobservice.secret | default (randAlphaNum 16) | b64enc | quote }} + {{- if not .Values.registry.credentials.existingSecret }} + REGISTRY_CREDENTIAL_PASSWORD: {{ .Values.registry.credentials.password | b64enc | quote }} + {{- end }} + {{- template "harbor.traceJaegerPassword" . }} diff --git a/helm-charts/harbor/templates/jobservice/jobservice-svc.yaml b/helm-charts/harbor/templates/jobservice/jobservice-svc.yaml new file mode 100644 index 0000000..d2b7a47 --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-svc.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.jobservice" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-jobservice" "http-jobservice" .Values.internalTLS.enabled }} + port: {{ template "harbor.jobservice.servicePort" . }} + targetPort: {{ template "harbor.jobservice.containerPort" . }} +{{- if .Values.metrics.enabled }} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.jobservice.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: jobservice diff --git a/helm-charts/harbor/templates/jobservice/jobservice-tls.yaml b/helm-charts/harbor/templates/jobservice/jobservice-tls.yaml new file mode 100644 index 0000000..234cb39 --- /dev/null +++ b/helm-charts/harbor/templates/jobservice/jobservice-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.jobservice.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} + tls.crt: {{ (required "The \"internalTLS.jobservice.crt\" is required!" .Values.internalTLS.jobservice.crt) | b64enc | quote }} + tls.key: {{ (required "The \"internalTLS.jobservice.key\" is required!" .Values.internalTLS.jobservice.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/metrics/metrics-svcmon.yaml b/helm-charts/harbor/templates/metrics/metrics-svcmon.yaml new file mode 100644 index 0000000..1122ef0 --- /dev/null +++ b/helm-charts/harbor/templates/metrics/metrics-svcmon.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "harbor.fullname" . }} + labels: {{ include "harbor.labels" . | nindent 4 }} +{{- if .Values.metrics.serviceMonitor.additionalLabels }} +{{ toYaml .Values.metrics.serviceMonitor.additionalLabels | indent 4 }} +{{- end }} +spec: + jobLabel: app.kubernetes.io/name + endpoints: + - port: {{ template "harbor.metricsPortName" . }} + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + honorLabels: true +{{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: +{{ tpl (toYaml .Values.metrics.serviceMonitor.metricRelabelings | indent 4) . }} +{{- end }} +{{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: +{{ toYaml .Values.metrics.serviceMonitor.relabelings | indent 4 }} +{{- end }} + selector: + matchLabels: {{ include "harbor.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/helm-charts/harbor/templates/nginx/configmap-http.yaml b/helm-charts/harbor/templates/nginx/configmap-http.yaml new file mode 100644 index 0000000..c4b8354 --- /dev/null +++ b/helm-charts/harbor/templates/nginx/configmap-http.yaml @@ -0,0 +1,150 @@ +{{- if and (ne .Values.expose.type "ingress") (not .Values.expose.tls.enabled) }} +{{- $scheme := (include "harbor.component.scheme" .) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + + events { + worker_connections 3096; + use epoll; + multi_accept on; + } + + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + tcp_nodelay on; + + # this is necessary for us to be able to disable request buffering in all cases + proxy_http_version 1.1; + + upstream core { + server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; + } + + upstream portal { + server {{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}; + } + + log_format timed_combined '[$time_local]:$remote_addr - ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time $upstream_response_time $pipe'; + + access_log /dev/stdout timed_combined; + + map $http_x_forwarded_proto $x_forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; + } + + server { + {{- if .Values.ipFamily.ipv4.enabled}} + listen 8080; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8080; + {{- end }} + server_tokens off; + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # Add extra headers + add_header X-Frame-Options DENY; + add_header Content-Security-Policy "frame-ancestors 'none'"; + + location / { + proxy_pass {{ $scheme }}://portal/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /api/ { + proxy_pass {{ $scheme }}://core/api/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /chartrepo/ { + proxy_pass {{ $scheme }}://core/chartrepo/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /c/ { + proxy_pass {{ $scheme }}://core/c/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /v1/ { + return 404; + } + + location /v2/ { + proxy_pass {{ $scheme }}://core/v2/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + proxy_buffering off; + proxy_request_buffering off; + proxy_send_timeout 900; + proxy_read_timeout 900; + } + + location /service/ { + proxy_pass {{ $scheme }}://core/service/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/notifications { + return 404; + } + } + } +{{- end }} diff --git a/helm-charts/harbor/templates/nginx/configmap-https.yaml b/helm-charts/harbor/templates/nginx/configmap-https.yaml new file mode 100644 index 0000000..56c943a --- /dev/null +++ b/helm-charts/harbor/templates/nginx/configmap-https.yaml @@ -0,0 +1,187 @@ +{{- if and (ne .Values.expose.type "ingress") .Values.expose.tls.enabled }} +{{- $scheme := (include "harbor.component.scheme" .) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + + events { + worker_connections 3096; + use epoll; + multi_accept on; + } + + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + tcp_nodelay on; + + # this is necessary for us to be able to disable request buffering in all cases + proxy_http_version 1.1; + + upstream core { + server "{{ template "harbor.core" . }}:{{ template "harbor.core.servicePort" . }}"; + } + + upstream portal { + server "{{ template "harbor.portal" . }}:{{ template "harbor.portal.servicePort" . }}"; + } + + log_format timed_combined '[$time_local]:$remote_addr - ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$request_time $upstream_response_time $pipe'; + + access_log /dev/stdout timed_combined; + + map $http_x_forwarded_proto $x_forwarded_proto { + default $http_x_forwarded_proto; + "" $scheme; + } + + server { + {{- if .Values.ipFamily.ipv4.enabled }} + listen 8443 ssl; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8443 ssl; + {{- end }} + # server_name harbordomain.com; + server_tokens off; + # SSL + ssl_certificate /etc/nginx/cert/tls.crt; + ssl_certificate_key /etc/nginx/cert/tls.key; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + {{- if .Values.internalTLS.strong_ssl_ciphers }} + ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+RSA+SHA256:DHE+RSA+SHA256:!AES128; + {{ else }} + ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; + {{- end }} + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + + # disable any limits to avoid HTTP 413 for large image uploads + client_max_body_size 0; + + # required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486) + chunked_transfer_encoding on; + + # Add extra headers + add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload"; + add_header X-Frame-Options DENY; + add_header Content-Security-Policy "frame-ancestors 'none'"; + + location / { + proxy_pass {{ $scheme }}://portal/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; HttpOnly; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /api/ { + proxy_pass {{ $scheme }}://core/api/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /chartrepo/ { + proxy_pass {{ $scheme }}://core/chartrepo/; + {{- if and .Values.internalTLS.enabled }} + proxy_ssl_verify off; + proxy_ssl_session_reuse on; + {{- end }} + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /c/ { + proxy_pass {{ $scheme }}://core/c/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /v1/ { + return 404; + } + + location /v2/ { + proxy_pass {{ $scheme }}://core/v2/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/ { + proxy_pass {{ $scheme }}://core/service/; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $x_forwarded_proto; + + proxy_cookie_path / "/; Secure"; + + proxy_buffering off; + proxy_request_buffering off; + } + + location /service/notifications { + return 404; + } + } + server { + {{- if .Values.ipFamily.ipv4.enabled }} + listen 8080; + {{- end}} + {{- if .Values.ipFamily.ipv6.enabled }} + listen [::]:8080; + {{- end}} + #server_name harbordomain.com; + return 301 https://$host$request_uri; + } + } +{{- end }} diff --git a/helm-charts/harbor/templates/nginx/deployment.yaml b/helm-charts/harbor/templates/nginx/deployment.yaml new file mode 100644 index 0000000..8290d49 --- /dev/null +++ b/helm-charts/harbor/templates/nginx/deployment.yaml @@ -0,0 +1,126 @@ +{{- if ne .Values.expose.type "ingress" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: nginx +spec: + replicas: {{ .Values.nginx.replicas }} + revisionHistoryLimit: {{ .Values.nginx.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: nginx + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: nginx +{{- if .Values.nginx.podLabels }} +{{ toYaml .Values.nginx.podLabels | indent 8 }} +{{- end }} + annotations: + {{- if not .Values.expose.tls.enabled }} + checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-http.yaml") . | sha256sum }} + {{- else }} + checksum/configmap: {{ include (print $.Template.BasePath "/nginx/configmap-https.yaml") . | sha256sum }} + {{- end }} + {{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} + checksum/secret: {{ include (print $.Template.BasePath "/nginx/secret.yaml") . | sha256sum }} + {{- end }} +{{- if .Values.nginx.podAnnotations }} +{{ toYaml .Values.nginx.podAnnotations | indent 8 }} +{{- end }} + spec: +{{- if .Values.nginx.serviceAccountName }} + serviceAccountName: {{ .Values.nginx.serviceAccountName }} +{{- end }} + securityContext: + runAsUser: 10000 + fsGroup: 10000 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.nginx.automountServiceAccountToken | default false }} +{{- with .Values.nginx.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: nginx +{{- end }} +{{- end }} + containers: + - name: nginx + image: "{{ .Values.nginx.image.repository }}:{{ .Values.nginx.image.tag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + {{- $_ := set . "scheme" "HTTP" -}} + {{- $_ := set . "port" "8080" -}} + {{- if .Values.expose.tls.enabled }} + {{- $_ := set . "scheme" "HTTPS" -}} + {{- $_ := set . "port" "8443" -}} + {{- end }} + livenessProbe: + httpGet: + scheme: {{ .scheme }} + path: / + port: {{ .port }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + scheme: {{ .scheme }} + path: / + port: {{ .port }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.nginx.resources }} + resources: +{{ toYaml .Values.nginx.resources | indent 10 }} +{{- end }} +{{- with .Values.nginx.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + ports: + - containerPort: 8080 + - containerPort: 8443 + - containerPort: 4443 + volumeMounts: + - name: config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + {{- if .Values.expose.tls.enabled }} + - name: certificate + mountPath: /etc/nginx/cert + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "harbor.nginx" . }} + {{- if .Values.expose.tls.enabled }} + - name: certificate + secret: + secretName: {{ template "harbor.tlsSecretForNginx" . }} + {{- end }} + {{- with .Values.nginx.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.nginx.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.nginx.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.nginx.priorityClassName }} + priorityClassName: {{ .Values.nginx.priorityClassName }} + {{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/nginx/secret.yaml b/helm-charts/harbor/templates/nginx/secret.yaml new file mode 100644 index 0000000..c819c55 --- /dev/null +++ b/helm-charts/harbor/templates/nginx/secret.yaml @@ -0,0 +1,23 @@ +{{- if eq (include "harbor.autoGenCertForNginx" .) "true" }} +{{- $ca := genCA "harbor-ca" 365 }} +{{- $cn := (required "The \"expose.tls.auto.commonName\" is required!" .Values.expose.tls.auto.commonName) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.nginx" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if regexMatch `^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$` $cn }} + {{- $cert := genSignedCert $cn (list $cn) nil 365 $ca }} + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} + {{- else }} + {{- $cert := genSignedCert $cn nil (list $cn) 365 $ca }} + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/nginx/service.yaml b/helm-charts/harbor/templates/nginx/service.yaml new file mode 100644 index 0000000..12021bf --- /dev/null +++ b/helm-charts/harbor/templates/nginx/service.yaml @@ -0,0 +1,78 @@ +{{- if or (eq .Values.expose.type "clusterIP") (eq .Values.expose.type "nodePort") (eq .Values.expose.type "loadBalancer") }} +apiVersion: v1 +kind: Service +metadata: +{{- if eq .Values.expose.type "clusterIP" }} +{{- $clusterIP := .Values.expose.clusterIP }} + name: {{ $clusterIP.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- with $clusterIP.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: ClusterIP + ports: + - name: http + port: {{ $clusterIP.ports.httpPort }} + targetPort: 8080 + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $clusterIP.ports.httpsPort }} + targetPort: 8443 + {{- end }} +{{- else if eq .Values.expose.type "nodePort" }} +{{- $nodePort := .Values.expose.nodePort }} + name: {{ $nodePort.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + type: NodePort + ports: + - name: http + port: {{ $nodePort.ports.http.port }} + targetPort: 8080 + {{- if $nodePort.ports.http.nodePort }} + nodePort: {{ $nodePort.ports.http.nodePort }} + {{- end }} + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $nodePort.ports.https.port }} + targetPort: 8443 + {{- if $nodePort.ports.https.nodePort }} + nodePort: {{ $nodePort.ports.https.nodePort }} + {{- end }} + {{- end }} +{{- else if eq .Values.expose.type "loadBalancer" }} +{{- $loadBalancer := .Values.expose.loadBalancer }} + name: {{ $loadBalancer.name }} + labels: +{{ include "harbor.labels" . | indent 4 }} +{{- with $loadBalancer.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: LoadBalancer + {{- with $loadBalancer.sourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $loadBalancer.IP }} + loadBalancerIP: {{ $loadBalancer.IP }} + {{- end }} + ports: + - name: http + port: {{ $loadBalancer.ports.httpPort }} + targetPort: 8080 + {{- if .Values.expose.tls.enabled }} + - name: https + port: {{ $loadBalancer.ports.httpsPort }} + targetPort: 8443 + {{- end }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: nginx +{{- end }} diff --git a/helm-charts/harbor/templates/portal/configmap.yaml b/helm-charts/harbor/templates/portal/configmap.yaml new file mode 100644 index 0000000..7b2118e --- /dev/null +++ b/helm-charts/harbor/templates/portal/configmap.yaml @@ -0,0 +1,67 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + nginx.conf: |+ + worker_processes auto; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + client_body_temp_path /tmp/client_body_temp; + proxy_temp_path /tmp/proxy_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + server { + {{- if .Values.internalTLS.enabled }} + {{- if .Values.ipFamily.ipv4.enabled}} + listen {{ template "harbor.portal.containerPort" . }} ssl; + {{- end }} + {{- if .Values.ipFamily.ipv6.enabled}} + listen [::]:{{ template "harbor.portal.containerPort" . }} ssl; + {{- end }} + # SSL + ssl_certificate /etc/harbor/ssl/portal/tls.crt; + ssl_certificate_key /etc/harbor/ssl/portal/tls.key; + + # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + {{- if .Values.internalTLS.strong_ssl_ciphers }} + ssl_ciphers ECDHE+AESGCM:DHE+AESGCM:ECDHE+RSA+SHA256:DHE+RSA+SHA256:!AES128; + {{ else }} + ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:'; + {{- end }} + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + {{- else }} + {{- if .Values.ipFamily.ipv4.enabled }} + listen {{ template "harbor.portal.containerPort" . }}; + {{- end }} + {{- if .Values.ipFamily.ipv6.enabled}} + listen [::]:{{ template "harbor.portal.containerPort" . }}; + {{- end }} + {{- end }} + server_name localhost; + root /usr/share/nginx/html; + index index.html index.htm; + include /etc/nginx/mime.types; + gzip on; + gzip_min_length 1000; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; + location /devcenter-api-2.0 { + try_files $uri $uri/ /swagger-ui-index.html; + } + location / { + try_files $uri $uri/ /index.html; + } + location = /index.html { + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + } + } diff --git a/helm-charts/harbor/templates/portal/deployment.yaml b/helm-charts/harbor/templates/portal/deployment.yaml new file mode 100644 index 0000000..959a3fd --- /dev/null +++ b/helm-charts/harbor/templates/portal/deployment.yaml @@ -0,0 +1,114 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: portal +spec: + replicas: {{ .Values.portal.replicas }} + revisionHistoryLimit: {{ .Values.portal.revisionHistoryLimit }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: portal + template: + metadata: + labels: +{{ include "harbor.matchLabels" . | indent 8 }} + component: portal +{{- if .Values.portal.podLabels }} +{{ toYaml .Values.portal.podLabels | indent 8 }} +{{- end }} + annotations: +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/portal/tls.yaml") . | sha256sum }} +{{- end }} + checksum/configmap: {{ include (print $.Template.BasePath "/portal/configmap.yaml") . | sha256sum }} +{{- if .Values.portal.podAnnotations }} +{{ toYaml .Values.portal.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- if .Values.portal.serviceAccountName }} + serviceAccountName: {{ .Values.portal.serviceAccountName }} +{{- end }} + automountServiceAccountToken: {{ .Values.portal.automountServiceAccountToken | default false }} +{{- with .Values.portal.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: portal +{{- end }} +{{- end }} + containers: + - name: portal + image: {{ .Values.portal.image.repository }}:{{ .Values.portal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} +{{- if .Values.portal.resources }} + resources: +{{ toYaml .Values.portal.resources | indent 10 }} +{{- end }} +{{- with .Values.portal.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + livenessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.portal.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.portal.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 + ports: + - containerPort: {{ template "harbor.portal.containerPort" . }} + volumeMounts: + - name: portal-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + {{- if .Values.internalTLS.enabled }} + - name: portal-internal-certs + mountPath: /etc/harbor/ssl/portal + {{- end }} + volumes: + - name: portal-config + configMap: + name: "{{ template "harbor.portal" . }}" + {{- if .Values.internalTLS.enabled }} + - name: portal-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.portal.secretName" . }} + {{- end }} + {{- with .Values.portal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.portal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.portal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.portal.priorityClassName }} + priorityClassName: {{ .Values.portal.priorityClassName }} + {{- end }} diff --git a/helm-charts/harbor/templates/portal/service.yaml b/helm-charts/harbor/templates/portal/service.yaml new file mode 100644 index 0000000..ff4eda4 --- /dev/null +++ b/helm-charts/harbor/templates/portal/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.portal" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: +{{- if or (eq .Values.expose.ingress.controller "gce") (eq .Values.expose.ingress.controller "alb") (eq .Values.expose.ingress.controller "f5-bigip") }} + type: NodePort +{{- end }} + ports: + - port: {{ template "harbor.portal.servicePort" . }} + targetPort: {{ template "harbor.portal.containerPort" . }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: portal diff --git a/helm-charts/harbor/templates/portal/tls.yaml b/helm-charts/harbor/templates/portal/tls.yaml new file mode 100644 index 0000000..de63f4e --- /dev/null +++ b/helm-charts/harbor/templates/portal/tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.portal.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} + tls.crt: {{ (required "The \"internalTLS.portal.crt\" is required!" .Values.internalTLS.portal.crt) | b64enc | quote }} + tls.key: {{ (required "The \"internalTLS.portal.key\" is required!" .Values.internalTLS.portal.key) | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/redis/service.yaml b/helm-charts/harbor/templates/redis/service.yaml new file mode 100644 index 0000000..79c95c3 --- /dev/null +++ b/helm-charts/harbor/templates/redis/service.yaml @@ -0,0 +1,14 @@ +{{- if eq .Values.redis.type "internal" -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "harbor.redis" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - port: 6379 + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: redis +{{- end -}} \ No newline at end of file diff --git a/helm-charts/harbor/templates/redis/statefulset.yaml b/helm-charts/harbor/templates/redis/statefulset.yaml new file mode 100644 index 0000000..371b0fd --- /dev/null +++ b/helm-charts/harbor/templates/redis/statefulset.yaml @@ -0,0 +1,116 @@ +{{- if eq .Values.redis.type "internal" -}} +{{- $redis := .Values.persistence.persistentVolumeClaim.redis -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "harbor.redis" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: redis +spec: + replicas: 1 + serviceName: {{ template "harbor.redis" . }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: redis + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: redis +{{- if .Values.redis.podLabels }} +{{ toYaml .Values.redis.podLabels | indent 8 }} +{{- end }} +{{- if .Values.redis.podAnnotations }} + annotations: +{{ toYaml .Values.redis.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 999 + fsGroup: 999 +{{- if .Values.redis.internal.serviceAccountName }} + serviceAccountName: {{ .Values.redis.internal.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.redis.internal.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 + containers: + - name: redis + image: {{ .Values.redis.internal.image.repository }}:{{ .Values.redis.internal.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.redis.internal.resources }} + resources: +{{ toYaml .Values.redis.internal.resources | indent 10 }} +{{- end }} +{{- with .Values.redis.internal.extraEnvVars }} + env: +{{- toYaml . | nindent 10 }} +{{- end }} + volumeMounts: + - name: data + mountPath: /var/lib/redis + subPath: {{ $redis.subPath }} + {{- if not .Values.persistence.enabled }} + volumes: + - name: data + emptyDir: {} + {{- else if $redis.existingClaim }} + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ $redis.existingClaim }} + {{- end -}} + {{- with .Values.redis.internal.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.redis.internal.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.redis.internal.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.redis.internal.priorityClassName }} + priorityClassName: {{ .Values.redis.internal.priorityClassName }} + {{- end }} + {{- if and .Values.persistence.enabled (not $redis.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $redis.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $redis.accessMode | quote }}] + {{- if $redis.storageClass }} + {{- if (eq "-" $redis.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $redis.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $redis.size | quote }} + {{- end -}} + {{- end -}} diff --git a/helm-charts/harbor/templates/registry/registry-cm.yaml b/helm-charts/harbor/templates/registry/registry-cm.yaml new file mode 100644 index 0000000..4f7056c --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-cm.yaml @@ -0,0 +1,246 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + config.yml: |+ + version: 0.1 + log: + {{- if eq .Values.logLevel "warning" }} + level: warn + {{- else if eq .Values.logLevel "fatal" }} + level: error + {{- else }} + level: {{ .Values.logLevel }} + {{- end }} + fields: + service: registry + storage: + {{- $storage := .Values.persistence.imageChartStorage }} + {{- $type := $storage.type }} + {{- if eq $type "filesystem" }} + filesystem: + rootdirectory: {{ $storage.filesystem.rootdirectory }} + {{- if $storage.filesystem.maxthreads }} + maxthreads: {{ $storage.filesystem.maxthreads }} + {{- end }} + {{- else if eq $type "azure" }} + azure: + accountname: {{ $storage.azure.accountname }} + container: {{ $storage.azure.container }} + {{- if $storage.azure.realm }} + realm: {{ $storage.azure.realm }} + {{- end }} + {{- else if eq $type "gcs" }} + gcs: + bucket: {{ $storage.gcs.bucket }} + {{- if not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity }} + keyfile: /etc/registry/gcs-key.json + {{- end }} + {{- if $storage.gcs.rootdirectory }} + rootdirectory: {{ $storage.gcs.rootdirectory }} + {{- end }} + {{- if $storage.gcs.chunksize }} + chunksize: {{ $storage.gcs.chunksize }} + {{- end }} + {{- else if eq $type "s3" }} + s3: + region: {{ $storage.s3.region }} + bucket: {{ $storage.s3.bucket }} + {{- if $storage.s3.regionendpoint }} + regionendpoint: {{ $storage.s3.regionendpoint }} + {{- end }} + {{- if $storage.s3.encrypt }} + encrypt: {{ $storage.s3.encrypt }} + {{- end }} + {{- if $storage.s3.keyid }} + keyid: {{ $storage.s3.keyid }} + {{- end }} + {{- if $storage.s3.secure }} + secure: {{ $storage.s3.secure }} + {{- end }} + {{- if and $storage.s3.secure $storage.s3.skipverify }} + skipverify: {{ $storage.s3.skipverify }} + {{- end }} + {{- if $storage.s3.v4auth }} + v4auth: {{ $storage.s3.v4auth }} + {{- end }} + {{- if $storage.s3.chunksize }} + chunksize: {{ $storage.s3.chunksize }} + {{- end }} + {{- if $storage.s3.rootdirectory }} + rootdirectory: {{ $storage.s3.rootdirectory }} + {{- end }} + {{- if $storage.s3.storageclass }} + storageclass: {{ $storage.s3.storageclass }} + {{- end }} + {{- if $storage.s3.multipartcopychunksize }} + multipartcopychunksize: {{ $storage.s3.multipartcopychunksize }} + {{- end }} + {{- if $storage.s3.multipartcopymaxconcurrency }} + multipartcopymaxconcurrency: {{ $storage.s3.multipartcopymaxconcurrency }} + {{- end }} + {{- if $storage.s3.multipartcopythresholdsize }} + multipartcopythresholdsize: {{ $storage.s3.multipartcopythresholdsize }} + {{- end }} + {{- else if eq $type "swift" }} + swift: + authurl: {{ $storage.swift.authurl }} + username: {{ $storage.swift.username }} + container: {{ $storage.swift.container }} + {{- if $storage.swift.region }} + region: {{ $storage.swift.region }} + {{- end }} + {{- if $storage.swift.tenant }} + tenant: {{ $storage.swift.tenant }} + {{- end }} + {{- if $storage.swift.tenantid }} + tenantid: {{ $storage.swift.tenantid }} + {{- end }} + {{- if $storage.swift.domain }} + domain: {{ $storage.swift.domain }} + {{- end }} + {{- if $storage.swift.domainid }} + domainid: {{ $storage.swift.domainid }} + {{- end }} + {{- if $storage.swift.trustid }} + trustid: {{ $storage.swift.trustid }} + {{- end }} + {{- if $storage.swift.insecureskipverify }} + insecureskipverify: {{ $storage.swift.insecureskipverify }} + {{- end }} + {{- if $storage.swift.chunksize }} + chunksize: {{ $storage.swift.chunksize }} + {{- end }} + {{- if $storage.swift.prefix }} + prefix: {{ $storage.swift.prefix }} + {{- end }} + {{- if $storage.swift.authversion }} + authversion: {{ $storage.swift.authversion }} + {{- end }} + {{- if $storage.swift.endpointtype }} + endpointtype: {{ $storage.swift.endpointtype }} + {{- end }} + {{- if $storage.swift.tempurlcontainerkey }} + tempurlcontainerkey: {{ $storage.swift.tempurlcontainerkey }} + {{- end }} + {{- if $storage.swift.tempurlmethods }} + tempurlmethods: {{ $storage.swift.tempurlmethods }} + {{- end }} + {{- else if eq $type "oss" }} + oss: + accesskeyid: {{ $storage.oss.accesskeyid }} + region: {{ $storage.oss.region }} + bucket: {{ $storage.oss.bucket }} + {{- if $storage.oss.endpoint }} + endpoint: {{ $storage.oss.bucket }}.{{ $storage.oss.endpoint }} + {{- end }} + {{- if $storage.oss.internal }} + internal: {{ $storage.oss.internal }} + {{- end }} + {{- if $storage.oss.encrypt }} + encrypt: {{ $storage.oss.encrypt }} + {{- end }} + {{- if $storage.oss.secure }} + secure: {{ $storage.oss.secure }} + {{- end }} + {{- if $storage.oss.chunksize }} + chunksize: {{ $storage.oss.chunksize }} + {{- end }} + {{- if $storage.oss.rootdirectory }} + rootdirectory: {{ $storage.oss.rootdirectory }} + {{- end }} + {{- end }} + cache: + layerinfo: redis + maintenance: + uploadpurging: + {{- if .Values.registry.upload_purging.enabled }} + enabled: true + age: {{ .Values.registry.upload_purging.age }} + interval: {{ .Values.registry.upload_purging.interval }} + dryrun: {{ .Values.registry.upload_purging.dryrun }} + {{- else }} + enabled: false + {{- end }} + delete: + enabled: true + redirect: + disable: {{ $storage.disableredirect }} + redis: + addr: {{ template "harbor.redis.addr" . }} + {{- if eq "redis+sentinel" (include "harbor.redis.scheme" .) }} + sentinelMasterSet: {{ template "harbor.redis.masterSet" . }} + {{- end }} + db: {{ template "harbor.redis.dbForRegistry" . }} + {{- if not (eq (include "harbor.redis.password" .) "") }} + password: {{ template "harbor.redis.password" . }} + {{- end }} + readtimeout: 10s + writetimeout: 10s + dialtimeout: 10s + pool: + maxidle: 100 + maxactive: 500 + idletimeout: 60s + http: + addr: :{{ template "harbor.registry.containerPort" . }} + relativeurls: {{ .Values.registry.relativeurls }} + {{- if .Values.internalTLS.enabled }} + tls: + certificate: /etc/harbor/ssl/registry/tls.crt + key: /etc/harbor/ssl/registry/tls.key + minimumtls: tls1.2 + {{- end }} + # set via environment variable + # secret: placeholder + debug: + {{- if .Values.metrics.enabled}} + addr: :{{ .Values.metrics.registry.port }} + prometheus: + enabled: true + path: {{ .Values.metrics.registry.path }} + {{- else }} + addr: localhost:5001 + {{- end }} + auth: + htpasswd: + realm: harbor-registry-basic-realm + path: /etc/registry/passwd + validation: + disabled: true + compatibility: + schema1: + enabled: true + + {{- if .Values.registry.middleware.enabled }} + {{- $middleware := .Values.registry.middleware }} + {{- $middlewareType := $middleware.type }} + {{- if eq $middlewareType "cloudFront" }} + middleware: + storage: + - name: cloudfront + options: + baseurl: {{ $middleware.cloudFront.baseurl }} + privatekey: /etc/registry/pk.pem + keypairid: {{ $middleware.cloudFront.keypairid }} + duration: {{ $middleware.cloudFront.duration }} + ipfilteredby: {{ $middleware.cloudFront.ipfilteredby }} + {{- end }} + {{- end }} + ctl-config.yml: |+ + --- + {{- if .Values.internalTLS.enabled }} + protocol: "https" + port: 8443 + https_config: + cert: "/etc/harbor/ssl/registry/tls.crt" + key: "/etc/harbor/ssl/registry/tls.key" + {{- else }} + protocol: "http" + port: 8080 + {{- end }} + log_level: {{ .Values.logLevel }} + registry_config: "/etc/registry/config.yml" diff --git a/helm-charts/harbor/templates/registry/registry-dpl.yaml b/helm-charts/harbor/templates/registry/registry-dpl.yaml new file mode 100644 index 0000000..b9c97ff --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-dpl.yaml @@ -0,0 +1,347 @@ +{{- $storage := .Values.persistence.imageChartStorage }} +{{- $type := $storage.type }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} + component: registry +spec: + replicas: {{ .Values.registry.replicas }} + revisionHistoryLimit: {{ .Values.registry.revisionHistoryLimit }} + strategy: + type: {{ .Values.updateStrategy.type }} + {{- if eq .Values.updateStrategy.type "Recreate" }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: registry + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: registry +{{- if .Values.registry.podLabels }} +{{ toYaml .Values.registry.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/configmap: {{ include (print $.Template.BasePath "/registry/registry-cm.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/registry/registry-secret.yaml") . | sha256sum }} + checksum/secret-jobservice: {{ include (print $.Template.BasePath "/jobservice/jobservice-secrets.yaml") . | sha256sum }} + checksum/secret-core: {{ include (print $.Template.BasePath "/core/core-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/registry/registry-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.registry.podAnnotations }} +{{ toYaml .Values.registry.podAnnotations | indent 8 }} +{{- end }} + spec: + securityContext: + runAsUser: 10000 + fsGroup: 10000 + fsGroupChangePolicy: OnRootMismatch +{{- if .Values.registry.serviceAccountName }} + serviceAccountName: {{ .Values.registry.serviceAccountName }} +{{- end -}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.registry.automountServiceAccountToken | default false }} + terminationGracePeriodSeconds: 120 +{{- with .Values.registry.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: registry +{{- end }} +{{- end }} + containers: + - name: registry + image: {{ .Values.registry.registry.image.repository }}:{{ .Values.registry.registry.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registry.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registry.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.registry.registry.resources }} + resources: +{{ toYaml .Values.registry.registry.resources | indent 10 }} +{{- end }} + args: ["serve", "/etc/registry/config.yml"] + envFrom: + - secretRef: + name: "{{ template "harbor.registry" . }}" + {{- if .Values.persistence.imageChartStorage.s3.existingSecret }} + - secretRef: + name: {{ .Values.persistence.imageChartStorage.s3.existingSecret }} + {{- end }} + env: + {{- if has "registry" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/registry/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/registry/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/registry/ca.crt + {{- end }} + {{- if .Values.redis.external.existingSecret }} + - name: REGISTRY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.redis.external.existingSecret }} + key: REDIS_PASSWORD + {{- end }} + {{- if .Values.persistence.imageChartStorage.azure.existingSecret }} + - name: REGISTRY_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.azure.existingSecret }} + key: AZURE_STORAGE_ACCESS_KEY + {{- end }} +{{- with .Values.registry.registry.extraEnvVars }} +{{- toYaml . | nindent 8 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.registry.containerPort" . }} + - containerPort: 5001 + volumeMounts: + - name: registry-data + mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} + subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} + - name: registry-htpasswd + mountPath: /etc/registry/passwd + subPath: passwd + - name: registry-config + mountPath: /etc/registry/config.yml + subPath: config.yml + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + mountPath: /etc/harbor/ssl/registry + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity) }} + - name: gcs-key + mountPath: /etc/registry/gcs-key.json + subPath: gcs-key.json + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + mountPath: /harbor_cust_cert/custom-ca-bundle.crt + subPath: ca.crt + {{- end }} + {{- if .Values.registry.middleware.enabled }} + {{- if eq .Values.registry.middleware.type "cloudFront" }} + - name: cloudfront-key + mountPath: /etc/registry/pk.pem + subPath: pk.pem + {{- end }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + - name: registryctl + image: {{ .Values.registry.controller.image.repository }}:{{ .Values.registry.controller.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: /api/health + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registryctl.containerPort" . }} + initialDelaySeconds: 300 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /api/health + scheme: {{ include "harbor.component.scheme" . | upper }} + port: {{ template "harbor.registryctl.containerPort" . }} + initialDelaySeconds: 1 + periodSeconds: 10 +{{- if .Values.registry.controller.resources }} + resources: +{{ toYaml .Values.registry.controller.resources | indent 10 }} +{{- end }} + envFrom: + - configMapRef: + name: "{{ template "harbor.registryCtl" . }}" + - secretRef: + name: "{{ template "harbor.registry" . }}" + - secretRef: + name: "{{ template "harbor.registryCtl" . }}" + {{- if .Values.persistence.imageChartStorage.s3.existingSecret }} + - secretRef: + name: {{ .Values.persistence.imageChartStorage.s3.existingSecret }} + {{- end }} + env: + - name: CORE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "harbor.core" . }} + key: secret + - name: JOBSERVICE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "harbor.jobservice" . }} + key: JOBSERVICE_SECRET + {{- if has "registry" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: INTERNAL_TLS_KEY_PATH + value: /etc/harbor/ssl/registry/tls.key + - name: INTERNAL_TLS_CERT_PATH + value: /etc/harbor/ssl/registry/tls.crt + - name: INTERNAL_TLS_TRUST_CA_PATH + value: /etc/harbor/ssl/registry/ca.crt + {{- end }} + {{- if .Values.redis.external.existingSecret }} + - name: REGISTRY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.redis.external.existingSecret }} + key: REDIS_PASSWORD + {{- end }} + {{- if .Values.persistence.imageChartStorage.azure.existingSecret }} + - name: REGISTRY_STORAGE_AZURE_ACCOUNTKEY + valueFrom: + secretKeyRef: + name: {{ .Values.persistence.imageChartStorage.azure.existingSecret }} + key: AZURE_STORAGE_ACCESS_KEY + {{- end }} +{{- with .Values.registry.controller.extraEnvVars }} +{{- toYaml . | nindent 8 }} +{{- end }} + ports: + - containerPort: {{ template "harbor.registryctl.containerPort" . }} + volumeMounts: + - name: registry-data + mountPath: {{ .Values.persistence.imageChartStorage.filesystem.rootdirectory }} + subPath: {{ .Values.persistence.persistentVolumeClaim.registry.subPath }} + - name: registry-config + mountPath: /etc/registry/config.yml + subPath: config.yml + - name: registry-config + mountPath: /etc/registryctl/config.yml + subPath: ctl-config.yml + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + mountPath: /etc/harbor/ssl/registry + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + mountPath: /harbor_cust_cert/custom-ca-bundle.crt + subPath: ca.crt + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity ) }} + - name: gcs-key + mountPath: /etc/registry/gcs-key.json + subPath: gcs-key.json + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 8 }} + {{- end }} + volumes: + - name: registry-htpasswd + secret: + {{- if not .Values.registry.credentials.existingSecret }} + secretName: {{ template "harbor.registry" . }}-htpasswd + {{ else }} + secretName: {{ .Values.registry.credentials.existingSecret }} + {{- end }} + items: + - key: REGISTRY_HTPASSWD + path: passwd + - name: registry-config + configMap: + name: "{{ template "harbor.registry" . }}" + - name: registry-data + {{- if and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "filesystem") }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.persistentVolumeClaim.registry.existingClaim | default (include "harbor.registry" .) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.internalTLS.enabled }} + - name: registry-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.registry.secretName" . }} + {{- end }} + {{- if and (and .Values.persistence.enabled (eq .Values.persistence.imageChartStorage.type "gcs")) (not .Values.persistence.imageChartStorage.gcs.useWorkloadIdentity ) }} + - name: gcs-key + secret: + {{- if and (eq $type "gcs") $storage.gcs.existingSecret }} + secretName: {{ $storage.gcs.existingSecret }} + {{- else }} + secretName: {{ template "harbor.registry" . }} + {{- end }} + items: + - key: GCS_KEY_DATA + path: gcs-key.json + {{- end }} + {{- if .Values.persistence.imageChartStorage.caBundleSecretName }} + - name: storage-service-ca + secret: + secretName: {{ .Values.persistence.imageChartStorage.caBundleSecretName }} + {{- end }} + {{- if .Values.registry.middleware.enabled }} + {{- if eq .Values.registry.middleware.type "cloudFront" }} + - name: cloudfront-key + secret: + secretName: {{ .Values.registry.middleware.cloudFront.privateKeySecret }} + items: + - key: CLOUDFRONT_KEY_DATA + path: pk.pem + {{- end }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- with .Values.registry.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.registry.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.registry.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.registry.priorityClassName }} + priorityClassName: {{ .Values.registry.priorityClassName }} + {{- end }} diff --git a/helm-charts/harbor/templates/registry/registry-pvc.yaml b/helm-charts/harbor/templates/registry/registry-pvc.yaml new file mode 100644 index 0000000..2112e22 --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-pvc.yaml @@ -0,0 +1,32 @@ +{{- if .Values.persistence.enabled }} +{{- $registry := .Values.persistence.persistentVolumeClaim.registry -}} +{{- if and (not $registry.existingClaim) (eq .Values.persistence.imageChartStorage.type "filesystem") }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "harbor.registry" . }} + annotations: + {{- range $key, $value := $registry.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if eq .Values.persistence.resourcePolicy "keep" }} + helm.sh/resource-policy: keep + {{- end }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: registry +spec: + accessModes: + - {{ $registry.accessMode }} + resources: + requests: + storage: {{ $registry.size }} + {{- if $registry.storageClass }} + {{- if eq "-" $registry.storageClass }} + storageClassName: "" + {{- else }} + storageClassName: {{ $registry.storageClass }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/registry/registry-secret.yaml b/helm-charts/harbor/templates/registry/registry-secret.yaml new file mode 100644 index 0000000..5294629 --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-secret.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + REGISTRY_HTTP_SECRET: {{ .Values.registry.secret | default (randAlphaNum 16) | b64enc | quote }} + {{- if not .Values.redis.external.existingSecret }} + REGISTRY_REDIS_PASSWORD: {{ include "harbor.redis.password" . | b64enc | quote }} + {{- end }} + {{- $storage := .Values.persistence.imageChartStorage }} + {{- $type := $storage.type }} + {{- if and (eq $type "azure") (not $storage.azure.existingSecret) }} + REGISTRY_STORAGE_AZURE_ACCOUNTKEY: {{ $storage.azure.accountkey | b64enc | quote }} + {{- else if and (and (eq $type "gcs") (not $storage.gcs.existingSecret)) (not $storage.gcs.useWorkloadIdentity) }} + GCS_KEY_DATA: {{ $storage.gcs.encodedkey | quote }} + {{- else if eq $type "s3" }} + {{- if and (not $storage.s3.existingSecret) ($storage.s3.accesskey) }} + REGISTRY_STORAGE_S3_ACCESSKEY: {{ $storage.s3.accesskey | b64enc | quote }} + {{- end }} + {{- if and (not $storage.s3.existingSecret) ($storage.s3.secretkey) }} + REGISTRY_STORAGE_S3_SECRETKEY: {{ $storage.s3.secretkey | b64enc | quote }} + {{- end }} + {{- else if eq $type "swift" }} + REGISTRY_STORAGE_SWIFT_PASSWORD: {{ $storage.swift.password | b64enc | quote }} + {{- if $storage.swift.secretkey }} + REGISTRY_STORAGE_SWIFT_SECRETKEY: {{ $storage.swift.secretkey | b64enc | quote }} + {{- end }} + {{- if $storage.swift.accesskey }} + REGISTRY_STORAGE_SWIFT_ACCESSKEY: {{ $storage.swift.accesskey | b64enc | quote }} + {{- end }} + {{- else if eq $type "oss" }} + REGISTRY_STORAGE_OSS_ACCESSKEYSECRET: {{ $storage.oss.accesskeysecret | b64enc | quote }} + {{- end }} +{{- if not .Values.registry.credentials.existingSecret }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registry" . }}-htpasswd" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- if .Values.registry.credentials.htpasswdString }} + REGISTRY_HTPASSWD: {{ .Values.registry.credentials.htpasswdString | b64enc | quote }} + {{- else }} + REGISTRY_HTPASSWD: {{ htpasswd .Values.registry.credentials.username .Values.registry.credentials.password | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/registry/registry-svc.yaml b/helm-charts/harbor/templates/registry/registry-svc.yaml new file mode 100644 index 0000000..749690e --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-svc.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.registry" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-registry" "http-registry" .Values.internalTLS.enabled }} + port: {{ template "harbor.registry.servicePort" . }} + + - name: {{ ternary "https-controller" "http-controller" .Values.internalTLS.enabled }} + port: {{ template "harbor.registryctl.servicePort" . }} +{{- if .Values.metrics.enabled}} + - name: {{ template "harbor.metricsPortName" . }} + port: {{ .Values.metrics.registry.port }} +{{- end }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: registry \ No newline at end of file diff --git a/helm-charts/harbor/templates/registry/registry-tls.yaml b/helm-charts/harbor/templates/registry/registry-tls.yaml new file mode 100644 index 0000000..9d1862c --- /dev/null +++ b/helm-charts/harbor/templates/registry/registry-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.registry.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} + tls.crt: {{ (required "The \"internalTLS.registry.crt\" is required!" .Values.internalTLS.registry.crt) | b64enc | quote }} + tls.key: {{ (required "The \"internalTLS.registry.key\" is required!" .Values.internalTLS.registry.key) | b64enc | quote }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/registry/registryctl-cm.yaml b/helm-charts/harbor/templates/registry/registryctl-cm.yaml new file mode 100644 index 0000000..87aa5ff --- /dev/null +++ b/helm-charts/harbor/templates/registry/registryctl-cm.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: "{{ template "harbor.registryCtl" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +data: + {{- template "harbor.traceEnvsForRegistryCtl" . }} diff --git a/helm-charts/harbor/templates/registry/registryctl-secret.yaml b/helm-charts/harbor/templates/registry/registryctl-secret.yaml new file mode 100644 index 0000000..7009770 --- /dev/null +++ b/helm-charts/harbor/templates/registry/registryctl-secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.registryCtl" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + {{- template "harbor.traceJaegerPassword" . }} \ No newline at end of file diff --git a/helm-charts/harbor/templates/trivy/trivy-secret.yaml b/helm-charts/harbor/templates/trivy/trivy-secret.yaml new file mode 100644 index 0000000..84652c7 --- /dev/null +++ b/helm-charts/harbor/templates/trivy/trivy-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.trivy.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "harbor.trivy" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} +type: Opaque +data: + redisURL: {{ include "harbor.redis.urlForTrivy" . | b64enc }} + gitHubToken: {{ .Values.trivy.gitHubToken | default "" | b64enc | quote }} +{{- end }} diff --git a/helm-charts/harbor/templates/trivy/trivy-sts.yaml b/helm-charts/harbor/templates/trivy/trivy-sts.yaml new file mode 100644 index 0000000..aba23c9 --- /dev/null +++ b/helm-charts/harbor/templates/trivy/trivy-sts.yaml @@ -0,0 +1,222 @@ +{{- if .Values.trivy.enabled }} +{{- $trivy := .Values.persistence.persistentVolumeClaim.trivy }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "harbor.trivy" . }} + labels: +{{ include "harbor.labels" . | indent 4 }} + component: trivy +spec: + replicas: {{ .Values.trivy.replicas }} + serviceName: {{ template "harbor.trivy" . }} + selector: + matchLabels: +{{ include "harbor.matchLabels" . | indent 6 }} + component: trivy + template: + metadata: + labels: +{{ include "harbor.labels" . | indent 8 }} + component: trivy +{{- if .Values.trivy.podLabels }} +{{ toYaml .Values.trivy.podLabels | indent 8 }} +{{- end }} + annotations: + checksum/secret: {{ include (print $.Template.BasePath "/trivy/trivy-secret.yaml") . | sha256sum }} +{{- if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "auto") }} + checksum/tls: {{ include (print $.Template.BasePath "/internal/auto-tls.yaml") . | sha256sum }} +{{- else if and .Values.internalTLS.enabled (eq .Values.internalTLS.certSource "manual") }} + checksum/tls: {{ include (print $.Template.BasePath "/trivy/trivy-tls.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.trivy.podAnnotations }} +{{ toYaml .Values.trivy.podAnnotations | indent 8 }} +{{- end }} + spec: +{{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} +{{- end }} +{{- if .Values.trivy.serviceAccountName }} + serviceAccountName: {{ .Values.trivy.serviceAccountName }} +{{- end }} + securityContext: + runAsUser: 10000 + fsGroup: 10000 + automountServiceAccountToken: {{ .Values.trivy.automountServiceAccountToken | default false }} +{{- with .Values.trivy.topologySpreadConstraints}} + topologySpreadConstraints: +{{- range . }} + - {{ . | toYaml | indent 8 | trim }} + labelSelector: + matchLabels: +{{ include "harbor.matchLabels" $ | indent 12 }} + component: trivy +{{- end }} +{{- end }} + containers: + - name: trivy + image: {{ .Values.trivy.image.repository }}:{{ .Values.trivy.image.tag }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + securityContext: + privileged: false + allowPrivilegeEscalation: false + env: + {{- if has "trivy" .Values.proxy.components }} + - name: HTTP_PROXY + value: "{{ .Values.proxy.httpProxy }}" + - name: HTTPS_PROXY + value: "{{ .Values.proxy.httpsProxy }}" + - name: NO_PROXY + value: "{{ template "harbor.noProxy" . }}" + {{- end }} + - name: "SCANNER_LOG_LEVEL" + value: {{ .Values.logLevel | quote }} + - name: "SCANNER_TRIVY_CACHE_DIR" + value: "/home/scanner/.cache/trivy" + - name: "SCANNER_TRIVY_REPORTS_DIR" + value: "/home/scanner/.cache/reports" + - name: "SCANNER_TRIVY_DEBUG_MODE" + value: {{ .Values.trivy.debugMode | quote }} + - name: "SCANNER_TRIVY_VULN_TYPE" + value: {{ .Values.trivy.vulnType | quote }} + - name: "SCANNER_TRIVY_TIMEOUT" + value: {{ .Values.trivy.timeout | quote }} + - name: "SCANNER_TRIVY_GITHUB_TOKEN" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: gitHubToken + - name: "SCANNER_TRIVY_SEVERITY" + value: {{ .Values.trivy.severity | quote }} + - name: "SCANNER_TRIVY_IGNORE_UNFIXED" + value: {{ .Values.trivy.ignoreUnfixed | default false | quote }} + - name: "SCANNER_TRIVY_SKIP_UPDATE" + value: {{ .Values.trivy.skipUpdate | default false | quote }} + - name: "SCANNER_TRIVY_OFFLINE_SCAN" + value: {{ .Values.trivy.offlineScan | default false | quote }} + - name: "SCANNER_TRIVY_SECURITY_CHECKS" + value: {{ .Values.trivy.securityCheck | quote }} + - name: "SCANNER_TRIVY_INSECURE" + value: {{ .Values.trivy.insecure | default false | quote }} + - name: SCANNER_API_SERVER_ADDR + value: ":{{ template "harbor.trivy.containerPort" . }}" + {{- if .Values.internalTLS.enabled }} + - name: INTERNAL_TLS_ENABLED + value: "true" + - name: SCANNER_API_SERVER_TLS_KEY + value: /etc/harbor/ssl/trivy/tls.key + - name: SCANNER_API_SERVER_TLS_CERTIFICATE + value: /etc/harbor/ssl/trivy/tls.crt + {{- end }} + - name: "SCANNER_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL + - name: "SCANNER_STORE_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL + - name: "SCANNER_JOB_QUEUE_REDIS_URL" + valueFrom: + secretKeyRef: + name: {{ template "harbor.trivy" . }} + key: redisURL +{{- with .Values.trivy.extraEnvVars }} +{{- toYaml . | nindent 12 }} +{{- end }} + ports: + - name: api-server + containerPort: {{ template "harbor.trivy.containerPort" . }} + volumeMounts: + - name: data + mountPath: /home/scanner/.cache + subPath: {{ .Values.persistence.persistentVolumeClaim.trivy.subPath }} + readOnly: false + {{- if .Values.internalTLS.enabled }} + - name: trivy-internal-certs + mountPath: /etc/harbor/ssl/trivy + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolumeMount" . | indent 10 }} + {{- end }} + livenessProbe: + httpGet: + scheme: {{ include "harbor.component.scheme" . | upper }} + path: /probe/healthy + port: api-server + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 10 + readinessProbe: + httpGet: + scheme: {{ include "harbor.component.scheme" . | upper }} + path: /probe/ready + port: api-server + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + resources: +{{ toYaml .Values.trivy.resources | indent 12 }} + {{- if or (or .Values.internalTLS.enabled .Values.caBundleSecretName) (or (not .Values.persistence.enabled) $trivy.existingClaim) }} + volumes: + {{- if .Values.internalTLS.enabled }} + - name: trivy-internal-certs + secret: + secretName: {{ template "harbor.internalTLS.trivy.secretName" . }} + {{- end }} + {{- if .Values.caBundleSecretName }} +{{ include "harbor.caBundleVolume" . | indent 6 }} + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: "data" + emptyDir: {} + {{- else if $trivy.existingClaim }} + - name: "data" + persistentVolumeClaim: + claimName: {{ $trivy.existingClaim }} + {{- end }} + {{- end }} + {{- with .Values.trivy.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.trivy.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.trivy.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.trivy.priorityClassName }} + priorityClassName: {{ .Values.trivy.priorityClassName }} + {{- end }} +{{- if and .Values.persistence.enabled (not $trivy.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + labels: +{{ include "harbor.labels" . | indent 8 }} + annotations: + {{- range $key, $value := $trivy.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + accessModes: [{{ $trivy.accessMode | quote }}] + {{- if $trivy.storageClass }} + {{- if (eq "-" $trivy.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ $trivy.storageClass }}" + {{- end }} + {{- end }} + resources: + requests: + storage: {{ $trivy.size | quote }} +{{- end }} +{{- end }} diff --git a/helm-charts/harbor/templates/trivy/trivy-svc.yaml b/helm-charts/harbor/templates/trivy/trivy-svc.yaml new file mode 100644 index 0000000..24daf09 --- /dev/null +++ b/helm-charts/harbor/templates/trivy/trivy-svc.yaml @@ -0,0 +1,16 @@ +{{ if .Values.trivy.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: "{{ template "harbor.trivy" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +spec: + ports: + - name: {{ ternary "https-trivy" "http-trivy" .Values.internalTLS.enabled }} + protocol: TCP + port: {{ template "harbor.trivy.servicePort" . }} + selector: +{{ include "harbor.matchLabels" . | indent 4 }} + component: trivy +{{ end }} diff --git a/helm-charts/harbor/templates/trivy/trivy-tls.yaml b/helm-charts/harbor/templates/trivy/trivy-tls.yaml new file mode 100644 index 0000000..a9c8330 --- /dev/null +++ b/helm-charts/harbor/templates/trivy/trivy-tls.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.trivy.enabled .Values.internalTLS.enabled }} +{{- if eq .Values.internalTLS.certSource "manual" }} +apiVersion: v1 +kind: Secret +metadata: + name: "{{ template "harbor.internalTLS.trivy.secretName" . }}" + labels: +{{ include "harbor.labels" . | indent 4 }} +type: kubernetes.io/tls +data: + ca.crt: {{ (required "The \"internalTLS.trustCa\" is required!" .Values.internalTLS.trustCa) | b64enc | quote }} + tls.crt: {{ (required "The \"internalTLS.trivy.crt\" is required!" .Values.internalTLS.trivy.crt) | b64enc | quote }} + tls.key: {{ (required "The \"internalTLS.trivy.key\" is required!" .Values.internalTLS.trivy.key) | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/helm-charts/harbor/values.yaml b/helm-charts/harbor/values.yaml new file mode 100644 index 0000000..8ab994a --- /dev/null +++ b/helm-charts/harbor/values.yaml @@ -0,0 +1,963 @@ +expose: + # Set how to expose the service. Set the type as "ingress", "clusterIP", "nodePort" or "loadBalancer" + # and fill the information in the corresponding section + type: loadBalancer + tls: + # Enable TLS or not. + # Delete the "ssl-redirect" annotations in "expose.ingress.annotations" when TLS is disabled and "expose.type" is "ingress" + # Note: if the "expose.type" is "ingress" and TLS is disabled, + # the port must be included in the command when pulling/pushing images. + # Refer to https://github.com/goharbor/harbor/issues/5291 for details. + enabled: false + # The source of the tls certificate. Set as "auto", "secret" + # or "none" and fill the information in the corresponding section + # 1) auto: generate the tls certificate automatically + # 2) secret: read the tls certificate from the specified secret. + # The tls certificate can be generated manually or by cert manager + # 3) none: configure no tls certificate for the ingress. If the default + # tls certificate is configured in the ingress controller, choose this option + certSource: auto + auto: + # The common name used to generate the certificate, it's necessary + # when the type isn't "ingress" + commonName: "" + secret: + # The name of secret which contains keys named: + # "tls.crt" - the certificate + # "tls.key" - the private key + secretName: "" + ingress: + hosts: + core: harbor.guaranteedstruggle.host + # set to the type of ingress controller if it has specific requirements. + # leave as `default` for most ingress controllers. + # set to `gce` if using the GCE ingress controller + # set to `ncp` if using the NCP (NSX-T Container Plugin) ingress controller + # set to `alb` if using the ALB ingress controller + # set to `f5-bigip` if using the F5 BIG-IP ingress controller + controller: default + ## Allow .Capabilities.KubeVersion.Version to be overridden while creating ingress + kubeVersionOverride: "" + className: "" + annotations: + # note different ingress controllers may require a different ssl-redirect annotation + # for Envoy, use ingress.kubernetes.io/force-ssl-redirect: "true" and remove the nginx lines below + ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + harbor: + # harbor ingress-specific annotations + annotations: {} + # harbor ingress-specific labels + labels: {} + clusterIP: + # The name of ClusterIP service + name: harbor + # Annotations on the ClusterIP service + annotations: {} + ports: + # The service port Harbor listens on when serving HTTP + httpPort: 80 + # The service port Harbor listens on when serving HTTPS + httpsPort: 443 + nodePort: + # The name of NodePort service + name: harbor + ports: + http: + # The service port Harbor listens on when serving HTTP + port: 80 + # The node port Harbor listens on when serving HTTP + nodePort: 30002 + https: + # The service port Harbor listens on when serving HTTPS + port: 443 + # The node port Harbor listens on when serving HTTPS + nodePort: 30003 + loadBalancer: + # The name of LoadBalancer service + name: harbor + # Set the IP if the LoadBalancer supports assigning IP + IP: "" + ports: + # The service port Harbor listens on when serving HTTP + httpPort: 80 + # The service port Harbor listens on when serving HTTPS + #httpsPort: 443 + annotations: {} + sourceRanges: [] + +# The external URL for Harbor core service. It is used to +# 1) populate the docker/helm commands showed on portal +# 2) populate the token service URL returned to docker client +# +# Format: protocol://domain[:port]. Usually: +# 1) if "expose.type" is "ingress", the "domain" should be +# the value of "expose.ingress.hosts.core" +# 2) if "expose.type" is "clusterIP", the "domain" should be +# the value of "expose.clusterIP.name" +# 3) if "expose.type" is "nodePort", the "domain" should be +# the IP address of k8s node +# +# If Harbor is deployed behind the proxy, set it as the URL of proxy +externalURL: https://harbor.guaranteedstruggle.host + +# The internal TLS used for harbor components secure communicating. In order to enable https +# in each component tls cert files need to provided in advance. +internalTLS: + # If internal TLS enabled + enabled: false + # enable strong ssl ciphers (default: false) + strong_ssl_ciphers: false + # There are three ways to provide tls + # 1) "auto" will generate cert automatically + # 2) "manual" need provide cert file manually in following value + # 3) "secret" internal certificates from secret + certSource: "auto" + # The content of trust ca, only available when `certSource` is "manual" + trustCa: "" + # core related cert configuration + core: + # secret name for core's tls certs + secretName: "" + # Content of core's TLS cert file, only available when `certSource` is "manual" + crt: "" + # Content of core's TLS key file, only available when `certSource` is "manual" + key: "" + # jobservice related cert configuration + jobservice: + # secret name for jobservice's tls certs + secretName: "" + # Content of jobservice's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of jobservice's TLS key file, only available when `certSource` is "manual" + key: "" + # registry related cert configuration + registry: + # secret name for registry's tls certs + secretName: "" + # Content of registry's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of registry's TLS key file, only available when `certSource` is "manual" + key: "" + # portal related cert configuration + portal: + # secret name for portal's tls certs + secretName: "" + # Content of portal's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of portal's TLS key file, only available when `certSource` is "manual" + key: "" + # trivy related cert configuration + trivy: + # secret name for trivy's tls certs + secretName: "" + # Content of trivy's TLS key file, only available when `certSource` is "manual" + crt: "" + # Content of trivy's TLS key file, only available when `certSource` is "manual" + key: "" + +ipFamily: + # ipv6Enabled set to true if ipv6 is enabled in cluster, currently it affected the nginx related component + ipv6: + enabled: false + # ipv4Enabled set to true if ipv4 is enabled in cluster, currently it affected the nginx related component + ipv4: + enabled: true + +# The persistence is enabled by default and a default StorageClass +# is needed in the k8s cluster to provision volumes dynamically. +# Specify another StorageClass in the "storageClass" or set "existingClaim" +# if you already have existing persistent volumes to use +# +# For storing images and charts, you can also use "azure", "gcs", "s3", +# "swift" or "oss". Set it in the "imageChartStorage" section +persistence: + enabled: true + # Setting it to "keep" to avoid removing PVCs during a helm delete + # operation. Leaving it empty will delete PVCs after the chart deleted + # (this does not apply for PVCs that are created for internal database + # and redis components, i.e. they are never deleted automatically) + resourcePolicy: "keep" + persistentVolumeClaim: + registry: + # Use the existing PVC which must be created manually before bound, + # and specify the "subPath" if the PVC is shared with other components + existingClaim: "" + # Specify the "storageClass" used to provision the volume. Or the default + # StorageClass will be used (the default). + # Set it to "-" to disable dynamic provisioning + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 5Gi + annotations: {} + jobservice: + jobLog: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + # If external database is used, the following settings for database will + # be ignored + database: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + # If external Redis is used, the following settings for Redis will + # be ignored + redis: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 1Gi + annotations: {} + trivy: + existingClaim: "" + storageClass: "" + subPath: "" + accessMode: ReadWriteOnce + size: 5Gi + annotations: {} + # Define which storage backend is used for registry to store + # images and charts. Refer to + # https://github.com/distribution/distribution/blob/main/docs/configuration.md#storage + # for the detail. + imageChartStorage: + # Specify whether to disable `redirect` for images and chart storage, for + # backends which not supported it (such as using minio for `s3` storage type), please disable + # it. To disable redirects, simply set `disableredirect` to `true` instead. + # Refer to + # https://github.com/distribution/distribution/blob/main/docs/configuration.md#redirect + # for the detail. + disableredirect: false + # Specify the "caBundleSecretName" if the storage service uses a self-signed certificate. + # The secret must contain keys named "ca.crt" which will be injected into the trust store + # of registry's containers. + # caBundleSecretName: + + # Specify the type of storage: "filesystem", "azure", "gcs", "s3", "swift", + # "oss" and fill the information needed in the corresponding section. The type + # must be "filesystem" if you want to use persistent volumes for registry + type: filesystem + filesystem: + rootdirectory: /storage + #maxthreads: 100 + azure: + accountname: accountname + accountkey: base64encodedaccountkey + container: containername + #realm: core.windows.net + # To use existing secret, the key must be AZURE_STORAGE_ACCESS_KEY + existingSecret: "" + gcs: + bucket: bucketname + # The base64 encoded json file which contains the key + encodedkey: base64-encoded-json-key-file + #rootdirectory: /gcs/object/name/prefix + #chunksize: "5242880" + # To use existing secret, the key must be GCS_KEY_DATA + existingSecret: "" + useWorkloadIdentity: false + s3: + # Set an existing secret for S3 accesskey and secretkey + # keys in the secret should be REGISTRY_STORAGE_S3_ACCESSKEY and REGISTRY_STORAGE_S3_SECRETKEY for registry + #existingSecret: "" + region: us-west-1 + bucket: bucketname + #accesskey: awsaccesskey + #secretkey: awssecretkey + #regionendpoint: http://myobjects.local + #encrypt: false + #keyid: mykeyid + #secure: true + #skipverify: false + #v4auth: true + #chunksize: "5242880" + #rootdirectory: /s3/object/name/prefix + #storageclass: STANDARD + #multipartcopychunksize: "33554432" + #multipartcopymaxconcurrency: 100 + #multipartcopythresholdsize: "33554432" + swift: + authurl: https://storage.myprovider.com/v3/auth + username: username + password: password + container: containername + #region: fr + #tenant: tenantname + #tenantid: tenantid + #domain: domainname + #domainid: domainid + #trustid: trustid + #insecureskipverify: false + #chunksize: 5M + #prefix: + #secretkey: secretkey + #accesskey: accesskey + #authversion: 3 + #endpointtype: public + #tempurlcontainerkey: false + #tempurlmethods: + oss: + accesskeyid: accesskeyid + accesskeysecret: accesskeysecret + region: regionname + bucket: bucketname + #endpoint: endpoint + #internal: false + #encrypt: false + #secure: true + #chunksize: 10M + #rootdirectory: rootdirectory + +imagePullPolicy: IfNotPresent + +# Use this set to assign a list of default pullSecrets +imagePullSecrets: +# - name: docker-registry-secret +# - name: internal-registry-secret + +# The update strategy for deployments with persistent volumes(jobservice, registry): "RollingUpdate" or "Recreate" +# Set it as "Recreate" when "RWM" for volumes isn't supported +updateStrategy: + type: RollingUpdate + +# debug, info, warning, error or fatal +logLevel: info + +# The initial password of Harbor admin. Change it from portal after launching Harbor +# or give an existing secret for it +# key in secret is given via (default to HARBOR_ADMIN_PASSWORD) +# existingSecretAdminPassword: +existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD +harborAdminPassword: "admin2ch" + +# The name of the secret which contains key named "ca.crt". Setting this enables the +# download link on portal to download the CA certificate when the certificate isn't +# generated automatically +caSecretName: "" + +# The secret key used for encryption. Must be a string of 16 chars. +secretKey: "not-a-secure-key" +# If using existingSecretSecretKey, the key must be secretKey +existingSecretSecretKey: "" + +# The proxy settings for updating trivy vulnerabilities from the Internet and replicating +# artifacts from/to the registries that cannot be reached directly +proxy: + httpProxy: + httpsProxy: + noProxy: 127.0.0.1,localhost,.local,.internal + components: + - core + - jobservice + - trivy + +# Run the migration job via helm hook +enableMigrateHelmHook: false + +# The custom ca bundle secret, the secret must contain key named "ca.crt" +# which will be injected into the trust store for core, jobservice, registry, trivy components +# caBundleSecretName: "" + +## UAA Authentication Options +# If you're using UAA for authentication behind a self-signed +# certificate you will need to provide the CA Cert. +# Set uaaSecretName below to provide a pre-created secret that +# contains a base64 encoded CA Certificate named `ca.crt`. +# uaaSecretName: + +# If service exposed via "ingress", the Nginx will not be used +nginx: + image: + repository: goharbor/nginx-photon + tag: v2.9.1 + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + +portal: + image: + repository: goharbor/harbor-portal + tag: v2.9.1 + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + +core: + image: + repository: goharbor/harbor-core + tag: v2.9.1 + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + replicas: 1 + revisionHistoryLimit: 10 + ## Startup probe values + startupProbe: + enabled: true + initialDelaySeconds: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## Additional service annotations + serviceAnnotations: {} + ## User settings configuration json string + configureUserSettings: + # The provider for updating project quota(usage), there are 2 options, redis or db. + # By default it is implemented by db but you can configure it to redis which + # can improve the performance of high concurrent pushing to the same project, + # and reduce the database connections spike and occupies. + # Using redis will bring up some delay for quota usage updation for display, so only + # suggest switch provider to redis if you were ran into the db connections spike around + # the scenario of high concurrent pushing to same project, no improvment for other scenes. + quotaUpdateProvider: db # Or redis + # Secret is used when core server communicates with other components. + # If a secret key is not specified, Helm will generate one. + # Must be a string of 16 chars. + secret: "" + # Fill in the name of a kubernetes secret if you want to use your own + # TLS certificate and private key for token encryption/decryption. + # The secret must contain keys named: + # "tls.key" - the private key + # "tls.crt" - the certificate + secretName: "" + # If not specifying a preexisting secret, a secret can be created from tokenKey and tokenCert and used instead. + # If none of secretName, tokenKey, and tokenCert are specified, an ephemeral key and certificate will be autogenerated. + # tokenKey and tokenCert must BOTH be set or BOTH unset. + # The tokenKey value is formatted as a multiline string containing a PEM-encoded RSA key, indented one more than tokenKey on the following line. + tokenKey: | + # If tokenKey is set, the value of tokenCert must be set as a PEM-encoded certificate signed by tokenKey, and supplied as a multiline string, indented one more than tokenCert on the following line. + tokenCert: | + # The XSRF key. Will be generated automatically if it isn't specified + xsrfKey: "" + ## The priority class to run the pod as + priorityClassName: + # The time duration for async update artifact pull_time and repository + # pull_count, the unit is second. Will be 10 seconds if it isn't set. + # eg. artifactPullAsyncFlushDuration: 10 + artifactPullAsyncFlushDuration: + gdpr: + deleteUser: false + +jobservice: + image: + repository: goharbor/harbor-jobservice + tag: v2.9.1 + replicas: 1 + revisionHistoryLimit: 10 + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + maxJobWorkers: 10 + # The logger for jobs: "file", "database" or "stdout" + jobLoggers: + - file + # - database + # - stdout + # The jobLogger sweeper duration (ignored if `jobLogger` is `stdout`) + loggerSweeperDuration: 14 #days + notification: + webhook_job_max_retry: 3 + webhook_job_http_client_timeout: 3 # in seconds + reaper: + # the max time to wait for a task to finish, if unfinished after max_update_hours, the task will be mark as error, but the task will continue to run, default value is 24 + max_update_hours: 24 + # the max time for execution in running state without new task created + max_dangling_hours: 168 + + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + # Secret is used when job service communicates with other components. + # If a secret key is not specified, Helm will generate one. + # Must be a string of 16 chars. + secret: "" + ## The priority class to run the pod as + priorityClassName: + +registry: + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + registry: + image: + repository: goharbor/registry-photon + tag: v2.9.1 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + controller: + image: + repository: goharbor/harbor-registryctl + tag: v2.9.1 + + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + replicas: 1 + revisionHistoryLimit: 10 + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + # Secret is used to secure the upload state from client + # and registry storage backend. + # See: https://github.com/distribution/distribution/blob/main/docs/configuration.md#http + # If a secret key is not specified, Helm will generate one. + # Must be a string of 16 chars. + secret: "" + # If true, the registry returns relative URLs in Location headers. The client is responsible for resolving the correct URL. + relativeurls: true + credentials: + username: "harbor_registry_user" + password: "harbor_registry_password" + # If using existingSecret, the key must be REGISTRY_PASSWD and REGISTRY_HTPASSWD + existingSecret: "" + # Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.credentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which generates different lines each time because of the salt. + # htpasswdString: $apr1$XLefHzeG$Xl4.s00sMSCCcMyJljSZb0 # example string + middleware: + enabled: false + type: cloudFront + cloudFront: + baseurl: example.cloudfront.net + keypairid: KEYPAIRID + duration: 3000s + ipfilteredby: none + # The secret key that should be present is CLOUDFRONT_KEY_DATA, which should be the encoded private key + # that allows access to CloudFront + privateKeySecret: "my-secret" + # enable purge _upload directories + upload_purging: + enabled: true + # remove files in _upload directories which exist for a period of time, default is one week. + age: 168h + # the interval of the purge operations + interval: 24h + dryrun: false + +trivy: + # enabled the flag to enable Trivy scanner + enabled: true + image: + # repository the repository for Trivy adapter image + repository: goharbor/trivy-adapter-photon + # tag the tag for Trivy adapter image + tag: v2.9.1 + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + # replicas the number of Pod replicas + replicas: 1 + # debugMode the flag to enable Trivy debug mode with more verbose scanning log + debugMode: false + # vulnType a comma-separated list of vulnerability types. Possible values are `os` and `library`. + vulnType: "os,library" + # severity a comma-separated list of severities to be checked + severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL" + # ignoreUnfixed the flag to display only fixed vulnerabilities + ignoreUnfixed: false + # insecure the flag to skip verifying registry certificate + insecure: false + # gitHubToken the GitHub access token to download Trivy DB + # + # Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases. + # It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached + # in the local file system (`/home/scanner/.cache/trivy/db/trivy.db`). In addition, the database contains the update + # timestamp so Trivy can detect whether it should download a newer version from the Internet or use the cached one. + # Currently, the database is updated every 12 hours and published as a new release to GitHub. + # + # Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough + # for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000 + # requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult + # https://developer.github.com/v3/#rate-limiting + # + # You can create a GitHub token by following the instructions in + # https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line + gitHubToken: "" + # skipUpdate the flag to disable Trivy DB downloads from GitHub + # + # You might want to set the value of this flag to `true` in test or CI/CD environments to avoid GitHub rate limiting issues. + # If the value is set to `true` you have to manually download the `trivy.db` file and mount it in the + # `/home/scanner/.cache/trivy/db/trivy.db` path. + skipUpdate: false + # The offlineScan option prevents Trivy from sending API requests to identify dependencies. + # + # Scanning JAR files and pom.xml may require Internet access for better detection, but this option tries to avoid it. + # For example, the offline mode will not try to resolve transitive dependencies in pom.xml when the dependency doesn't + # exist in the local repositories. It means a number of detected vulnerabilities might be fewer in offline mode. + # It would work if all the dependencies are in local. + # This option doesn’t affect DB download. You need to specify skipUpdate as well as offlineScan in an air-gapped environment. + offlineScan: false + # Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. Defaults to `vuln`. + securityCheck: "vuln" + # The duration to wait for scan completion + timeout: 5m0s + resources: + requests: + cpu: 200m + memory: 512Mi + limits: + cpu: 1 + memory: 1Gi + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + ## The priority class to run the pod as + priorityClassName: + +database: + # if external database is used, set "type" to "external" + # and fill the connection information in "external" section + type: internal + internal: + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + image: + repository: goharbor/harbor-db + tag: v2.9.1 + # The initial superuser password for internal database + password: "changeit" + # The size limit for Shared memory, pgSQL use it for shared_buffer + # More details see: + # https://github.com/goharbor/harbor/issues/15034 + shmSizeLimit: 512Mi + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + # The timeout used in livenessProbe; 1 to 5 seconds + livenessProbe: + timeoutSeconds: 1 + # The timeout used in readinessProbe; 1 to 5 seconds + readinessProbe: + timeoutSeconds: 1 + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ## The priority class to run the pod as + priorityClassName: + initContainer: + migrator: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + permissions: {} + # resources: + # requests: + # memory: 128Mi + # cpu: 100m + external: + host: "192.168.0.1" + port: "5432" + username: "user" + password: "password" + coreDatabase: "registry" + # if using existing secret, the key must be "password" + existingSecret: "" + # "disable" - No SSL + # "require" - Always SSL (skip verification) + # "verify-ca" - Always SSL (verify that the certificate presented by the + # server was signed by a trusted CA) + # "verify-full" - Always SSL (verify that the certification presented by the + # server was signed by a trusted CA and the server host name matches the one + # in the certificate) + sslmode: "disable" + # The maximum number of connections in the idle connection pool per pod (core+exporter). + # If it <=0, no idle connections are retained. + maxIdleConns: 100 + # The maximum number of open connections to the database per pod (core+exporter). + # If it <= 0, then there is no limit on the number of open connections. + # Note: the default number of connections is 1024 for postgre of harbor. + maxOpenConns: 900 + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + +redis: + # if external Redis is used, set "type" to "external" + # and fill the connection information in "external" section + type: internal + internal: + # set the service account to be used, default if left empty + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + image: + repository: goharbor/redis-photon + tag: v2.9.1 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + nodeSelector: {} + tolerations: [] + affinity: {} + ## The priority class to run the pod as + priorityClassName: + # # jobserviceDatabaseIndex defaults to "1" + # # registryDatabaseIndex defaults to "2" + # # trivyAdapterIndex defaults to "5" + # # harborDatabaseIndex defaults to "0", but it can be configured to "6", this config is optional + # # cacheLayerDatabaseIndex defaults to "0", but it can be configured to "7", this config is optional + jobserviceDatabaseIndex: "1" + registryDatabaseIndex: "2" + trivyAdapterIndex: "5" + # harborDatabaseIndex: "6" + # cacheLayerDatabaseIndex: "7" + external: + # support redis, redis+sentinel + # addr for redis: : + # addr for redis+sentinel: :,:,: + addr: "192.168.0.2:6379" + # The name of the set of Redis instances to monitor, it must be set to support redis+sentinel + sentinelMasterSet: "" + # The "coreDatabaseIndex" must be "0" as the library Harbor + # used doesn't support configuring it + # harborDatabaseIndex defaults to "0", but it can be configured to "6", this config is optional + # cacheLayerDatabaseIndex defaults to "0", but it can be configured to "7", this config is optional + coreDatabaseIndex: "0" + jobserviceDatabaseIndex: "1" + registryDatabaseIndex: "2" + trivyAdapterIndex: "5" + # harborDatabaseIndex: "6" + # cacheLayerDatabaseIndex: "7" + # username field can be an empty string, and it will be authenticated against the default user + username: "" + password: "" + # If using existingSecret, the key must be REDIS_PASSWORD + existingSecret: "" + ## Additional deployment annotations + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + +exporter: + replicas: 1 + revisionHistoryLimit: 10 + # resources: + # requests: + # memory: 256Mi + # cpu: 100m + extraEnvVars: [] + podAnnotations: {} + ## Additional deployment labels + podLabels: {} + serviceAccountName: "" + # mount the service account token + automountServiceAccountToken: false + image: + repository: goharbor/harbor-exporter + tag: v2.9.1 + nodeSelector: {} + tolerations: [] + affinity: {} + # Spread Pods across failure-domains like regions, availability zones or nodes + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # nodeTaintsPolicy: Honor + # whenUnsatisfiable: DoNotSchedule + cacheDuration: 23 + cacheCleanInterval: 14400 + ## The priority class to run the pod as + priorityClassName: + +metrics: + enabled: false + core: + path: /metrics + port: 8001 + registry: + path: /metrics + port: 8001 + jobservice: + path: /metrics + port: 8001 + exporter: + path: /metrics + port: 8001 + ## Create prometheus serviceMonitor to scrape harbor metrics. + ## This requires the monitoring.coreos.com/v1 CRD. Please see + ## https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/getting-started.md + ## + serviceMonitor: + enabled: false + additionalLabels: {} + # Scrape interval. If not set, the Prometheus default scrape interval is used. + interval: "" + # Metric relabel configs to apply to samples before ingestion. + metricRelabelings: + [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + # Relabel configs to apply to samples before ingestion. + relabelings: + [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + +trace: + enabled: false + # trace provider: jaeger or otel + # jaeger should be 1.26+ + provider: jaeger + # set sample_rate to 1 if you wanna sampling 100% of trace data; set 0.5 if you wanna sampling 50% of trace data, and so forth + sample_rate: 1 + # namespace used to differentiate different harbor services + # namespace: + # attributes is a key value dict contains user defined attributes used to initialize trace provider + # attributes: + # application: harbor + jaeger: + # jaeger supports two modes: + # collector mode(uncomment endpoint and uncomment username, password if needed) + # agent mode(uncomment agent_host and agent_port) + endpoint: http://hostname:14268/api/traces + # username: + # password: + # agent_host: hostname + # export trace data by jaeger.thrift in compact mode + # agent_port: 6831 + otel: + endpoint: hostname:4318 + url_path: /v1/traces + compression: false + insecure: true + # timeout is in seconds + timeout: 10 + +# cache layer configurations +# if this feature enabled, harbor will cache the resource +# `project/project_metadata/repository/artifact/manifest` in the redis +# which help to improve the performance of high concurrent pulling manifest. +cache: + # default is not enabled. + enabled: false + # default keep cache for one day. + expireHours: 24 diff --git a/helm-charts/longhorn/auth b/helm-charts/longhorn/auth new file mode 100644 index 0000000..37797ab --- /dev/null +++ b/helm-charts/longhorn/auth @@ -0,0 +1 @@ +admin:$apr1$YG9oBd1/$w2KOan/FK.Xi6z27QQjDE0 diff --git a/helm-charts/racnher/.helmignore b/helm-charts/racnher/.helmignore new file mode 100644 index 0000000..2b29f27 --- /dev/null +++ b/helm-charts/racnher/.helmignore @@ -0,0 +1 @@ +tests diff --git a/helm-charts/racnher/Chart.yaml b/helm-charts/racnher/Chart.yaml new file mode 100644 index 0000000..307de46 --- /dev/null +++ b/helm-charts/racnher/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +appVersion: v2.8.0-rc1 +description: Install Rancher Server to manage Kubernetes clusters across providers. +home: https://rancher.com +icon: https://github.com/rancher/ui/blob/master/public/assets/images/logos/welcome-cow.svg +keywords: +- rancher +kubeVersion: < 1.29.0-0 +maintainers: +- email: charts@rancher.com + name: Rancher Labs +name: rancher +sources: +- https://github.com/rancher/rancher +- https://github.com/rancher/server-chart +version: 2.8.0-rc1 diff --git a/helm-charts/racnher/README.md b/helm-charts/racnher/README.md new file mode 100644 index 0000000..b0394b9 --- /dev/null +++ b/helm-charts/racnher/README.md @@ -0,0 +1,208 @@ +By installing this application, you accept the [End User License Agreement & Terms & Conditions](https://www.suse.com/licensing/eula/). + +# Rancher + +***Rancher*** is open source software that combines everything an organization needs to adopt and run containers in production. Built on Kubernetes, Rancher makes it easy for DevOps teams to test, deploy and manage their applications. + +### Introduction + +This chart bootstraps a [Rancher Server](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster) on a Kubernetes cluster using the [Helm](https://helm.sh/) package manager. For a Rancher Supported Deployment please follow our [HA install instructions](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs). + + +### Prerequisites Details + +*For installations covered under [Rancher Support SLA](https://www.suse.com/suse-rancher/support-matrix/all-supported-versions) the target cluster must be **[RKE1](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke1-for-rancher)**, **[RKE2](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/rke2-for-rancher)**, **[K3s](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/k3s-for-rancher)**, **[AKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-aks)**, **[EKS](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-amazon-eks)**, or **[GKE](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-gke)**.* + +Make sure the node(s) for the Rancher server fulfill the following requirements: + +[Operating Systems and Container Runtime Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#operating-systems-and-container-runtime-requirements) +[Hardware Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#hardware-requirements) + +- [CPU and Memory](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#cpu-and-memory) +- [Ingress](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#ingress) +- [Disks](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#disks) + +[Networking Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#networking-requirements) +- [Node IP Addresses](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#node-ip-addresses) +- [Port Requirements](https://ranchermanager.docs.rancher.com/pages-for-subheaders/installation-requirements#port-requirements) + +[Install the Required CLI Tools](https://ranchermanager.docs.rancher.com/pages-for-subheaders/cli-with-rancher) + +- [kubectl](https://ranchermanager.docs.rancher.com/reference-guides/cli-with-rancher/kubectl-utility) - Kubernetes command-line tool. +- [helm](https://docs.helm.sh/using_helm/#installing-helm) - Package management for Kubernetes. Refer to the [Helm version requirements](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/resources/helm-version-requirements) to choose a version of Helm to install Rancher. + +For a list of best practices that we recommend for running the Rancher server in production, refer to the [best practices section](https://ranchermanager.docs.rancher.com/pages-for-subheaders/best-practices). + +## Installing Rancher + +For production environments, we recommend installing Rancher in a [high-availability Kubernetes installation](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/kubernetes-cluster-setup/high-availability-installs) so that your user base can always access Rancher Server. When installed in a Kubernetes cluster, Rancher will integrate with the cluster’s etcd database and take advantage of Kubernetes scheduling for high-availability. + +Optional: Installing Rancher on a [Single-node](https://ranchermanager.docs.rancher.com/pages-for-subheaders/rancher-on-a-single-node-with-docker) Kubernetes Cluster + +#### Add the Helm Chart Repository + +Use [helm repo add](https://helm.sh/docs/helm/helm_repo_add/) command to add the Helm chart repository that contains charts to install Rancher. For more information about the repository choices and which is best for your use case, see Choosing a Version of Rancher. + +```bash +helm repo add rancher-latest https://releases.rancher.com/server-charts/latest +``` + +#### Create a Namespace for Rancher + +We’ll need to define a Kubernetes namespace where the resources created by the Chart should be installed. This should always be cattle-system: + +```bash +kubectl create namespace cattle-system +``` + +#### Choose your SSL Configuration + +The Rancher management server is designed to be secure by default and requires SSL/TLS configuration. + +There are three recommended options for the source of the certificate used for TLS termination at the Rancher server: + +- [Rancher-generated TLS certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) +- [Bring your own certificate](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) + +#### Install cert-manager + +This step is only required to use certificates issued by Rancher’s generated CA **`(ingress.tls.source=rancher)`** or to request Let’s Encrypt issued certificates **`(ingress.tls.source=letsEncrypt)`**. + +[These instructions are adapted from the official cert-manager documentation.](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#4-install-cert-manager) + +#### Install Rancher with Helm and Your Chosen Certificate Option + +- [Rancher to generated certificates](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org +``` + +- [Let’s Encrypt](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=letsEncrypt \ + --set letsEncrypt.email=me@example.org +``` + +- [Certificates from Files](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#5-install-rancher-with-helm-and-your-chosen-certificate-option) + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret +``` + +*If you are using a Private CA signed certificate , add **--set privateCA=true** to the command:`* + +```bash +helm install rancher rancher-latest/rancher \ + --namespace cattle-system \ + --set hostname=rancher.my.org \ + --set ingress.tls.source=secret \ + --set privateCA=true +``` + +#### Verify that the Rancher Server is Successfully Deployed + +After adding the secrets, check if Rancher was rolled out successfully: + +```bash +kubectl -n cattle-system rollout status deploy/rancher +Waiting for deployment "rancher" rollout to finish: 0 of 3 updated replicas are available... +deployment "rancher" successfully rolled out +``` + +If you see the following **`error: error: deployment "rancher" exceeded its progress deadline`**, you can check the status of the deployment by running the following command: + +```bash +kubectl -n cattle-system get deploy rancher +NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE +rancher 3 3 3 3 3m +``` + +It should show the same count for **`DESIRED`** and **`AVAILABLE`**. + +#### Save Your Options + +Make sure you save the **`--set`** options you used. You will need to use the same options when you upgrade Rancher to new versions with Helm. + +#### Finishing Up + +That’s it. You should have a functional Rancher server. + +In a web browser, go to the DNS name that forwards traffic to your load balancer. Then you should be greeted by the colorful login page. + +Doesn’t work? Take a look at the [Troubleshooting Page](https://ranchermanager.docs.rancher.com/troubleshooting/general-troubleshooting) + +***All of these instructions are defined in detailed in the [Rancher Documentation](https://ranchermanager.docs.rancher.com/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster#install-the-rancher-helm-chart).*** + +### Helm Chart Options for Kubernetes Installations + +The full [Helm Chart Options](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options) can be found here. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +#### Common Options + +| Parameter | Default Value | Description | +| ------------------------- | ------------- | -------------------------------------------------------------------------------------------- | +| `hostname` | " " | ***string*** - the Fully Qualified Domain Name for your Rancher Server | +| `ingress.tls.source` | "rancher" | ***string*** - Where to get the cert for the ingress. - "***rancher, letsEncrypt, secret***" | +| `letsEncrypt.email` | " " | ***string*** - Your email address | +| `letsEncrypt.environment` | "production" | ***string*** - Valid options: "***staging, production***" | +| `privateCA` | false | ***bool*** - Set to true if your cert is signed by a private CA | + +#### Advanced Options + +| Parameter | Default Value | Description | +| ---------------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `additionalTrustedCAs` | false | ***bool*** - [See Additional Trusted CAs Server](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/installation-references/helm-chart-options#additional-trusted-cas) | +| `addLocal` | "true" | ***string*** - As of Rancher v2.5.0 this flag is deprecated and must be set to "true" | +| `antiAffinity` | "preferred" | ***string*** - AntiAffinity rule for Rancher pods - *"preferred, required"* | +| `replicas` | 3 | ***int*** - Number of replicas of Rancher pods | +| `auditLog.destination` | "sidecar" | ***string*** - Stream to sidecar container console or hostPath volume - *"sidecar, hostPath"* | +| `auditLog.hostPath` | "/var/log/rancher/audit" | ***string*** - log file destination on host (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.level` | 0 | ***int*** - set the [API Audit Log level](https://ranchermanager.docs.rancher.com/how-to-guides/advanced-user-guides/enable-api-audit-log#audit-log-levels). 0 is off. [0-3] | +| `auditLog.maxAge` | 1 | ***int*** - maximum number of days to retain old audit log files (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxBackup` | 1 | int - maximum number of audit log files to retain (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.maxSize` | 100 | ***int*** - maximum size in megabytes of the audit log file before it gets rotated (only applies when **auditLog.destination** is set to **hostPath**) | +| `auditLog.image.repository` | "rancher/mirrored-bci-micro" | ***string*** - Location for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.tag` | "15.4.14.3" | ***string*** - Tag for the image used to collect audit logs *Note: Available as of v2.7.0* | +| `auditLog.image.pullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for auditLog images - *"Always", "Never", "IfNotPresent"* *Note: Available as of v2.7.0* | +| `busyboxImage` | "" | ***string*** - *Deprecated `auditlog.image.repository` should be used to control auditing sidecar image.* Image location for busybox image used to collect audit logs *Note: Available as of v2.2.0, and Deprecated as of v2.7.0* | +| `busyboxImagePullPolicy` | "IfNotPresent" | ***string*** - - *Deprecated `auditlog.image.pullPolicy` should be used to control auditing sidecar image.* Override imagePullPolicy for busybox images - *"Always", "Never", "IfNotPresent"* *Deprecated as of v2.7.0* | +| `debug` | false | ***bool*** - set debug flag on rancher server | +| `certmanager.version` | " " | ***string*** - set cert-manager compatibility | +| `extraEnv` | [] | ***list*** - set additional environment variables for Rancher Note: *Available as of v2.2.0* | +| `imagePullSecrets` | [] | ***list*** - list of names of Secret resource containing private registry credentials | +| `ingress.enabled` | true | ***bool*** - install ingress resource | +| `ingress.ingressClassName` | " " | ***string*** - class name of ingress if not set manually or by the ingress controller's defaults | +| `ingress.includeDefaultExtraAnnotations` | true | ***bool*** - Add default nginx annotations | +| `ingress.extraAnnotations` | {} | ***map*** - additional annotations to customize the ingress | +| `ingress.configurationSnippet` | " " | ***string*** - Add additional Nginx configuration. Can be used for proxy configuration. Note: *Available as of v2.0.15, v2.1.10 and v2.2.4* | +| `service.annotations` | {} | ***map*** - annotations to customize the service | +| `service.type` | " " | ***string*** - Override the type used for the service - *"NodePort", "LoadBalancer", "ClusterIP"* | +| `letsEncrypt.ingress.class` | " " | ***string*** - optional ingress class for the cert-manager acmesolver ingress that responds to the Let’s *Encrypt ACME challenges* | +| `proxy` | " " | ***string** - HTTP[S] proxy server for Rancher | +| `noProxy` | "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local" | ***string*** - comma separated list of hostnames or ip address not to use the proxy | +| `resources` | {} | ***map*** - rancher pod resource requests & limits | +| `rancherImage` | "rancher/rancher" | ***string*** - rancher image source | +| `rancherImageTag` | same as chart version | ***string*** - rancher/rancher image tag | +| `rancherImagePullPolicy` | "IfNotPresent" | ***string*** - Override imagePullPolicy for rancher server images - *"Always", "Never", "IfNotPresent"* | +| `tls` | "ingress" | ***string*** - See External TLS Termination for details. - *"ingress, external"* | +| `systemDefaultRegistry` | "" | ***string*** - private registry to be used for all system Docker images, e.g., [http://registry.example.com/] *Available as of v2.3.0* | +| `useBundledSystemChart` | false | ***bool*** - select to use the system-charts packaged with Rancher server. This option is used for air gapped installations. *Available as of v2.3.0* | +| `customLogos.enabled` | false | ***bool*** - Enabled [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) and [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence volume | +| `customLogos.volumeSubpaths.emberUi` | "ember" | ***string*** - Volume subpath for [Ember Rancher UI (cluster manager) custom logos](https://github.com/rancher/ui/tree/master/public/assets/images/logos) persistence | +| `customLogos.volumeSubpaths.vueUi` | "vue" | ***string*** - Volume subpath for [Vue Rancher UI (cluster explorer) custom logos](https://github.com/rancher/dashboard/tree/master/shell/assets/images/pl) persistence | +| `customLogos.volumeName` | "" | ***string*** - Use an existing volume. Custom logos should be copied to the proper `volume/subpath` folder by the user. Optional for persistentVolumeClaim, required for configMap | +| `customLogos.storageClass` | "" | ***string*** - Set custom logos persistentVolumeClaim storage class. Required for dynamic pv | +| `customLogos.accessMode` | "ReadWriteOnce" | ***string*** - Set custom persistentVolumeClaim access mode | +| `customLogos.size` | "1Gi" | ***string*** - Set custom persistentVolumeClaim size | diff --git a/helm-charts/racnher/scripts/post-delete-hook.sh b/helm-charts/racnher/scripts/post-delete-hook.sh new file mode 100644 index 0000000..ad8d7a7 --- /dev/null +++ b/helm-charts/racnher/scripts/post-delete-hook.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -e + +namespaces="${NAMESPACES}" +rancher_namespace="${RANCHER_NAMESPACE}" +timeout="${TIMEOUT}" +ignoreTimeoutError="${IGNORETIMEOUTERROR}" + +if [[ -z ${namespaces} ]]; then + echo "No namespace is provided." + exit 1 +fi + +if [[ -z ${rancher_namespace} ]]; then + echo "No rancher namespace is provided." + exit 1 +fi + +if [[ -z ${timeout} ]]; then + echo "No timeout value is provided." + exit 1 +fi + +if [[ -z ${ignoreTimeoutError} ]]; then + echo "No ignoreTimeoutError value is provided." + exit 1 +fi + +succeeded=() +failed=() + +get_pod_count() { + kubectl get pods --selector app="${1}" -n "${2}" -o json | jq '.items | length' +} + +echo "Uninstalling Rancher resources in the following namespaces: ${namespaces}" + +for namespace in ${namespaces}; do + for app in $(helm list -n "${namespace}" -q); do + if [[ ${app} =~ .crd$ ]]; then + echo "--- Skip the app [${app}] in the namespace [${namespace}]" + continue + fi + echo "--- Deleting the app [${app}] in the namespace [${namespace}]" + if [[ ! $(helm uninstall "${app}" -n "${namespace}") ]]; then + failed=("${failed[@]}" "${app}") + continue + fi + + t=0 + while true; do + if [[ $(get_pod_count "${app}" "${namespace}") -eq 0 ]]; then + echo "successfully uninstalled [${app}] in the namespace [${namespace}]" + succeeded=("${succeeded[@]}" "${app}") + break + fi + if [[ ${t} -ge ${timeout} ]]; then + echo "timeout uninstalling [${app}] in the namespace [${namespace}]" + failed=("${failed[@]}" "${app}") + break + fi + # by default, wait 120 seconds in total for an app to be uninstalled + echo "waiting 5 seconds for pods of [${app}] to be terminated ..." + sleep 5 + t=$((t + 5)) + done + done + + # delete the helm operator pods + for pod in $(kubectl get pods -n "${namespace}" -o name); do + if [[ ${pod} =~ ^pod\/helm-operation-* ]]; then + echo "--- Deleting the pod [${pod}] in the namespace [${namespace}]" + kubectl delete "${pod}" -n "${namespace}" + fi + done +done + +echo "Removing Rancher bootstrap secret in the following namespace: ${rancher_namespace}" +kubectl --ignore-not-found=true delete secret bootstrap-secret -n "${rancher_namespace}" + +echo "------ Summary ------" +if [[ ${#succeeded[@]} -ne 0 ]]; then + echo "Succeeded to uninstall the following apps:" "${succeeded[@]}" +fi + +if [[ ${#failed[@]} -ne 0 ]]; then + echo "Failed to uninstall the following apps:" "${failed[@]}" + if [[ "${ignoreTimeoutError}" == "false" ]]; then + exit 2 + fi +else + echo "Cleanup finished successfully." +fi diff --git a/helm-charts/racnher/templates/NOTES.txt b/helm-charts/racnher/templates/NOTES.txt new file mode 100644 index 0000000..5d9d1e8 --- /dev/null +++ b/helm-charts/racnher/templates/NOTES.txt @@ -0,0 +1,22 @@ +Rancher Server has been installed. + +NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued, Containers are started and the Ingress rule comes up. + +Check out our docs at https://rancher.com/docs/ + +If you provided your own bootstrap password during installation, browse to https://{{ .Values.hostname }} to get started. + +If this is the first time you installed Rancher, get started by running this command and clicking the URL it generates: + +``` +echo https://{{ .Values.hostname }}/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}') +``` + +To get just the bootstrap password on its own, run: + +``` +kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ "{{" }}.data.bootstrapPassword|base64decode{{ "}}" }}{{ "{{" }} "\n" {{ "}}" }}' +``` + + +Happy Containering! diff --git a/helm-charts/racnher/templates/_helpers.tpl b/helm-charts/racnher/templates/_helpers.tpl new file mode 100644 index 0000000..00ab80b --- /dev/null +++ b/helm-charts/racnher/templates/_helpers.tpl @@ -0,0 +1,101 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "rancher.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.fullname" -}} + {{- $name := default .Chart.Name .Values.nameOverride -}} + {{- if contains $name .Release.Name -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified chart name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "rancher.chartname" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +# Render Values in configurationSnippet +{{- define "configurationSnippet" -}} + {{- tpl (.Values.ingress.configurationSnippet) . | nindent 6 -}} +{{- end -}} + +{{/* +Generate the labels. +*/}} +{{- define "rancher.labels" -}} +app: {{ template "rancher.fullname" . }} +chart: {{ template "rancher.chartname" . }} +heritage: {{ .Release.Service }} +release: {{ .Release.Name }} +{{- end }} + +# Windows Support + +{{/* +Windows cluster will add default taint for linux nodes, +add below linux tolerations to workloads could be scheduled to those linux nodes +*/}} + +{{- define "linux-node-tolerations" -}} +- key: "cattle.io/os" + value: "linux" + effect: "NoSchedule" + operator: "Equal" +{{- end -}} + +{{- define "linux-node-selector-terms" -}} +{{- $key := "kubernetes.io/os" -}} +- matchExpressions: + - key: {{ $key }} + operator: NotIn + values: + - windows +{{- end -}} + +{{- define "system_default_registry" -}} +{{- if .Values.systemDefaultRegistry -}} + {{- if hasSuffix "/" .Values.systemDefaultRegistry -}} + {{- printf "%s" .Values.systemDefaultRegistry -}} + {{- else -}} + {{- printf "%s/" .Values.systemDefaultRegistry -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Define the chosen value for PSPs. If this value is "", then the user did not set the value. This will +result in psps on <=1.24 and no psps on >=1.25. If the value is true/false, then the user specifically +chose an option, and that option will be used. If it is set otherwise, then we fail so the user can correct +the invalid value. +*/}} + +{{- define "rancher.chart_psp_enabled" -}} +{{- if kindIs "bool" .Values.global.cattle.psp.enabled -}} +{{ .Values.global.cattle.psp.enabled }} +{{- else if empty .Values.global.cattle.psp.enabled -}} + {{- if gt (len (lookup "rbac.authorization.k8s.io/v1" "ClusterRole" "" "")) 0 -}} + {{- if (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") -}} +true + {{- else -}} +false + {{- end -}} + {{- else -}} +true + {{- end -}} +{{- else -}} +{{- fail "Invalid value for .Values.global.cattle.psp.enabled - must be a bool of true, false, or \"\"" -}} +{{- end -}} +{{- end -}} diff --git a/helm-charts/racnher/templates/clusterRoleBinding.yaml b/helm-charts/racnher/templates/clusterRoleBinding.yaml new file mode 100644 index 0000000..aeb155d --- /dev/null +++ b/helm-charts/racnher/templates/clusterRoleBinding.yaml @@ -0,0 +1,14 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +subjects: +- kind: ServiceAccount + name: {{ template "rancher.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/helm-charts/racnher/templates/configMap.yaml b/helm-charts/racnher/templates/configMap.yaml new file mode 100644 index 0000000..21848e5 --- /dev/null +++ b/helm-charts/racnher/templates/configMap.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rancher-config + labels: {{ include "rancher.labels" . | nindent 4 }} + app.kubernetes.io/part-of: "rancher" +data: + priorityClassName: {{ .Values.priorityClassName }} + {{- if and .Values.webhook (kindIs "string" .Values.webhook) }} + rancher-webhook: {{ .Values.webhook | quote }} + {{- else if .Values.webhook }} + rancher-webhook: {{ toYaml .Values.webhook | quote }} + {{- end }} diff --git a/helm-charts/racnher/templates/deployment.yaml b/helm-charts/racnher/templates/deployment.yaml new file mode 100644 index 0000000..8beb787 --- /dev/null +++ b/helm-charts/racnher/templates/deployment.yaml @@ -0,0 +1,253 @@ +kind: Deployment +apiVersion: apps/v1 +metadata: + name: {{ template "rancher.fullname" . }} + annotations: +{{- if (lt (int .Values.replicas) 0) }} + management.cattle.io/scale-available: "{{ sub 0 (int .Values.replicas)}}" +{{- end }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: +{{- if (gt (int .Values.replicas) 0) }} + replicas: {{ .Values.replicas }} +{{- end }} + selector: + matchLabels: + app: {{ template "rancher.fullname" . }} + strategy: + rollingUpdate: + maxSurge: 1 +{{- if (eq (int .Values.replicas) 1) }} + maxUnavailable: 0 +{{- else }} + maxUnavailable: 1 +{{- end }} + type: RollingUpdate + template: + metadata: + labels: + app: {{ template "rancher.fullname" . }} + release: {{ .Release.Name }} + spec: + priorityClassName: {{ .Values.priorityClassName }} + serviceAccountName: {{ template "rancher.fullname" . }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 6 }} +{{- end }} + affinity: + podAntiAffinity: +{{- if eq .Values.antiAffinity "required" }} + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- else }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "rancher.fullname" . }} + topologyKey: {{ .Values.topologyKey | default "kubernetes.io/hostname" }} +{{- end }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: {{ include "linux-node-selector-terms" . | nindent 14 }} + tolerations: {{ include "linux-node-tolerations" . | nindent 8 }} + containers: + - image: {{ .Values.rancherImage }}:{{ default .Chart.AppVersion .Values.rancherImageTag }} + imagePullPolicy: {{ default "IfNotPresent" .Values.rancherImagePullPolicy }} + name: {{ template "rancher.name" . }} + ports: + - containerPort: 80 + protocol: TCP +{{- if (and .Values.hostPort (gt (int .Values.hostPort) 0)) }} + - containerPort: 444 + hostPort: {{ int .Values.hostPort }} + protocol: TCP +{{- end}} + args: +{{- if .Values.debug }} + - "--debug" +{{- end }} +{{- if .Values.privateCA }} + # Private CA - don't clear ca certs +{{- else if and (eq .Values.tls "ingress") (eq .Values.ingress.tls.source "rancher") }} + # Rancher self-signed - don't clear ca certs +{{- else }} + # Public trusted CA - clear ca certs + - "--no-cacerts" +{{- end }} + - "--http-listen-port=80" + - "--https-listen-port=443" + - "--add-local={{ .Values.addLocal }}" + env: + - name: CATTLE_NAMESPACE + value: {{ .Release.Namespace }} + - name: CATTLE_PEER_SERVICE + value: {{ template "rancher.fullname" . }} +{{- if .Values.features }} + - name: CATTLE_FEATURES + value: "{{ .Values.features }}" +{{- end}} +{{- if .Values.noDefaultAdmin }} + - name: CATTLE_NO_DEFAULT_ADMIN + value: "{{ .Values.noDefaultAdmin }}" +{{- end}} +{{- if gt (int .Values.auditLog.level) 0 }} + - name: AUDIT_LEVEL + value: {{ .Values.auditLog.level | quote }} + - name: AUDIT_LOG_MAXAGE + value: {{ .Values.auditLog.maxAge | quote }} + - name: AUDIT_LOG_MAXBACKUP + value: {{ .Values.auditLog.maxBackup | quote }} + - name: AUDIT_LOG_MAXSIZE + value: {{ .Values.auditLog.maxSize | quote }} +{{- end }} +{{- if .Values.proxy }} + - name: HTTP_PROXY + value: {{ .Values.proxy }} + - name: HTTPS_PROXY + value: {{ .Values.proxy }} + - name: NO_PROXY + value: {{ .Values.noProxy }} +{{- end }} +{{- if .Values.systemDefaultRegistry }} + - name: CATTLE_SYSTEM_DEFAULT_REGISTRY + value: {{ .Values.systemDefaultRegistry }} +{{- end }} +{{- if .Values.useBundledSystemChart }} + - name: CATTLE_SYSTEM_CATALOG + value: bundled +{{- end }} +{{- if .Values.restrictedAdmin }} + - name: CATTLE_RESTRICTED_DEFAULT_ADMIN + value: "true" +{{- end}} +{{- if .Values.bootstrapPassword }} + - name: CATTLE_BOOTSTRAP_PASSWORD + valueFrom: + secretKeyRef: + name: "bootstrap-secret" + key: "bootstrapPassword" +{{- end }} +{{- if .Values.extraEnv }} +{{ toYaml .Values.extraEnv | indent 8}} +{{- end }} + livenessProbe: + httpGet: + path: /healthz + port: 80 + initialDelaySeconds: {{.Values.livenessProbe.initialDelaySeconds | default 60 }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds | default 30 }} + readinessProbe: + httpGet: + path: /healthz + port: 80 + initialDelaySeconds: {{.Values.readinessProbe.initialDelaySeconds | default 5}} + periodSeconds: {{ .Values.readinessProbe.periodSeconds | default 30}} +{{- if .Values.startupProbe }} + startupProbe: + httpGet: + path: /healthz + port: 80 + failureThreshold: {{.Values.startupProbe.failureThreshold | default 1}} + periodSeconds: {{ .Values.startupProbe.periodSeconds | default 30}} +{{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: +{{- if .Values.additionalTrustedCAs }} + - mountPath: /etc/pki/trust/anchors/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true + - mountPath: /etc/rancher/ssl/ca-additional.pem + name: tls-ca-additional-volume + subPath: ca-additional.pem + readOnly: true +{{- end }} +{{- if .Values.privateCA }} + # Pass CA cert into rancher for private CA + - mountPath: /etc/rancher/ssl/cacerts.pem + name: tls-ca-volume + subPath: cacerts.pem + readOnly: true +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + # Mount rancher custom-logos volume + - mountPath: /usr/share/rancher/ui/assets/images/logos + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.emberUi | default "ember" | quote }} + - mountPath: /usr/share/rancher/ui-dashboard/dashboard/_nuxt/assets/images/pl + name: custom-logos + subPath: {{ .Values.customLogos.volumeSubpaths.vueUi | default "vue" | quote }} +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + - mountPath: /var/log/auditlog + name: audit-log +{{- end }} +{{- if eq .Values.auditLog.destination "sidecar" }} + {{- if gt (int .Values.auditLog.level) 0 }} + # Make audit logs available for Rancher log collector tools. + {{- if .Values.busyboxImage }} + - image: {{ .Values.busyboxImage}} + {{- else }} + - image: {{ .Values.auditLog.image.repository }}:{{.Values.auditLog.image.tag}} + {{- end }} + {{- if .Values.busyboxImagePullPolicy }} + imagePullPolicy: {{ .Values.busyboxImagePullPolicy }} + {{- else }} + imagePullPolicy: {{ .Values.auditLog.image.pullPolicy }} + {{- end }} + name: {{ template "rancher.name" . }}-audit-log + command: ["tail"] + args: ["-F", "/var/log/auditlog/rancher-api-audit.log"] + volumeMounts: + - mountPath: /var/log/auditlog + name: audit-log + {{- end }} +{{- end }} + volumes: +{{- if .Values.additionalTrustedCAs }} + - name: tls-ca-additional-volume + secret: + defaultMode: 0400 + secretName: tls-ca-additional +{{- end }} +{{- if .Values.privateCA }} + - name: tls-ca-volume + secret: + defaultMode: 0400 + secretName: tls-ca +{{- end }} +{{- if gt (int .Values.auditLog.level) 0 }} + {{- if eq .Values.auditLog.destination "hostPath" }} + - name: audit-log + hostPath: + path: {{ .Values.auditLog.hostPath }} + type: DirectoryOrCreate + {{- else }} + - name: audit-log + emptyDir: {} + {{- end }} +{{- end }} +{{- if and .Values.customLogos.enabled (or (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (and (eq .Values.customLogos.volumeKind "configMap") (.Values.customLogos.volumeName))) }} + - name: custom-logos + {{- if (eq .Values.customLogos.volumeKind "persistentVolumeClaim") }} + persistentVolumeClaim: + claimName: {{ .Values.customLogos.volumeName | default (printf "%s-custom-logos" (include "rancher.fullname" .)) }} + {{- else if (eq .Values.customLogos.volumeKind "configMap") }} + configMap: + name: {{ .Values.customLogos.volumeName }} + {{- end }} +{{- end }} diff --git a/helm-charts/racnher/templates/ingress.yaml b/helm-charts/racnher/templates/ingress.yaml new file mode 100644 index 0000000..d772f96 --- /dev/null +++ b/helm-charts/racnher/templates/ingress.yaml @@ -0,0 +1,66 @@ +{{- if .Values.ingress.enabled }} +{{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} +apiVersion: networking.k8s.io/v1 +{{- else }} +apiVersion: networking.k8s.io/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} + annotations: +{{- if .Values.ingress.configurationSnippet }} + nginx.ingress.kubernetes.io/configuration-snippet: | + {{- template "configurationSnippet" . }} +{{- end }} +{{- if eq .Values.tls "external" }} + nginx.ingress.kubernetes.io/ssl-redirect: "false" # turn off ssl redirect for external. +{{- else }} + {{- if ne .Values.ingress.tls.source "secret" }} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + certmanager.k8s.io/issuer: {{ template "rancher.fullname" . }} + {{- else }} + cert-manager.io/issuer: {{ template "rancher.fullname" . }} + cert-manager.io/issuer-kind: Issuer + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.ingress.includeDefaultExtraAnnotations }} + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" + nginx.ingress.kubernetes.io/proxy-send-timeout: "1800" +{{- end }} +{{- if .Values.ingress.extraAnnotations }} +{{ toYaml .Values.ingress.extraAnnotations | indent 4 }} +{{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} + rules: + - host: {{ .Values.hostname }} # hostname to access rancher server + http: + paths: + - backend: + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + service: + name: {{ template "rancher.fullname" . }} + port: + number: {{ .Values.ingress.servicePort }} + {{- else }} + serviceName: {{ template "rancher.fullname" . }} + servicePort: {{ .Values.ingress.servicePort }} + {{- end }} + {{- if or (.Capabilities.APIVersions.Has "networking.k8s.io/v1/Ingress") (not (.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/Ingress")) }} + pathType: ImplementationSpecific + path: "/" + {{- end }} +{{- if eq .Values.tls "ingress" }} + tls: + - hosts: + - {{ .Values.hostname }} + secretName: {{ .Values.ingress.tls.secretName }} +{{- end }} +{{- end }} diff --git a/helm-charts/racnher/templates/issuer-letsEncrypt.yaml b/helm-charts/racnher/templates/issuer-letsEncrypt.yaml new file mode 100644 index 0000000..ee0a7b0 --- /dev/null +++ b/helm-charts/racnher/templates/issuer-letsEncrypt.yaml @@ -0,0 +1,37 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "letsEncrypt" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + acme: + {{- if eq .Values.letsEncrypt.environment "production" }} + server: https://acme-v02.api.letsencrypt.org/directory + {{- else }} + server: https://acme-staging-v02.api.letsencrypt.org/directory + {{- end }} + email: {{ .Values.letsEncrypt.email }} + privateKeySecretRef: + name: letsencrypt-{{ .Values.letsEncrypt.environment }} + {{- if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} + http01: {} + {{- else }} + solvers: + - http01: + ingress: + class: {{ .Values.letsEncrypt.ingress.class }} + {{- end }} + {{- end -}} +{{- end -}} diff --git a/helm-charts/racnher/templates/issuer-rancher.yaml b/helm-charts/racnher/templates/issuer-rancher.yaml new file mode 100644 index 0000000..9e24b38 --- /dev/null +++ b/helm-charts/racnher/templates/issuer-rancher.yaml @@ -0,0 +1,22 @@ +{{- if eq .Values.tls "ingress" -}} + {{- if eq .Values.ingress.tls.source "rancher" -}} + {{- $certmanagerVer := split "." .Values.certmanager.version -}} + {{- if or (.Capabilities.APIVersions.Has "cert-manager.io/v1beta1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 16)) }} +apiVersion: cert-manager.io/v1beta1 + {{- else if or (.Capabilities.APIVersions.Has "cert-manager.io/v1alpha2") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (ge (int $certmanagerVer._1) 11)) }} +apiVersion: cert-manager.io/v1alpha2 + {{- else if or (.Capabilities.APIVersions.Has "certmanager.k8s.io/v1alpha1") (and (gt (len $certmanagerVer._0) 0) (eq (int $certmanagerVer._0) 0) (lt (int $certmanagerVer._1) 11)) }} +apiVersion: certmanager.k8s.io/v1alpha1 + {{- else }} +apiVersion: cert-manager.io/v1 + {{- end }} +kind: Issuer +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + ca: + secretName: tls-rancher + {{- end -}} +{{- end -}} diff --git a/helm-charts/racnher/templates/post-delete-hook-cluster-role-binding.yaml b/helm-charts/racnher/templates/post-delete-hook-cluster-role-binding.yaml new file mode 100644 index 0000000..476957b --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-cluster-role-binding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "rancher.fullname" . }}-post-delete +subjects: + - kind: ServiceAccount + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm-charts/racnher/templates/post-delete-hook-cluster-role.yaml b/helm-charts/racnher/templates/post-delete-hook-cluster-role.yaml new file mode 100644 index 0000000..45babfc --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-cluster-role.yaml @@ -0,0 +1,47 @@ +{{- if .Values.postDelete.enabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +rules: + - apiGroups: [ "extensions","apps" ] + resources: [ "deployments" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "batch" ] + resources: [ "jobs" ] + verbs: [ "get", "list", "watch", "delete", "create" ] + - apiGroups: [ "rbac.authorization.k8s.io" ] + resources: [ "clusterroles", "clusterrolebindings", "roles", "rolebindings" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "" ] + resources: [ "pods", "secrets", "services", "configmaps" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "" ] + resources: [ "serviceaccounts" ] + verbs: [ "get", "list", "delete", "create" ] + - apiGroups: [ "networking.k8s.io" ] + resources: [ "networkpolicies" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "admissionregistration.k8s.io" ] + resources: [ "validatingwebhookconfigurations", "mutatingwebhookconfigurations" ] + verbs: [ "get", "list", "delete" ] + - apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + verbs: ["delete", "create" ] +{{- if eq (include "rancher.chart_psp_enabled" . ) "true" }} + - apiGroups: [ "policy" ] + resources: [ "podsecuritypolicies" ] + verbs: [ "use"] +{{- end }} + - apiGroups: [ "networking.k8s.io" ] + resources: [ "ingresses" ] + verbs: [ "delete" ] + - apiGroups: [ "cert-manager.io" ] + resources: [ "issuers" ] + verbs: [ "delete" ] +{{- end }} diff --git a/helm-charts/racnher/templates/post-delete-hook-config-map.yaml b/helm-charts/racnher/templates/post-delete-hook-config-map.yaml new file mode 100644 index 0000000..eb7b9e6 --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-config-map.yaml @@ -0,0 +1,15 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +data: + post-delete-hook.sh: |- +{{ $.Files.Get "scripts/post-delete-hook.sh" | indent 4 }} +{{- end }} diff --git a/helm-charts/racnher/templates/post-delete-hook-job.yaml b/helm-charts/racnher/templates/post-delete-hook-job.yaml new file mode 100644 index 0000000..d90ca80 --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-job.yaml @@ -0,0 +1,46 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "3" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 3 + template: + metadata: + name: {{ template "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 8 }} + spec: + serviceAccountName: {{ template "rancher.fullname" . }}-post-delete + restartPolicy: OnFailure + containers: + - name: {{ template "rancher.name" . }}-post-delete + image: "{{ include "system_default_registry" . }}{{ .Values.postDelete.image.repository }}:{{ .Values.postDelete.image.tag }}" + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: 0 + command: + - /scripts/post-delete-hook.sh + volumeMounts: + - mountPath: /scripts + name: config-volume + env: + - name: NAMESPACES + value: {{ .Values.postDelete.namespaceList | join " " | quote }} + - name: RANCHER_NAMESPACE + value: {{ .Release.Namespace }} + - name: TIMEOUT + value: {{ .Values.postDelete.timeout | quote }} + - name: IGNORETIMEOUTERROR + value: {{ .Values.postDelete.ignoreTimeoutError | quote }} + volumes: + - name: config-volume + configMap: + name: {{ template "rancher.fullname" . }}-post-delete + defaultMode: 0777 +{{- end }} diff --git a/helm-charts/racnher/templates/post-delete-hook-psp.yaml b/helm-charts/racnher/templates/post-delete-hook-psp.yaml new file mode 100644 index 0000000..8332087 --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-psp.yaml @@ -0,0 +1,34 @@ +{{- if eq (include "rancher.chart_psp_enabled" . ) "true" -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "rancher.fullname" . }}-post-delete + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +spec: + privileged: false + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + volumes: + - 'secret' + - 'configMap' +{{- end }} diff --git a/helm-charts/racnher/templates/post-delete-hook-service-account.yaml b/helm-charts/racnher/templates/post-delete-hook-service-account.yaml new file mode 100644 index 0000000..923687d --- /dev/null +++ b/helm-charts/racnher/templates/post-delete-hook-service-account.yaml @@ -0,0 +1,12 @@ +{{- if .Values.postDelete.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "rancher.fullname" . }}-post-delete + namespace: {{ .Release.Namespace }} + labels: {{ include "rancher.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded,hook-failed +{{- end }} diff --git a/helm-charts/racnher/templates/priorityClass.yaml b/helm-charts/racnher/templates/priorityClass.yaml new file mode 100644 index 0000000..5ef748a --- /dev/null +++ b/helm-charts/racnher/templates/priorityClass.yaml @@ -0,0 +1,8 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: rancher-critical + labels: {{ include "rancher.labels" . | nindent 4 }} +value: 1000000000 +globalDefault: false +description: "Priority class used by pods critical to rancher's functionality." diff --git a/helm-charts/racnher/templates/pvc.yaml b/helm-charts/racnher/templates/pvc.yaml new file mode 100644 index 0000000..45e644f --- /dev/null +++ b/helm-charts/racnher/templates/pvc.yaml @@ -0,0 +1,19 @@ +{{- if and (.Values.customLogos.enabled) (eq .Values.customLogos.volumeKind "persistentVolumeClaim") (not .Values.customLogos.volumeName) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }}-custom-logos +spec: + accessModes: + - {{ .Values.customLogos.accessMode | quote }} + resources: + requests: + storage: {{ .Values.customLogos.size | quote }} + storageClassName: {{ if .Values.customLogos.storageClass }} + {{- if (eq "-" .Values.customLogos.storageClass) -}} + "" + {{- else }} + {{- .Values.customLogos.storageClass }} + {{- end -}} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm-charts/racnher/templates/secret.yaml b/helm-charts/racnher/templates/secret.yaml new file mode 100644 index 0000000..fd476bd --- /dev/null +++ b/helm-charts/racnher/templates/secret.yaml @@ -0,0 +1,25 @@ +{{/* Use the bootstrap password from values.yaml if an existing secret is not found */}} +{{- $bootstrapPassword := .Values.bootstrapPassword -}} +{{- $existingSecret := lookup "v1" "Secret" .Release.Namespace "bootstrap-secret" -}} +{{- if $existingSecret -}} + {{- if $existingSecret.data -}} + {{- if $existingSecret.data.bootstrapPassword -}} + {{- $bootstrapPassword = $existingSecret.data.bootstrapPassword | b64dec -}} + {{- end -}} + {{- end -}} +{{- end -}} +{{/* If a bootstrap password was found in the values or an existing password was found create the secret */}} +{{- if $bootstrapPassword }} +apiVersion: v1 +kind: Secret +metadata: + name: "bootstrap-secret" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "-5" + "helm.sh/resource-policy": keep +type: Opaque +data: + bootstrapPassword: {{ $bootstrapPassword | b64enc | quote }} +{{- end }} diff --git a/helm-charts/racnher/templates/service.yaml b/helm-charts/racnher/templates/service.yaml new file mode 100644 index 0000000..2b2967b --- /dev/null +++ b/helm-charts/racnher/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} +spec: + {{- /* + If service.type is not provided this attribute is ommitted and k8s default of ClusterIP is used. + */}} + {{- if .Values.service.type }} + type: {{ .Values.service.type }} + {{- end }} + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + - port: 443 + targetPort: 444 + protocol: TCP + name: https-internal + selector: + app: {{ template "rancher.fullname" . }} diff --git a/helm-charts/racnher/templates/serviceAccount.yaml b/helm-charts/racnher/templates/serviceAccount.yaml new file mode 100644 index 0000000..84c0d29 --- /dev/null +++ b/helm-charts/racnher/templates/serviceAccount.yaml @@ -0,0 +1,6 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ template "rancher.fullname" . }} + labels: +{{ include "rancher.labels" . | indent 4 }} diff --git a/helm-charts/racnher/values.yaml b/helm-charts/racnher/values.yaml new file mode 100644 index 0000000..2fb7806 --- /dev/null +++ b/helm-charts/racnher/values.yaml @@ -0,0 +1,192 @@ +# Additional Trusted CAs. +# Enable this flag and add your CA certs as a secret named tls-ca-additional in the namespace. +# See README.md for details. +additionalTrustedCAs: false + +antiAffinity: preferred +topologyKey: kubernetes.io/hostname + +# Audit Logs https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# The audit log is piped to the console of the rancher-audit-log container in the rancher pod. +# https://rancher.com/docs/rancher/v2.x/en/installation/api-auditing/ +# destination stream to sidecar container console or hostPath volume +# level: Verbosity of logs, 0 to 3. 0 is off 3 is a lot. +auditLog: + destination: sidecar + hostPath: /var/log/rancher/audit/ + level: 0 + maxAge: 1 + maxBackup: 1 + maxSize: 100 + + # Image for collecting rancher audit logs. + # Important: update pkg/image/export/resolve.go when this default image is changed, so that it's reflected accordingly in rancher-images.txt generated for air-gapped setups. + image: + repository: "rancher/mirrored-bci-micro" + tag: 15.4.14.3 + # Override imagePullPolicy image + # options: Always, Never, IfNotPresent + pullPolicy: "IfNotPresent" + +# As of Rancher v2.5.0 this flag is deprecated and must be set to 'true' in order for Rancher to start +addLocal: "true" + +# Add debug flag to Rancher server +debug: false + +# When starting Rancher for the first time, bootstrap the admin as restricted-admin +restrictedAdmin: false + +# Extra environment variables passed to the rancher pods. +# extraEnv: +# - name: CATTLE_TLS_MIN_VERSION +# value: "1.0" + +# Fully qualified name to reach your Rancher server +# hostname: rancher.my.org + +## Optional array of imagePullSecrets containing private registry credentials +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: secretName + +config: + use-forwarded-headers: "true" + +### ingress ### +# Readme for details and instruction on adding tls secrets. +ingress: + # If set to false, ingress will not be created + # Defaults to true + # options: true, false + enabled: false + includeDefaultExtraAnnotations: false + extraAnnotations: {} + ingressClassName: "cilium" + # backend port number + servicePort: 80 + + # configurationSnippet - Add additional Nginx configuration. This example statically sets a header on the ingress. + # configurationSnippet: | + # more_set_input_headers "X-Forwarded-Host: {{ .Values.hostname }}"; + + tls: + # options: rancher, letsEncrypt, secret + source: rancher + secretName: tls-rancher-ingress + +### service ### +# Override to use NodePort or LoadBalancer service type - default is ClusterIP +service: + type: "LoadBalancer" + annotations: {} + targetPorts: + https: http +### LetsEncrypt config ### +# ProTip: The production environment only allows you to register a name 5 times a week. +# Use staging until you have your config right. +letsEncrypt: + # email: none@example.com + environment: production + ingress: + # options: traefik, nginx + class: "" +# If you are using certs signed by a private CA set to 'true' and set the 'tls-ca' +# in the 'rancher-system' namespace. See the README.md for details +privateCA: false + +# http[s] proxy server passed into rancher server. +# proxy: http://@:: + +# comma separated list of domains or ip addresses that will not use the proxy +noProxy: 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.svc,.cluster.local + +# Override rancher image location for Air Gap installs +rancherImage: rancher/rancher +# rancher/rancher image tag. https://hub.docker.com/r/rancher/rancher/tags/ +# Defaults to .Chart.appVersion +# rancherImageTag: v2.0.7 + +# Override imagePullPolicy for rancher server images +# options: Always, Never, IfNotPresent +# Defaults to IfNotPresent +# rancherImagePullPolicy: + +# Number of Rancher server replicas. Setting to negative number will dynamically between 0 and the abs(replicas) based on available nodes. +# of available nodes in the cluster +replicas: 3 + +# Set priorityClassName to avoid eviction +priorityClassName: rancher-critical + +# Set pod resource requests/limits for Rancher. +resources: {} + +# +# tls +# Where to offload the TLS/SSL encryption +# - ingress (default) +# - external +tls: external + +systemDefaultRegistry: "" + +# Set to use the packaged system charts +useBundledSystemChart: false + +# Certmanager version compatibility +certmanager: + version: "" + +# Rancher custom logos persistence +customLogos: + enabled: false + volumeSubpaths: + emberUi: "ember" + vueUi: "vue" + ## Volume kind to use for persistence: persistentVolumeClaim, configMap + volumeKind: persistentVolumeClaim + ## Use an existing volume. Custom logos should be copied to the volume by the user + # volumeName: custom-logos + ## Just for volumeKind: persistentVolumeClaim + ## To disables dynamic provisioning, set storageClass: "" or storageClass: "-" + # storageClass: "-" + accessMode: ReadWriteOnce + size: 1Gi + +# Rancher post-delete hook +postDelete: + enabled: true + image: + repository: rancher/shell + tag: v0.1.21-rc1 + namespaceList: + - cattle-fleet-system + - cattle-system + - rancher-operator-system + # Number of seconds to wait for an app to be uninstalled + timeout: 120 + # by default, the job will fail if it fail to uninstall any of the apps + ignoreTimeoutError: false + +# Set a bootstrap password. If leave empty, a random password will be generated. +bootstrapPassword: "admin2ch" +hostname: "rancher.guaranteedstruggle.host" + +livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 30 +readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 30 + +global: + cattle: + psp: + # will default to true on 1.24 and below, and false for 1.25 and above + # can be changed manually to true or false to bypass version checks and force that option + enabled: "" + +# helm values to use when installing the rancher-webhook chart. +# helm values set here will override all other global values used when installing the webhook such as priorityClassName and systemRegistry settings. +webhook: "" diff --git a/helm-charts/vault-helm b/helm-charts/vault-helm new file mode 160000 index 0000000..3e16e05 --- /dev/null +++ b/helm-charts/vault-helm @@ -0,0 +1 @@ +Subproject commit 3e16e05ba7132b1db567c6dcd37cc6a8ffa1d8fe