diff --git a/packages/apps/tenant/Chart.yaml b/packages/apps/tenant/Chart.yaml index eedbebf2..1dca128d 100644 --- a/packages/apps/tenant/Chart.yaml +++ b/packages/apps/tenant/Chart.yaml @@ -4,4 +4,4 @@ description: Separated tenant namespace icon: /logos/tenant.svg type: application -version: 1.6.0 +version: 1.6.1 diff --git a/packages/apps/tenant/templates/kubeconfig.yaml b/packages/apps/tenant/templates/kubeconfig.yaml new file mode 100644 index 00000000..59092e95 --- /dev/null +++ b/packages/apps/tenant/templates/kubeconfig.yaml @@ -0,0 +1,59 @@ +{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} +{{- $host := index $cozyConfig.data "root-host" }} +{{- $apiServerAdress := index $cozyConfig.data "api-server-adress" }} +{{- $k8sClientSecret := lookup "v1" "Secret" "cozy-keycloak" "k8s-client" }} +{{- $k8sClient := index $k8sClientSecret.data "client-secret-key" | b64dec }} +{{- $rootSaConfigMap := lookup "v1" "ConfigMap" "kube-system" "kube-root-ca.crt" }} +{{- $k8sCa := index $rootSaConfigMap.data "ca.crt" | b64enc }} + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "tenant.name" . }}-dashboard-resources + namespace: {{ .Release.namespace }} +rules: +- apiGroups: + - "" + resources: + - secrets + resourceNames: + - kubeconfig-{{ include "tenant.name" . }} + verbs: ["get", "list", "watch"] + + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: kubeconfig-{{ include "tenant.name" . }} + namespace: tenant-root +stringData: + kubeconfig: | + apiVersion: v1 + clusters: + - cluster: + server: https://{{ $apiServerAdress }}:6443 + certificate-authority-data: {{ $k8sCa }} + name: cluster + contexts: + - context: + cluster: cluster + namespace: {{ include "tenant.name" . }} + user: keycloak + name: {{ include "tenant.name" . }} + current-context: default + users: + - name: keycloak + user: + exec: + apiVersion: client.authentication.k8s.io/v1beta1 + args: + - oidc-login + - get-token + - --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy + - --oidc-client-id=kubernetes + - --oidc-client-secret={{ $k8sClient }} + - --skip-open-browser + - --grant-type=password + command: kubectl diff --git a/packages/apps/tenant/templates/tenant.yaml b/packages/apps/tenant/templates/tenant.yaml index ad95c437..646969e4 100644 --- a/packages/apps/tenant/templates/tenant.yaml +++ b/packages/apps/tenant/templates/tenant.yaml @@ -43,6 +43,9 @@ subjects: - kind: ServiceAccount name: tenant-root namespace: tenant-root +- kind: Group + name: tenant-root-super-admin + apiGroup: rbac.authorization.k8s.io {{- end }} {{- if hasPrefix "tenant-" .Release.Namespace }} {{- $parts := splitList "-" .Release.Namespace }} @@ -51,12 +54,18 @@ subjects: - kind: ServiceAccount name: {{ join "-" (slice $parts 0 (add $i 1)) }} namespace: {{ join "-" (slice $parts 0 (add $i 1)) }} +- kind: Group + name: {{ join "-" (slice $parts 0 (add $i 1)) }}-super-admin + apiGroup: rbac.authorization.k8s.io {{- end }} {{- end }} {{- end }} - kind: ServiceAccount name: {{ include "tenant.name" . }} namespace: {{ include "tenant.name" . }} +- kind: Group + name: {{ include "tenant.name" . }}-super-admin + apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: {{ include "tenant.name" . }} @@ -84,6 +93,9 @@ subjects: - kind: ServiceAccount name: {{ include "tenant.name" . }} namespace: {{ include "tenant.name" . }} +- kind: Group + name: {{ include "tenant.name" . }}-super-admin + apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: {{ include "tenant.name" . }} @@ -95,16 +107,47 @@ metadata: name: {{ include "tenant.name" . }}-view namespace: {{ include "tenant.name" . }} rules: - - apiGroups: ["apps.cozystack.io"] - resources: ["*"] - verbs: ["get", "list", "watch"] - - apiGroups: ["helm.toolkit.fluxcd.io"] - resources: ["helmreleases"] - verbs: ["get", "list", "watch"] - - apiGroups: [""] - resources: ["pods", "pods/log"] - verbs: ["get", "list", "watch"] + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - get + - apiGroups: + - apps.cozystack.io + resources: + - "*" + verbs: + - get + - list + - watch + - apiGroups: + - helm.toolkit.fluxcd.io + resources: + - helmreleases + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - "*" + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + --- + kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -125,21 +168,46 @@ metadata: name: {{ include "tenant.name" . }}-use namespace: {{ include "tenant.name" . }} rules: + - apiGroups: [rbac.authorization.k8s.io] + resources: + - roles + verbs: + - get - apiGroups: ["apps.cozystack.io"] - resources: ["*"] - verbs: ["get", "list", "watch"] + resources: + - "*" + verbs: + - get + - list + - watch - apiGroups: ["helm.toolkit.fluxcd.io"] - resources: ["helmreleases"] - verbs: ["get", "list", "watch"] + resources: + - helmreleases + verbs: + - get + - list + - watch - apiGroups: [""] - resources: ["pods", "pods/log"] - verbs: ["get", "list", "watch"] - - apiGroups: ["kubevirt.io"] - resources: ["virtualmachines"] - verbs: ["get", "list"] + resources: + - "*" + verbs: + - get + - list + - watch + - apiGroups: ["networking.k8s.io"] + resources: + - ingresses + verbs: + - get + - list + - watch - apiGroups: ["subresources.kubevirt.io"] - resources: ["virtualmachineinstances/console", "virtualmachineinstances/vnc"] - verbs: ["get", "list"] + resources: + - virtualmachineinstances/console + - virtualmachineinstances/vnc + verbs: + - get + - list --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -161,22 +229,124 @@ metadata: name: {{ include "tenant.name" . }}-admin namespace: {{ include "tenant.name" . }} rules: - - apiGroups: ["helm.toolkit.fluxcd.io"] - resources: ["helmreleases"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [rbac.authorization.k8s.io] + resources: + - roles + verbs: + - get - apiGroups: [""] - resources: ["pods/log", "pods"] - verbs: ["get", "list", "watch", "delete"] + resources: + - "*" + verbs: + - get + - list + - watch + - delete + - apiGroups: ["helm.toolkit.fluxcd.io"] + resources: + - helmreleases + verbs: + - get + - list + - watch - apiGroups: ["kubevirt.io"] - resources: ["virtualmachines"] - verbs: ["get", "list"] + resources: + - virtualmachines + verbs: + - get + - list - apiGroups: ["subresources.kubevirt.io"] - resources: ["virtualmachineinstances/console", "virtualmachineinstances/vnc"] - verbs: ["get", "list"] + resources: + - virtualmachineinstances/console + - virtualmachineinstances/vnc + verbs: + - get + - list - apiGroups: ["apps.cozystack.io"] - resources: ["buckets", "clickhouses", "ferretdb", "foos", "httpcaches", "kafkas", "kuberneteses", "mysqls", "natses", "postgreses", "rabbitmqs", "redises", "seaweedfses", "tcpbalancers", "virtualmachines", "vmdisks", "vminstances"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + resources: + - buckets + - clickhouses + - ferretdb + - foos + - httpcaches + - kafkas + - kuberneteses + - mysqls + - natses + - postgreses + - rabbitmqs + - redises + - seaweedfses + - tcpbalancers + - virtualmachines + - vmdisks + - vminstances + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "tenant.name" . }}-admin + namespace: cozy-public +rules: + - apiGroups: ["source.toolkit.fluxcd.io"] + resources: ["helmrepositories"] + verbs: + - get + - list + - apiGroups: + - source.toolkit.fluxcd.io + resources: + - helmcharts + verbs: + - get + - list + - apiGroups: ["source.toolkit.fluxcd.io"] + resources: + - helmcharts + verbs: ["*"] + resourceNames: + - bucket + - clickhouse + - ferretdb + - foo + - httpcache + - kafka + - kubernetes + - mysql + - nats + - postgres + - rabbitmq + - redis + - seaweedfs + - tcpbalancer + - virtualmachine + - vmdisk + - vminstance + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "tenant.name" . }}-admin + namespace: cozy-public +subjects: +- kind: Group + name: {{ include "tenant.name" . }}-admin + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: {{ include "tenant.name" . }}-admin + apiGroup: rbac.authorization.k8s.io --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -191,40 +361,3 @@ roleRef: kind: Role name: {{ include "tenant.name" . }}-admin apiGroup: rbac.authorization.k8s.io ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ include "tenant.name" . }}-super-admin - namespace: {{ include "tenant.name" . }} -rules: - - apiGroups: ["helm.toolkit.fluxcd.io"] - resources: ["helmreleases"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - - apiGroups: [""] - resources: ["pods/log", "pods"] - verbs: ["get", "list", "watch", "delete"] - - apiGroups: ["kubevirt.io"] - resources: ["virtualmachines"] - verbs: ["get", "list"] - - apiGroups: ["subresources.kubevirt.io"] - resources: ["virtualmachineinstances/console", "virtualmachineinstances/vnc"] - verbs: ["get", "list"] - - apiGroups: ["apps.cozystack.io"] - resources: ["*"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{ include "tenant.name" . }}-super-admin - namespace: {{ include "tenant.name" . }} -subjects: - - kind: Group - name: {{ include "tenant.name" . }}-super-admin - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: Role - name: {{ include "tenant.name" . }}-super-admin - apiGroup: rbac.authorization.k8s.io diff --git a/packages/apps/versions_map b/packages/apps/versions_map index 08c646bc..6ad48e5e 100644 --- a/packages/apps/versions_map +++ b/packages/apps/versions_map @@ -87,7 +87,8 @@ tenant 1.3.0 ceefae03 tenant 1.3.1 c56e5769 tenant 1.4.0 94c688f7 tenant 1.5.0 48128743 -tenant 1.6.0 HEAD +tenant 1.6.0 df448b99 +tenant 1.6.1 HEAD virtual-machine 0.1.4 f2015d6 virtual-machine 0.1.5 7cd7de7 virtual-machine 0.2.0 5ca8823 diff --git a/packages/core/platform/bundles/paas-full.yaml b/packages/core/platform/bundles/paas-full.yaml index 27e1dd32..6a252b9d 100644 --- a/packages/core/platform/bundles/paas-full.yaml +++ b/packages/core/platform/bundles/paas-full.yaml @@ -1,4 +1,8 @@ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} +{{- $host := index $cozyConfig.data "root-host" }} +{{- if not $host }} +{{- fail "ERROR need root-host in cozystack ConfigMap" }} +{{- end }} releases: - name: fluxcd-operator @@ -200,11 +204,14 @@ releases: releaseName: dashboard chart: cozy-dashboard namespace: cozy-dashboard - dependsOn: [cilium,kubeovn] + dependsOn: [cilium,kubeovn,keycloak-configure] + valuesFrom: + - kind: ConfigMap + name: kubeapps-auth-config + valuesKey: values.yaml {{- if .Capabilities.APIVersions.Has "source.toolkit.fluxcd.io/v1" }} {{- with (lookup "source.toolkit.fluxcd.io/v1" "HelmRepository" "cozy-public" "").items }} values: - kubeapps: redis: master: podAnnotations: diff --git a/packages/core/platform/bundles/paas-hosted.yaml b/packages/core/platform/bundles/paas-hosted.yaml index 695a4994..08d269ea 100644 --- a/packages/core/platform/bundles/paas-hosted.yaml +++ b/packages/core/platform/bundles/paas-hosted.yaml @@ -1,4 +1,8 @@ {{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} +{{- $host := index $cozyConfig.data "root-host" }} +{{- if not $host }} +{{- fail "ERROR need root-host in cozystack ConfigMap" }} +{{- end }} releases: - name: fluxcd-operator @@ -130,7 +134,11 @@ releases: releaseName: dashboard chart: cozy-dashboard namespace: cozy-dashboard - dependsOn: [] + dependsOn: [keycloak-configure] + valuesFrom: + - kind: ConfigMap + name: kubeapps-auth-config + valuesKey: values.yaml {{- if .Capabilities.APIVersions.Has "source.toolkit.fluxcd.io/v1" }} {{- with (lookup "source.toolkit.fluxcd.io/v1" "HelmRepository" "cozy-public" "").items }} values: diff --git a/packages/core/platform/templates/apps.yaml b/packages/core/platform/templates/apps.yaml index 859302db..f1872870 100644 --- a/packages/core/platform/templates/apps.yaml +++ b/packages/core/platform/templates/apps.yaml @@ -2,6 +2,12 @@ {{- $bundleName := index $cozyConfig.data "bundle-name" }} {{- $bundle := tpl (.Files.Get (printf "bundles/%s.yaml" $bundleName)) . | fromYaml }} {{- $host := "example.org" }} +{{- $host := "example.org" }} +{{- if $cozyConfig.data }} + {{- if hasKey $cozyConfig.data "root-host" }} + {{- $host = index $cozyConfig.data "root-host" }} + {{- end }} +{{- end }} {{- $tenantRoot := list }} {{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }} {{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }} diff --git a/packages/core/platform/templates/helmreleases.yaml b/packages/core/platform/templates/helmreleases.yaml index 1563a1a3..df0b1bfd 100644 --- a/packages/core/platform/templates/helmreleases.yaml +++ b/packages/core/platform/templates/helmreleases.yaml @@ -56,6 +56,18 @@ spec: values: {{- toYaml . | nindent 4}} {{- end }} + + {{- if $x.valuesFrom }} + valuesFrom: + {{- range $source := $x.valuesFrom }} + - kind: {{ $source.kind }} + name: {{ $source.name }} + {{- if $source.valuesKey }} + valuesKey: {{ $source.valuesKey }} + {{- end }} + {{- end }} + {{- end }} + {{- with $x.dependsOn }} dependsOn: {{- range $dep := . }} diff --git a/packages/extra/ingress/templates/dashboard.yaml b/packages/extra/ingress/templates/dashboard.yaml index 63b59e02..830e7a0a 100644 --- a/packages/extra/ingress/templates/dashboard.yaml +++ b/packages/extra/ingress/templates/dashboard.yaml @@ -10,9 +10,13 @@ kind: Ingress metadata: annotations: cert-manager.io/cluster-issuer: letsencrypt-prod - {{- if eq $issuerType "cloudflare" }} + {{- if eq $issuerType "cloudflare" }} {{- else }} acme.cert-manager.io/http01-ingress-class: {{ .Release.Namespace }} + nginx.ingress.kubernetes.io/proxy-body-size: 100m + nginx.ingress.kubernetes.io/proxy-buffer-size: 100m + nginx.ingress.kubernetes.io/proxy-buffers-number: "4" + nginx.ingress.kubernetes.io/client-max-body-size: 100m {{- end }} name: dashboard-{{ .Release.Namespace }} namespace: cozy-dashboard diff --git a/packages/system/dashboard/charts/kubeapps/Chart.lock b/packages/system/dashboard/charts/kubeapps/Chart.lock index 6c26c207..93e54bb9 100644 --- a/packages/system/dashboard/charts/kubeapps/Chart.lock +++ b/packages/system/dashboard/charts/kubeapps/Chart.lock @@ -1,12 +1,12 @@ dependencies: - name: redis repository: oci://registry-1.docker.io/bitnamicharts - version: 19.6.3 + version: 20.2.1 - name: postgresql repository: oci://registry-1.docker.io/bitnamicharts - version: 15.5.19 + version: 16.1.0 - name: common repository: oci://registry-1.docker.io/bitnamicharts - version: 2.20.5 -digest: sha256:eb2c690088e9dd237a1443aeedcf71419d5d4efe6999cf9e352b5407c005c6bc -generated: "2024-07-25T06:10:39.073759816Z" + version: 2.26.0 +digest: sha256:8765098cabaca39ce13d856f5260df97667201dac6d2209280e5de9ad1a33006 +generated: "2024-10-31T19:49:51.754205675Z" diff --git a/packages/system/dashboard/charts/kubeapps/Chart.yaml b/packages/system/dashboard/charts/kubeapps/Chart.yaml index 9300a247..d0529f4e 100644 --- a/packages/system/dashboard/charts/kubeapps/Chart.yaml +++ b/packages/system/dashboard/charts/kubeapps/Chart.yaml @@ -2,33 +2,33 @@ annotations: category: Infrastructure images: | - name: kubeapps-apis - image: docker.io/bitnami/kubeapps-apis:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-apis:2.12.0-debian-12-r0 - name: kubeapps-apprepository-controller - image: docker.io/bitnami/kubeapps-apprepository-controller:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-apprepository-controller:2.12.0-debian-12-r0 - name: kubeapps-asset-syncer - image: docker.io/bitnami/kubeapps-asset-syncer:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-asset-syncer:2.12.0-debian-12-r0 - name: kubeapps-dashboard - image: docker.io/bitnami/kubeapps-dashboard:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-dashboard:2.12.0-debian-12-r0 - name: kubeapps-oci-catalog - image: docker.io/bitnami/kubeapps-oci-catalog:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-oci-catalog:2.12.0-debian-12-r0 - name: kubeapps-pinniped-proxy - image: docker.io/bitnami/kubeapps-pinniped-proxy:2.11.0-debian-12-r2 + image: docker.io/bitnami/kubeapps-pinniped-proxy:2.12.0-debian-12-r0 - name: nginx - image: docker.io/bitnami/nginx:1.27.0-debian-12-r4 + image: docker.io/bitnami/nginx:1.27.2-debian-12-r2 - name: oauth2-proxy - image: docker.io/bitnami/oauth2-proxy:7.6.0-debian-12-r17 + image: docker.io/bitnami/oauth2-proxy:7.7.1-debian-12-r1 licenses: Apache-2.0 apiVersion: v2 -appVersion: 2.11.0 +appVersion: 2.12.0 dependencies: - condition: packaging.flux.enabled name: redis repository: oci://registry-1.docker.io/bitnamicharts - version: 19.x.x + version: 20.x.x - condition: packaging.helm.enabled name: postgresql repository: oci://registry-1.docker.io/bitnamicharts - version: 15.x.x + version: 16.x.x - name: common repository: oci://registry-1.docker.io/bitnamicharts tags: @@ -51,4 +51,4 @@ maintainers: name: kubeapps sources: - https://github.com/bitnami/charts/tree/main/bitnami/kubeapps -version: 15.3.10 +version: 17.0.3 diff --git a/packages/system/dashboard/charts/kubeapps/README.md b/packages/system/dashboard/charts/kubeapps/README.md index 759ce393..14855b42 100644 --- a/packages/system/dashboard/charts/kubeapps/README.md +++ b/packages/system/dashboard/charts/kubeapps/README.md @@ -218,7 +218,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `frontend.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | | `frontend.podSecurityContext.fsGroup` | Set frontend pod's Security Context fsGroup | `1001` | | `frontend.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `frontend.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `frontend.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `frontend.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `frontend.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `frontend.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -326,7 +326,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `dashboard.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | | `dashboard.podSecurityContext.fsGroup` | Set Dashboard pod's Security Context fsGroup | `1001` | | `dashboard.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `dashboard.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `dashboard.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `dashboard.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `dashboard.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `dashboard.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -427,7 +427,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `apprepository.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | | `apprepository.podSecurityContext.fsGroup` | Set AppRepository Controller pod's Security Context fsGroup | `1001` | | `apprepository.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `apprepository.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `apprepository.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `apprepository.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `apprepository.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `apprepository.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -506,7 +506,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `authProxy.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the Auth Proxy container(s) | `[]` | | `authProxy.containerPorts.proxy` | Auth Proxy HTTP container port | `3000` | | `authProxy.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `authProxy.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `authProxy.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `authProxy.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `authProxy.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `authProxy.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -543,7 +543,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `pinnipedProxy.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the Pinniped Proxy container(s) | `[]` | | `pinnipedProxy.containerPorts.pinnipedProxy` | Pinniped Proxy container port | `3333` | | `pinnipedProxy.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `pinnipedProxy.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `pinnipedProxy.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `pinnipedProxy.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `pinnipedProxy.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `pinnipedProxy.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -629,7 +629,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `kubeappsapis.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | | `kubeappsapis.podSecurityContext.fsGroup` | Set KubeappsAPIs pod's Security Context fsGroup | `1001` | | `kubeappsapis.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `kubeappsapis.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `kubeappsapis.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `kubeappsapis.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `kubeappsapis.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `kubeappsapis.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -718,7 +718,7 @@ In the first two cases, it is needed a certificate and a key. We would expect th | `ociCatalog.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if ociCatalog.resources is set (ociCatalog.resources is recommended for production). | `micro` | | `ociCatalog.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | | `ociCatalog.containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | -| `ociCatalog.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `ociCatalog.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `ociCatalog.containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | | `ociCatalog.containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | | `ociCatalog.containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | @@ -1031,6 +1031,14 @@ helm upgrade $RELEASE_NAME oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps If you find issues upgrading Kubeapps, check the [troubleshooting](#error-while-upgrading-the-chart) section. +### To 17.0.0 + +This major updates the PostgreSQL subchart to its newest major, 16.0.0, which uses PostgreSQL 17.x. Follow the [official instructions](https://www.postgresql.org/docs/17/upgrading.html) to upgrade to 17.x. + +### To 16.0.0 + +This major updates the Redis® subchart to its newest major, 20.0.0. [Here](https://github.com/bitnami/charts/tree/main/bitnami/redis#to-2000) you can find more information about the changes introduced in that version. + ### To 15.0.0 This major bump changes the following security defaults: @@ -1173,7 +1181,7 @@ kubectl delete statefulset -n kubeapps kubeapps-postgresql-master kubeapps-postg #### Useful links -- +- - - diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/Chart.yaml b/packages/system/dashboard/charts/kubeapps/charts/common/Chart.yaml index dabd8068..0d437c4c 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/Chart.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/common/Chart.yaml @@ -2,7 +2,7 @@ annotations: category: Infrastructure licenses: Apache-2.0 apiVersion: v2 -appVersion: 2.20.5 +appVersion: 2.26.0 description: A Library Helm Chart for grouping common logic between bitnami charts. This chart is not deployable by itself. home: https://bitnami.com @@ -20,4 +20,4 @@ name: common sources: - https://github.com/bitnami/charts/tree/main/bitnami/common type: library -version: 2.20.5 +version: 2.26.0 diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_affinities.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_affinities.tpl index c2d29079..d387dbe6 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_affinities.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_affinities.tpl @@ -60,13 +60,14 @@ Return a topologyKey definition {{/* Return a soft podAffinity/podAntiAffinity definition -{{ include "common.affinities.pods.soft" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "context" $) -}} +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "extraNamespaces" (list "namespace1" "namespace2") "context" $) -}} */}} {{- define "common.affinities.pods.soft" -}} {{- $component := default "" .component -}} {{- $customLabels := default (dict) .customLabels -}} {{- $extraMatchLabels := default (dict) .extraMatchLabels -}} {{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +{{- $extraNamespaces := default (list) .extraNamespaces -}} preferredDuringSchedulingIgnoredDuringExecution: - podAffinityTerm: labelSelector: @@ -77,6 +78,13 @@ preferredDuringSchedulingIgnoredDuringExecution: {{- range $key, $value := $extraMatchLabels }} {{ $key }}: {{ $value | quote }} {{- end }} + {{- if $extraNamespaces }} + namespaces: + - {{ .context.Release.Namespace }} + {{- with $extraNamespaces }} + {{ include "common.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} weight: 1 {{- range $extraPodAffinityTerms }} @@ -96,13 +104,14 @@ preferredDuringSchedulingIgnoredDuringExecution: {{/* Return a hard podAffinity/podAntiAffinity definition -{{ include "common.affinities.pods.hard" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "context" $) -}} +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "customLabels" .Values.podLabels "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "extraPodAffinityTerms" .Values.extraPodAffinityTerms "extraNamespaces" (list "namespace1" "namespace2") "context" $) -}} */}} {{- define "common.affinities.pods.hard" -}} {{- $component := default "" .component -}} {{- $customLabels := default (dict) .customLabels -}} {{- $extraMatchLabels := default (dict) .extraMatchLabels -}} {{- $extraPodAffinityTerms := default (list) .extraPodAffinityTerms -}} +{{- $extraNamespaces := default (list) .extraNamespaces -}} requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: {{- (include "common.labels.matchLabels" ( dict "customLabels" $customLabels "context" .context )) | nindent 8 }} @@ -112,6 +121,13 @@ requiredDuringSchedulingIgnoredDuringExecution: {{- range $key, $value := $extraMatchLabels }} {{ $key }}: {{ $value | quote }} {{- end }} + {{- if $extraNamespaces }} + namespaces: + - {{ .context.Release.Namespace }} + {{- with $extraNamespaces }} + {{ include "common.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} + {{- end }} + {{- end }} topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} {{- range $extraPodAffinityTerms }} - labelSelector: diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_compatibility.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_compatibility.tpl index eb4061d7..a61588d6 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_compatibility.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_compatibility.tpl @@ -34,6 +34,10 @@ Usage: {{- end -}} {{- end -}} {{- end -}} +{{/* Remove empty seLinuxOptions object if global.compatibility.omitEmptySeLinuxOptions is set to true */}} +{{- if and (((.context.Values.global).compatibility).omitEmptySeLinuxOptions) (not .secContext.seLinuxOptions) -}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} +{{- end -}} {{/* Remove fields that are disregarded when running the container in privileged mode */}} {{- if $adaptedContext.privileged -}} {{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_images.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_images.tpl index 6821b1ce..76bb7ce4 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_images.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_images.tpl @@ -5,8 +5,9 @@ SPDX-License-Identifier: APACHE-2.0 {{/* vim: set filetype=mustache: */}} {{/* -Return the proper image name -{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global ) }} +Return the proper image name. +If image tag and digest are not defined, termination fallbacks to chart appVersion. +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global "chart" .Chart ) }} */}} {{- define "common.images.image" -}} {{- $registryName := default .imageRoot.registry ((.global).imageRegistry) -}} @@ -14,6 +15,11 @@ Return the proper image name {{- $separator := ":" -}} {{- $termination := .imageRoot.tag | toString -}} +{{- if not .imageRoot.tag }} + {{- if .chart }} + {{- $termination = .chart.AppVersion | toString -}} + {{- end -}} +{{- end -}} {{- if .imageRoot.digest }} {{- $separator = "@" -}} {{- $termination = .imageRoot.digest | toString -}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_secrets.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_secrets.tpl index e87575a8..801918ce 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_secrets.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_secrets.tpl @@ -103,30 +103,33 @@ The order in which this function returns a secret password: {{- $password = index $secretData .key | b64dec }} {{- else if not (eq .failOnNew false) }} {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} - {{- else if $providedPasswordValue }} + {{- end -}} +{{- end }} + +{{- if not $password }} + {{- if $providedPasswordValue }} {{- $password = $providedPasswordValue | toString }} - {{- end -}} -{{- else if $providedPasswordValue }} - {{- $password = $providedPasswordValue | toString }} -{{- else }} - - {{- if .context.Values.enabled }} - {{- $subchart = $chartName }} - {{- end -}} - - {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} - {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} - {{- $passwordValidationErrors := list $requiredPasswordError -}} - {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} - - {{- if .strong }} - {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} - {{- $password = randAscii $passwordLength }} - {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} - {{- $password = printf "%s%s" $subStr $password | toString | shuffle }} {{- else }} - {{- $password = randAlphaNum $passwordLength }} - {{- end }} + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- if not (eq .failOnNew false) }} + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + {{- end }} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle }} + {{- else }} + {{- $password = randAlphaNum $passwordLength }} + {{- end }} + {{- end -}} {{- end -}} {{- if not .skipB64enc }} {{- $password = $password | b64enc }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_tplvalues.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_tplvalues.tpl index c84d72c8..a04f4c1e 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/_tplvalues.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/_tplvalues.tpl @@ -36,3 +36,17 @@ Usage: {{- end -}} {{ $dst | toYaml }} {{- end -}} + +{{/* +Merge a list of values that contains template after rendering them. +Merge precedence is consistent with https://masterminds.github.io/sprig/dicts.html#mergeoverwrite-mustmergeoverwrite +Usage: +{{ include "common.tplvalues.merge-overwrite" ( dict "values" (list .Values.path.to.the.Value1 .Values.path.to.the.Value2) "context" $ ) }} +*/}} +{{- define "common.tplvalues.merge-overwrite" -}} +{{- $dst := dict -}} +{{- range .values -}} +{{- $dst = include "common.tplvalues.render" (dict "value" . "context" $.context "scope" $.scope) | fromYaml | mergeOverwrite $dst -}} +{{- end -}} +{{ $dst | toYaml }} +{{- end -}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_cassandra.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_cassandra.tpl index 3f41ff8f..f8fd213b 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_cassandra.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_cassandra.tpl @@ -4,32 +4,6 @@ SPDX-License-Identifier: APACHE-2.0 */}} {{/* vim: set filetype=mustache: */}} -{{/* -Validate Cassandra required passwords are not empty. - -Usage: -{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} -Params: - - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" - - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false -*/}} -{{- define "common.validations.values.cassandra.passwords" -}} - {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} - {{- $enabled := include "common.cassandra.values.enabled" . -}} - {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} - {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} - - {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} - {{- $requiredPasswords := list -}} - - {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} - - {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} - - {{- end -}} -{{- end -}} - {{/* Auxiliary function to get the right value for existingSecret. diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mongodb.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mongodb.tpl index d4cd38cb..e678a6de 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mongodb.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mongodb.tpl @@ -4,52 +4,6 @@ SPDX-License-Identifier: APACHE-2.0 */}} {{/* vim: set filetype=mustache: */}} -{{/* -Validate MongoDB® required passwords are not empty. - -Usage: -{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} -Params: - - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" - - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false -*/}} -{{- define "common.validations.values.mongodb.passwords" -}} - {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} - {{- $enabled := include "common.mongodb.values.enabled" . -}} - {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} - {{- $architecture := include "common.mongodb.values.architecture" . -}} - {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} - {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} - {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} - {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} - {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} - {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} - - {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} - - {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} - {{- $requiredPasswords := list -}} - - {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} - - {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} - {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} - {{- if and $valueUsername $valueDatabase -}} - {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} - {{- end -}} - - {{- if (eq $architecture "replicaset") -}} - {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} - {{- end -}} - - {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} - - {{- end -}} -{{- end -}} - {{/* Auxiliary function to get the right value for existingSecret. diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mysql.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mysql.tpl index 924812a9..fbb65c33 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mysql.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_mysql.tpl @@ -4,47 +4,6 @@ SPDX-License-Identifier: APACHE-2.0 */}} {{/* vim: set filetype=mustache: */}} -{{/* -Validate MySQL required passwords are not empty. - -Usage: -{{ include "common.validations.values.mysql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} -Params: - - secret - String - Required. Name of the secret where MySQL values are stored, e.g: "mysql-passwords-secret" - - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false -*/}} -{{- define "common.validations.values.mysql.passwords" -}} - {{- $existingSecret := include "common.mysql.values.auth.existingSecret" . -}} - {{- $enabled := include "common.mysql.values.enabled" . -}} - {{- $architecture := include "common.mysql.values.architecture" . -}} - {{- $authPrefix := include "common.mysql.values.key.auth" . -}} - {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} - {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} - {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} - {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} - - {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} - {{- $requiredPasswords := list -}} - - {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mysql-root-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} - - {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} - {{- if not (empty $valueUsername) -}} - {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mysql-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} - {{- end -}} - - {{- if (eq $architecture "replication") -}} - {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mysql-replication-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} - {{- end -}} - - {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} - - {{- end -}} -{{- end -}} - {{/* Auxiliary function to get the right value for existingSecret. diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_postgresql.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_postgresql.tpl index 0fa0b146..51d47162 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_postgresql.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_postgresql.tpl @@ -4,35 +4,6 @@ SPDX-License-Identifier: APACHE-2.0 */}} {{/* vim: set filetype=mustache: */}} -{{/* -Validate PostgreSQL required passwords are not empty. - -Usage: -{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} -Params: - - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" - - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false -*/}} -{{- define "common.validations.values.postgresql.passwords" -}} - {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} - {{- $enabled := include "common.postgresql.values.enabled" . -}} - {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} - {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} - {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} - {{- $requiredPasswords := list -}} - {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} - - {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} - {{- if (eq $enabledReplication "true") -}} - {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} - {{- end -}} - - {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} - {{- end -}} -{{- end -}} - {{/* Auxiliary function to decide whether evaluate global values. diff --git a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_redis.tpl b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_redis.tpl index f4778256..9fedfef9 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_redis.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/common/templates/validations/_redis.tpl @@ -5,39 +5,6 @@ SPDX-License-Identifier: APACHE-2.0 {{/* vim: set filetype=mustache: */}} -{{/* -Validate Redis® required passwords are not empty. - -Usage: -{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} -Params: - - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" - - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false -*/}} -{{- define "common.validations.values.redis.passwords" -}} - {{- $enabled := include "common.redis.values.enabled" . -}} - {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} - {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} - - {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} - {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} - - {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} - {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} - - {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} - {{- $requiredPasswords := list -}} - - {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} - {{- if eq $useAuth "true" -}} - {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} - {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} - {{- end -}} - - {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} - {{- end -}} -{{- end -}} - {{/* Auxiliary function to get the right value for enabled redis. diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.lock b/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.lock index 20827493..c399b3a7 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.lock +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.lock @@ -1,6 +1,6 @@ dependencies: - name: common repository: oci://registry-1.docker.io/bitnamicharts - version: 2.20.5 -digest: sha256:5b98791747a148b9d4956b81bb8635f49a0ae831869d700d52e514b8fd1a2445 -generated: "2024-07-16T12:17:39.814241+02:00" + version: 2.23.0 +digest: sha256:fbd6439f12ded949c04553b9c52a4c8153a8f2790147d972b314ddcd46921a14 +generated: "2024-09-14T18:55:25.608679155Z" diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.yaml index 30f3b278..ffb31a4d 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/Chart.yaml @@ -2,18 +2,18 @@ annotations: category: Database images: | - name: kubectl - image: docker.io/bitnami/kubectl:1.30.3-debian-12-r3 + image: docker.io/bitnami/kubectl:1.31.1-debian-12-r3 - name: os-shell - image: docker.io/bitnami/os-shell:12-debian-12-r26 + image: docker.io/bitnami/os-shell:12-debian-12-r30 - name: redis - image: docker.io/bitnami/redis:7.2.5-debian-12-r3 + image: docker.io/bitnami/redis:7.4.1-debian-12-r0 - name: redis-exporter - image: docker.io/bitnami/redis-exporter:1.62.0-debian-12-r1 + image: docker.io/bitnami/redis-exporter:1.63.0-debian-12-r1 - name: redis-sentinel - image: docker.io/bitnami/redis-sentinel:7.2.5-debian-12-r3 + image: docker.io/bitnami/redis-sentinel:7.4.1-debian-12-r0 licenses: Apache-2.0 apiVersion: v2 -appVersion: 7.2.5 +appVersion: 7.4.1 dependencies: - name: common repository: oci://registry-1.docker.io/bitnamicharts @@ -35,4 +35,4 @@ maintainers: name: redis sources: - https://github.com/bitnami/charts/tree/main/bitnami/redis -version: 19.6.3 +version: 20.2.1 diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/README.md b/packages/system/dashboard/charts/kubeapps/charts/redis/README.md index 250e24a8..9b01882e 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/README.md +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/README.md @@ -608,6 +608,7 @@ helm install my-release --set master.persistence.existingClaim=PVC_NAME oci://RE | `master.pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | | `master.pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `{}` | | `master.pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `master.pdb.minAvailable` and `master.pdb.maxUnavailable` are empty. | `{}` | +| `master.extraPodSpec` | Optionally specify extra PodSpec for the Redis® master pod(s) | `{}` | ### Redis® replicas configuration parameters @@ -736,6 +737,7 @@ helm install my-release --set master.persistence.existingClaim=PVC_NAME oci://RE | `replica.pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | | `replica.pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `{}` | | `replica.pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `replica.pdb.minAvailable` and `replica.pdb.maxUnavailable` are empty. | `{}` | +| `replica.extraPodSpec` | Optionally specify extra PodSpec for the Redis® replicas pod(s) | `{}` | ### Redis® Sentinel configuration parameters @@ -847,6 +849,7 @@ helm install my-release --set master.persistence.existingClaim=PVC_NAME oci://RE | `sentinel.masterService.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | | `sentinel.masterService.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | | `sentinel.terminationGracePeriodSeconds` | Integer setting the termination grace period for the redis-node pods | `30` | +| `sentinel.extraPodSpec` | Optionally specify extra PodSpec for the Redis® Sentinel pod(s) | `{}` | ### Other Parameters @@ -988,6 +991,7 @@ helm install my-release --set master.persistence.existingClaim=PVC_NAME oci://RE | `volumePermissions.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | | `volumePermissions.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | | `volumePermissions.containerSecurityContext.runAsUser` | Set init container's Security Context runAsUser | `0` | +| `volumePermissions.extraEnvVars` | Array with extra environment variables to add to volume permissions init container. | `[]` | | `kubectl.image.registry` | Kubectl image registry | `REGISTRY_NAME` | | `kubectl.image.repository` | Kubectl image repository | `REPOSITORY_NAME/kubectl` | | `kubectl.image.digest` | Kubectl image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | @@ -1068,6 +1072,10 @@ This issue can be mitigated by splitting the upgrade into two stages: one for al - Stage 2 (anything else that is not up to date, in this case only master): `helm upgrade oci://REGISTRY_NAME/REPOSITORY_NAME/redis` +### To 20.0.0 + +This major version updates the Redis® docker image version used from `7.2` to `7.4`, the new stable version. There are no major changes in the chart, but we recommend checking the [Redis® 7.4 release notes](https://raw.githubusercontent.com/redis/redis/7.4/00-RELEASENOTES) before upgrading. + ### To 19.0.0 This major bump changes the following security defaults: diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/Chart.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/Chart.yaml index dabd8068..8cc0aaa0 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/Chart.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/Chart.yaml @@ -2,7 +2,7 @@ annotations: category: Infrastructure licenses: Apache-2.0 apiVersion: v2 -appVersion: 2.20.5 +appVersion: 2.23.0 description: A Library Helm Chart for grouping common logic between bitnami charts. This chart is not deployable by itself. home: https://bitnami.com @@ -20,4 +20,4 @@ name: common sources: - https://github.com/bitnami/charts/tree/main/bitnami/common type: library -version: 2.20.5 +version: 2.23.0 diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_compatibility.tpl b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_compatibility.tpl index eb4061d7..a61588d6 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_compatibility.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_compatibility.tpl @@ -34,6 +34,10 @@ Usage: {{- end -}} {{- end -}} {{- end -}} +{{/* Remove empty seLinuxOptions object if global.compatibility.omitEmptySeLinuxOptions is set to true */}} +{{- if and (((.context.Values.global).compatibility).omitEmptySeLinuxOptions) (not .secContext.seLinuxOptions) -}} + {{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}} +{{- end -}} {{/* Remove fields that are disregarded when running the container in privileged mode */}} {{- if $adaptedContext.privileged -}} {{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_images.tpl b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_images.tpl index 6821b1ce..76bb7ce4 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_images.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_images.tpl @@ -5,8 +5,9 @@ SPDX-License-Identifier: APACHE-2.0 {{/* vim: set filetype=mustache: */}} {{/* -Return the proper image name -{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global ) }} +Return the proper image name. +If image tag and digest are not defined, termination fallbacks to chart appVersion. +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global "chart" .Chart ) }} */}} {{- define "common.images.image" -}} {{- $registryName := default .imageRoot.registry ((.global).imageRegistry) -}} @@ -14,6 +15,11 @@ Return the proper image name {{- $separator := ":" -}} {{- $termination := .imageRoot.tag | toString -}} +{{- if not .imageRoot.tag }} + {{- if .chart }} + {{- $termination = .chart.AppVersion | toString -}} + {{- end -}} +{{- end -}} {{- if .imageRoot.digest }} {{- $separator = "@" -}} {{- $termination = .imageRoot.digest | toString -}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_secrets.tpl b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_secrets.tpl index e87575a8..801918ce 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_secrets.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/charts/common/templates/_secrets.tpl @@ -103,30 +103,33 @@ The order in which this function returns a secret password: {{- $password = index $secretData .key | b64dec }} {{- else if not (eq .failOnNew false) }} {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} - {{- else if $providedPasswordValue }} + {{- end -}} +{{- end }} + +{{- if not $password }} + {{- if $providedPasswordValue }} {{- $password = $providedPasswordValue | toString }} - {{- end -}} -{{- else if $providedPasswordValue }} - {{- $password = $providedPasswordValue | toString }} -{{- else }} - - {{- if .context.Values.enabled }} - {{- $subchart = $chartName }} - {{- end -}} - - {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} - {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} - {{- $passwordValidationErrors := list $requiredPasswordError -}} - {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} - - {{- if .strong }} - {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} - {{- $password = randAscii $passwordLength }} - {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} - {{- $password = printf "%s%s" $subStr $password | toString | shuffle }} {{- else }} - {{- $password = randAlphaNum $passwordLength }} - {{- end }} + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- if not (eq .failOnNew false) }} + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + {{- end }} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle }} + {{- else }} + {{- $password = randAlphaNum $passwordLength }} + {{- end }} + {{- end -}} {{- end -}} {{- if not .skipB64enc }} {{- $password = $password | b64enc }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/_helpers.tpl b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/_helpers.tpl index 0912b989..2f0bda6a 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/_helpers.tpl +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/_helpers.tpl @@ -222,34 +222,13 @@ Get the password key to be retrieved from Redis® secret. {{- end -}} {{- end -}} - -{{/* -Returns the available value for certain key in an existing secret (if it exists), -otherwise it generates a random value. -*/}} -{{- define "getValueFromSecret" }} - {{- $len := (default 16 .Length) | int -}} - {{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} - {{- if $obj }} - {{- index $obj .Key | b64dec -}} - {{- else -}} - {{- randAlphaNum $len -}} - {{- end -}} -{{- end }} - {{/* Return Redis® password */}} {{- define "redis.password" -}} -{{- if or .Values.auth.enabled .Values.global.redis.password }} - {{- if not (empty .Values.global.redis.password) }} - {{- .Values.global.redis.password -}} - {{- else if not (empty .Values.auth.password) -}} - {{- .Values.auth.password -}} - {{- else -}} - {{- include "getValueFromSecret" (dict "Namespace" (include "common.names.namespace" .) "Name" (include "redis.secretName" .) "Length" 10 "Key" (include "redis.secretPasswordKey" .)) -}} - {{- end -}} -{{- end -}} +{{- if or .Values.auth.enabled .Values.global.redis.password -}} + {{- include "common.secrets.passwords.manage" (dict "secret" (include "redis.secretName" .) "key" (include "redis.secretPasswordKey" .) "providedValues" (list "global.redis.password" "auth.password") "length" 10 "skipB64enc" true "skipQuote" true "context" $) -}} +{{- end }} {{- end }} {{/* Check if there are rolling tags in the images */}} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/master/application.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/master/application.yaml index b17a2401..84f83021 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/master/application.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/master/application.yaml @@ -58,6 +58,9 @@ spec: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $ ) | nindent 8 }} {{- end }} spec: + {{- if .Values.master.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.master.extraPodSpec "context" $) | nindent 6 }} + {{- end }} {{- include "redis.imagePullSecrets" . | nindent 6 }} {{- if .Values.master.hostAliases }} hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.master.hostAliases "context" $) | nindent 8 }} @@ -393,6 +396,10 @@ spec: {{- else }} securityContext: {{- .Values.volumePermissions.containerSecurityContext | toYaml | nindent 12 }} {{- end }} + {{- if .Values.volumePermissions.extraEnvVars }} + env: + {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.extraEnvVars "context" $) | nindent 12 }} + {{- end }} {{- if .Values.volumePermissions.resources }} resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/replicas/application.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/replicas/application.yaml index fe4f3346..bba4c7e9 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/replicas/application.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/replicas/application.yaml @@ -56,6 +56,9 @@ spec: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $ ) | nindent 8 }} {{- end }} spec: + {{- if .Values.replica.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.replica.extraPodSpec "context" $) | nindent 6 }} + {{- end }} {{- include "redis.imagePullSecrets" . | nindent 6 }} {{- if .Values.replica.hostAliases }} hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.replica.hostAliases "context" $) | nindent 8 }} @@ -413,6 +416,10 @@ spec: {{- else }} securityContext: {{- .Values.volumePermissions.containerSecurityContext | toYaml | nindent 12 }} {{- end }} + {{- if .Values.volumePermissions.extraEnvVars }} + env: + {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.extraEnvVars "context" $) | nindent 12 }} + {{- end }} {{- if .Values.volumePermissions.resources }} resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/scripts-configmap.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/scripts-configmap.yaml index cf85307d..acb04424 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/scripts-configmap.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/scripts-configmap.yaml @@ -232,7 +232,9 @@ data: {{- end }} {{- if .Values.replica.preExecCmds }} - {{- .Values.replica.preExecCmds | nindent 4 }} + {{- range $command := .Values.replica.preExecCmds }} + {{- $command | nindent 4 }} + {{- end }} {{- end }} {{- if .Values.replica.command }} @@ -440,7 +442,9 @@ data: {{- end }} {{- end }} {{- if .Values.sentinel.preExecCmds }} - {{ .Values.sentinel.preExecCmds | nindent 4 }} + {{- range $command := .Values.sentinel.preExecCmds }} + {{- $command | nindent 4 }} + {{- end }} {{- end }} mv /opt/bitnami/redis-sentinel/etc/prepare-sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf exec redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf {{- if .Values.tls.enabled }} "${ARGS[@]}" {{- end }} --sentinel @@ -646,7 +650,9 @@ data: {{- end }} {{- end }} {{- if .Values.master.preExecCmds }} - {{ .Values.master.preExecCmds | nindent 4 }} + {{- range $command := .Values.master.preExecCmds }} + {{- $command | nindent 4 }} + {{- end }} {{- end }} {{- if .Values.master.command }} exec {{ .Values.master.command }} "${ARGS[@]}" @@ -754,8 +760,9 @@ data: {{- end }} {{- end }} {{- if .Values.replica.preExecCmds }} - {{ .Values.replica.preExecCmds | nindent 4 }} - {{- end }} + {{- range $command := .Values.replica.preExecCmds }} + {{- $command | nindent 4 }} + {{- end }} {{- end }} {{- if .Values.replica.command }} exec {{ .Values.replica.command }} "${ARGS[@]}" {{- else }} @@ -783,6 +790,7 @@ data: done echo "new master elected, updating label(s)..." kubectl label pod --field-selector metadata.name="$(< "/etc/shared/current")" isMaster="true" --overwrite + kubectl label pod --field-selector metadata.name="$(< "/etc/shared/current")" app.kubernetes.io/role- if [ -f /etc/shared/previous ]; then kubectl label pod --field-selector metadata.name="$(< "/etc/shared/previous")" isMaster="false" --overwrite fi diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/sentinel/statefulset.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/sentinel/statefulset.yaml index 59cc2925..45c7451e 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/sentinel/statefulset.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/sentinel/statefulset.yaml @@ -37,6 +37,9 @@ spec: metadata: labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} app.kubernetes.io/component: node + {{- if .Values.sentinel.masterService.enabled }} + app.kubernetes.io/role: slave + {{- end }} {{- if and .Values.metrics.enabled .Values.metrics.podLabels }} {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podLabels "context" $ ) | nindent 8 }} {{- end }} @@ -54,6 +57,9 @@ spec: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $ ) | nindent 8 }} {{- end }} spec: + {{- if .Values.sentinel.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.sentinel.extraPodSpec "context" $) | nindent 6 }} + {{- end }} {{- include "redis.imagePullSecrets" . | nindent 6 }} automountServiceAccountToken: {{ .Values.replica.automountServiceAccountToken }} {{- if .Values.replica.hostAliases }} @@ -636,6 +642,10 @@ spec: {{- else }} securityContext: {{- .Values.volumePermissions.containerSecurityContext | toYaml | nindent 12 }} {{- end }} + {{- if .Values.volumePermissions.extraEnvVars }} + env: + {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.extraEnvVars "context" $) | nindent 12 }} + {{- end }} {{- if .Values.volumePermissions.resources }} resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} @@ -802,7 +812,9 @@ spec: {{- end }} {{- include "common.storage.class" (dict "persistence" .Values.replica.persistence "global" .Values.global) | nindent 8 }} {{- if .Values.sentinel.persistence.enabled }} - - metadata: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: name: sentinel-data {{- $claimLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.sentinel.persistence.labels .Values.commonLabels ) "context" . ) }} labels: {{- include "common.labels.matchLabels" ( dict "customLabels" $claimLabels "context" $ ) | nindent 10 }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/servicemonitor.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/servicemonitor.yaml index e5ffd903..1a9f6eea 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/templates/servicemonitor.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/templates/servicemonitor.yaml @@ -45,7 +45,7 @@ spec: {{- if .honorLabels }} honorLabels: {{ .honorLabels }} {{- end }} - {{- with concat .Values.metrics.serviceMonitor.relabelings .Values.metrics.serviceMonitor.relabellings }} + {{- with concat $.Values.metrics.serviceMonitor.relabelings $.Values.metrics.serviceMonitor.relabellings }} relabelings: {{- toYaml . | nindent 6 }} {{- end }} {{- if .metricRelabelings }} diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/values.schema.json b/packages/system/dashboard/charts/kubeapps/charts/redis/values.schema.json index e9feba6a..f872c957 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/values.schema.json +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/values.schema.json @@ -1,163 +1,3275 @@ { - "$schema": "http://json-schema.org/schema#", - "type": "object", - "properties": { - "architecture": { - "type": "string", - "title": "Redis architecture", - "form": true, - "description": "Allowed values: `standalone` or `replication`", - "enum": ["standalone", "replication"] - }, - "auth": { - "type": "object", - "title": "Authentication configuration", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Use password authentication" - }, - "password": { - "type": "string", - "title": "Redis password", - "form": true, - "description": "Defaults to a random 10-character alphanumeric string if not set", - "hidden": { - "value": false, - "path": "auth/enabled" - } - } - } - }, - "master": { - "type": "object", - "title": "Master replicas settings", - "form": true, - "properties": { - "kind": { - "type": "string", - "title": "Workload Kind", - "form": true, - "description": "Allowed values: `Deployment`, `StatefulSet` or `DaemonSet`", - "enum": ["Deployment", "StatefulSet", "DaemonSet"] - }, - "persistence": { - "type": "object", - "title": "Persistence for master replicas", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable persistence", - "description": "Enable persistence using Persistent Volume Claims" - }, - "size": { - "type": "string", - "title": "Persistent Volume Size", - "form": true, - "render": "slider", - "sliderMin": 1, - "sliderMax": 100, - "sliderUnit": "Gi", - "hidden": { - "value": false, - "path": "master/persistence/enabled" - } + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "global": { + "type": "object", + "properties": { + "imageRegistry": { + "type": "string", + "description": "Global Docker image registry", + "default": "" + }, + "imagePullSecrets": { + "type": "array", + "description": "Global Docker registry secret names as an array", + "default": [], + "items": {} + }, + "defaultStorageClass": { + "type": "string", + "description": "Global default StorageClass for Persistent Volume(s)", + "default": "" + }, + "storageClass": { + "type": "string", + "description": "DEPRECATED: use global.defaultStorageClass instead", + "default": "" + }, + "redis": { + "type": "object", + "properties": { + "password": { + "type": "string", + "description": "Global Redis® password (overrides `auth.password`)", + "default": "" + } + } + }, + "compatibility": { + "type": "object", + "properties": { + "openshift": { + "type": "object", + "properties": { + "adaptSecurityContext": { + "type": "string", + "description": "Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation)", + "default": "auto" + } + } + } + } + } } - } - } - } - }, - "replica": { - "type": "object", - "title": "Redis replicas settings", - "form": true, - "hidden": { - "value": "standalone", - "path": "architecture" - }, - "properties": { - "kind": { - "type": "string", - "title": "Workload Kind", - "form": true, - "description": "Allowed values: `DaemonSet` or `StatefulSet`", - "enum": ["DaemonSet", "StatefulSet"] }, - "replicaCount": { - "type": "integer", - "form": true, - "title": "Number of Redis replicas" + "kubeVersion": { + "type": "string", + "description": "Override Kubernetes version", + "default": "" }, - "persistence": { - "type": "object", - "title": "Persistence for Redis replicas", - "form": true, - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable persistence", - "description": "Enable persistence using Persistent Volume Claims" - }, - "size": { - "type": "string", - "title": "Persistent Volume Size", - "form": true, - "render": "slider", - "sliderMin": 1, - "sliderMax": 100, - "sliderUnit": "Gi", - "hidden": { - "value": false, - "path": "replica/persistence/enabled" - } + "nameOverride": { + "type": "string", + "description": "String to partially override common.names.fullname", + "default": "" + }, + "fullnameOverride": { + "type": "string", + "description": "String to fully override common.names.fullname", + "default": "" + }, + "namespaceOverride": { + "type": "string", + "description": "String to fully override common.names.namespace", + "default": "" + }, + "commonLabels": { + "type": "object", + "description": "Labels to add to all deployed objects", + "default": {} + }, + "commonAnnotations": { + "type": "object", + "description": "Annotations to add to all deployed objects", + "default": {} + }, + "secretAnnotations": { + "type": "object", + "description": "Annotations to add to secret", + "default": {} + }, + "clusterDomain": { + "type": "string", + "description": "Kubernetes cluster domain name", + "default": "cluster.local" + }, + "extraDeploy": { + "type": "array", + "description": "Array of extra objects to deploy with the release", + "default": [], + "items": {} + }, + "useHostnames": { + "type": "boolean", + "description": "Use hostnames internally when announcing replication. If false, the hostname will be resolved to an IP address", + "default": true + }, + "nameResolutionThreshold": { + "type": "number", + "description": "Failure threshold for internal hostnames resolution", + "default": 5 + }, + "nameResolutionTimeout": { + "type": "number", + "description": "Timeout seconds between probes for internal hostnames resolution", + "default": 5 + }, + "diagnosticMode": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable diagnostic mode (all probes will be disabled and the command will be overridden)", + "default": false + }, + "command": { + "type": "array", + "description": "Command to override all containers in the deployment", + "default": [ + "sleep" + ], + "items": { + "type": "string" + } + }, + "args": { + "type": "array", + "description": "Args to override all containers in the deployment", + "default": [ + "infinity" + ], + "items": { + "type": "string" + } + } } - } - } - } - }, - "volumePermissions": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "form": true, - "title": "Enable Init Containers", - "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" - } - } - }, - "metrics": { - "type": "object", - "form": true, - "title": "Prometheus metrics details", - "properties": { - "enabled": { - "type": "boolean", - "title": "Create Prometheus metrics exporter", - "description": "Create a side-car container to expose Prometheus metrics", - "form": true }, - "serviceMonitor": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "title": "Create Prometheus Operator ServiceMonitor", - "description": "Create a ServiceMonitor to track metrics using Prometheus Operator", - "form": true, - "hidden": { - "value": false, - "path": "metrics/enabled" - } + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "Redis® image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "Redis® image repository", + "default": "REPOSITORY_NAME/redis" + }, + "digest": { + "type": "string", + "description": "Redis® image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "Redis® image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "Redis® image pull secrets", + "default": [], + "items": {} + }, + "debug": { + "type": "boolean", + "description": "Enable image debug mode", + "default": false + } + } + }, + "architecture": { + "type": "string", + "description": "Redis® architecture. Allowed values: `standalone` or `replication`", + "default": "replication" + }, + "auth": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable password authentication", + "default": true + }, + "sentinel": { + "type": "boolean", + "description": "Enable password authentication on sentinels too", + "default": true + }, + "password": { + "type": "string", + "description": "Redis® password", + "default": "" + }, + "existingSecret": { + "type": "string", + "description": "The name of an existing secret with Redis® credentials", + "default": "" + }, + "existingSecretPasswordKey": { + "type": "string", + "description": "Password key to be retrieved from existing secret", + "default": "" + }, + "usePasswordFiles": { + "type": "boolean", + "description": "Mount credentials as files instead of using an environment variable", + "default": false + }, + "usePasswordFileFromSecret": { + "type": "boolean", + "description": "Mount password file from secret", + "default": true + } + } + }, + "commonConfiguration": { + "type": "string", + "description": "Common configuration to be added into the ConfigMap", + "default": "\"\"" + }, + "existingConfigmap": { + "type": "string", + "description": "The name of an existing ConfigMap with your custom configuration for Redis® nodes", + "default": "" + }, + "master": { + "type": "object", + "properties": { + "count": { + "type": "number", + "description": "Number of Redis® master instances to deploy (experimental, requires additional configuration)", + "default": 1 + }, + "revisionHistoryLimit": { + "type": "number", + "description": "The number of old history to retain to allow rollback", + "default": 10 + }, + "configuration": { + "type": "string", + "description": "Configuration for Redis® master nodes", + "default": "" + }, + "disableCommands": { + "type": "array", + "description": "Array with Redis® commands to disable on master nodes", + "default": [ + "FLUSHDB", + "FLUSHALL" + ], + "items": { + "type": "string" + } + }, + "command": { + "type": "array", + "description": "Override default container command (useful when using custom images)", + "default": [], + "items": {} + }, + "args": { + "type": "array", + "description": "Override default container args (useful when using custom images)", + "default": [], + "items": {} + }, + "enableServiceLinks": { + "type": "boolean", + "description": "Whether information about services should be injected into pod's environment variable", + "default": true + }, + "preExecCmds": { + "type": "array", + "description": "Additional commands to run prior to starting Redis® master", + "default": [], + "items": {} + }, + "extraFlags": { + "type": "array", + "description": "Array with additional command line flags for Redis® master", + "default": [], + "items": {} + }, + "extraEnvVars": { + "type": "array", + "description": "Array with extra environment variables to add to Redis® master nodes", + "default": [], + "items": {} + }, + "extraEnvVarsCM": { + "type": "string", + "description": "Name of existing ConfigMap containing extra env vars for Redis® master nodes", + "default": "" + }, + "extraEnvVarsSecret": { + "type": "string", + "description": "Name of existing Secret containing extra env vars for Redis® master nodes", + "default": "" + }, + "containerPorts": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Container port to open on Redis® master nodes", + "default": 6379 + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable startupProbe on Redis® master nodes", + "default": false + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for startupProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for startupProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for startupProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for startupProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for startupProbe", + "default": 1 + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable livenessProbe on Redis® master nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for livenessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for livenessProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for livenessProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for livenessProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for livenessProbe", + "default": 1 + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable readinessProbe on Redis® master nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for readinessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for readinessProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for readinessProbe", + "default": 1 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for readinessProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for readinessProbe", + "default": 1 + } + } + }, + "customStartupProbe": { + "type": "object", + "description": "Custom startupProbe that overrides the default one", + "default": {} + }, + "customLivenessProbe": { + "type": "object", + "description": "Custom livenessProbe that overrides the default one", + "default": {} + }, + "customReadinessProbe": { + "type": "object", + "description": "Custom readinessProbe that overrides the default one", + "default": {} + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if master.resources is set (master.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + }, + "podSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® master pods' Security Context", + "default": true + }, + "fsGroupChangePolicy": { + "type": "string", + "description": "Set filesystem group change policy", + "default": "Always" + }, + "sysctls": { + "type": "array", + "description": "Set kernel settings using the sysctl interface", + "default": [], + "items": {} + }, + "supplementalGroups": { + "type": "array", + "description": "Set filesystem extra groups", + "default": [], + "items": {} + }, + "fsGroup": { + "type": "number", + "description": "Set Redis® master pod's Security Context fsGroup", + "default": 1001 + } + } + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® master containers' Security Context", + "default": true + }, + "runAsUser": { + "type": "number", + "description": "Set Redis® master containers' Security Context runAsUser", + "default": 1001 + }, + "runAsGroup": { + "type": "number", + "description": "Set Redis® master containers' Security Context runAsGroup", + "default": 1001 + }, + "runAsNonRoot": { + "type": "boolean", + "description": "Set Redis® master containers' Security Context runAsNonRoot", + "default": true + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "Is it possible to escalate Redis® pod(s) privileges", + "default": false + }, + "readOnlyRootFilesystem": { + "type": "boolean", + "description": "Set container's Security Context read-only root filesystem", + "default": true + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Set Redis® master containers' Security Context seccompProfile", + "default": "RuntimeDefault" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "Set Redis® master containers' Security Context capabilities to drop", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + } + } + }, + "kind": { + "type": "string", + "description": "Use either Deployment, StatefulSet (default) or DaemonSet", + "default": "StatefulSet" + }, + "schedulerName": { + "type": "string", + "description": "Alternate scheduler for Redis® master pods", + "default": "" + }, + "updateStrategy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Redis® master statefulset strategy type", + "default": "RollingUpdate" + } + } + }, + "minReadySeconds": { + "type": "number", + "description": "How many seconds a pod needs to be ready before killing the next, during update", + "default": 0 + }, + "priorityClassName": { + "type": "string", + "description": "Redis® master pods' priorityClassName", + "default": "" + }, + "automountServiceAccountToken": { + "type": "boolean", + "description": "Mount Service Account token in pod", + "default": false + }, + "hostAliases": { + "type": "array", + "description": "Redis® master pods host aliases", + "default": [], + "items": {} + }, + "podLabels": { + "type": "object", + "description": "Extra labels for Redis® master pods", + "default": {} + }, + "podAnnotations": { + "type": "object", + "description": "Annotations for Redis® master pods", + "default": {} + }, + "shareProcessNamespace": { + "type": "boolean", + "description": "Share a single process namespace between all of the containers in Redis® master pods", + "default": false + }, + "podAffinityPreset": { + "type": "string", + "description": "Pod affinity preset. Ignored if `master.affinity` is set. Allowed values: `soft` or `hard`", + "default": "" + }, + "podAntiAffinityPreset": { + "type": "string", + "description": "Pod anti-affinity preset. Ignored if `master.affinity` is set. Allowed values: `soft` or `hard`", + "default": "soft" + }, + "nodeAffinityPreset": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Node affinity preset type. Ignored if `master.affinity` is set. Allowed values: `soft` or `hard`", + "default": "" + }, + "key": { + "type": "string", + "description": "Node label key to match. Ignored if `master.affinity` is set", + "default": "" + }, + "values": { + "type": "array", + "description": "Node label values to match. Ignored if `master.affinity` is set", + "default": [], + "items": {} + } + } + }, + "affinity": { + "type": "object", + "description": "Affinity for Redis® master pods assignment", + "default": {} + }, + "nodeSelector": { + "type": "object", + "description": "Node labels for Redis® master pods assignment", + "default": {} + }, + "tolerations": { + "type": "array", + "description": "Tolerations for Redis® master pods assignment", + "default": [], + "items": {} + }, + "topologySpreadConstraints": { + "type": "array", + "description": "Spread Constraints for Redis® master pod assignment", + "default": [], + "items": {} + }, + "dnsPolicy": { + "type": "string", + "description": "DNS Policy for Redis® master pod", + "default": "" + }, + "dnsConfig": { + "type": "object", + "description": "DNS Configuration for Redis® master pod", + "default": {} + }, + "lifecycleHooks": { + "type": "object", + "description": "for the Redis® master container(s) to automate configuration before or after startup", + "default": {} + }, + "extraVolumes": { + "type": "array", + "description": "Optionally specify extra list of additional volumes for the Redis® master pod(s)", + "default": [], + "items": {} + }, + "extraVolumeMounts": { + "type": "array", + "description": "Optionally specify extra list of additional volumeMounts for the Redis® master container(s)", + "default": [], + "items": {} + }, + "sidecars": { + "type": "array", + "description": "Add additional sidecar containers to the Redis® master pod(s)", + "default": [], + "items": {} + }, + "initContainers": { + "type": "array", + "description": "Add additional init containers to the Redis® master pod(s)", + "default": [], + "items": {} + }, + "persistence": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable persistence on Redis® master nodes using Persistent Volume Claims", + "default": true + }, + "medium": { + "type": "string", + "description": "Provide a medium for `emptyDir` volumes.", + "default": "" + }, + "sizeLimit": { + "type": "string", + "description": "Set this to enable a size limit for `emptyDir` volumes.", + "default": "" + }, + "path": { + "type": "string", + "description": "The path the volume will be mounted at on Redis® master containers", + "default": "/data" + }, + "subPath": { + "type": "string", + "description": "The subdirectory of the volume to mount on Redis® master containers", + "default": "" + }, + "subPathExpr": { + "type": "string", + "description": "Used to construct the subPath subdirectory of the volume to mount on Redis® master containers", + "default": "" + }, + "storageClass": { + "type": "string", + "description": "Persistent Volume storage class", + "default": "" + }, + "accessModes": { + "type": "array", + "description": "Persistent Volume access modes", + "default": [ + "ReadWriteOnce" + ], + "items": { + "type": "string" + } + }, + "size": { + "type": "string", + "description": "Persistent Volume size", + "default": "8Gi" + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the PVC", + "default": {} + }, + "labels": { + "type": "object", + "description": "Additional custom labels for the PVC", + "default": {} + }, + "selector": { + "type": "object", + "description": "Additional labels to match for the PVC", + "default": {} + }, + "dataSource": { + "type": "object", + "description": "Custom PVC data source", + "default": {} + }, + "existingClaim": { + "type": "string", + "description": "Use a existing PVC which must be created manually before bound", + "default": "" + } + } + }, + "persistentVolumeClaimRetentionPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Controls if and how PVCs are deleted during the lifecycle of a StatefulSet", + "default": false + }, + "whenScaled": { + "type": "string", + "description": "Volume retention behavior when the replica count of the StatefulSet is reduced", + "default": "Retain" + }, + "whenDeleted": { + "type": "string", + "description": "Volume retention behavior that applies when the StatefulSet is deleted", + "default": "Retain" + } + } + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Redis® master service type", + "default": "ClusterIP" + }, + "portNames": { + "type": "object", + "properties": { + "redis": { + "type": "string", + "description": "Redis® master service port name", + "default": "tcp-redis" + } + } + }, + "ports": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Redis® master service port", + "default": 6379 + } + } + }, + "nodePorts": { + "type": "object", + "properties": { + "redis": { + "type": "string", + "description": "Node port for Redis® master", + "default": "" + } + } + }, + "externalTrafficPolicy": { + "type": "string", + "description": "Redis® master service external traffic policy", + "default": "Cluster" + }, + "extraPorts": { + "type": "array", + "description": "Extra ports to expose (normally used with the `sidecar` value)", + "default": [], + "items": {} + }, + "internalTrafficPolicy": { + "type": "string", + "description": "Redis® master service internal traffic policy (requires Kubernetes v1.22 or greater to be usable)", + "default": "Cluster" + }, + "clusterIP": { + "type": "string", + "description": "Redis® master service Cluster IP", + "default": "" + }, + "loadBalancerIP": { + "type": "string", + "description": "Redis® master service Load Balancer IP", + "default": "" + }, + "loadBalancerClass": { + "type": "string", + "description": "master service Load Balancer class if service type is `LoadBalancer` (optional, cloud specific)", + "default": "" + }, + "loadBalancerSourceRanges": { + "type": "array", + "description": "Redis® master service Load Balancer sources", + "default": [], + "items": {} + }, + "externalIPs": { + "type": "array", + "description": "Redis® master service External IPs", + "default": [], + "items": {} + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® master service", + "default": {} + }, + "sessionAffinity": { + "type": "string", + "description": "Session Affinity for Kubernetes service, can be \"None\" or \"ClientIP\"", + "default": "None" + }, + "sessionAffinityConfig": { + "type": "object", + "description": "Additional settings for the sessionAffinity", + "default": {} + } + } + }, + "terminationGracePeriodSeconds": { + "type": "number", + "description": "Integer setting the termination grace period for the redis-master pods", + "default": 30 + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether a ServiceAccount should be created", + "default": true + }, + "name": { + "type": "string", + "description": "The name of the ServiceAccount to use.", + "default": "" + }, + "automountServiceAccountToken": { + "type": "boolean", + "description": "Whether to auto mount the service account token", + "default": false + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the ServiceAccount", + "default": {} + } + } + }, + "pdb": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Enable/disable a Pod Disruption Budget creation", + "default": true + } + } + } + } + }, + "replica": { + "type": "object", + "properties": { + "kind": { + "type": "string", + "description": "Use either DaemonSet or StatefulSet (default)", + "default": "StatefulSet" + }, + "replicaCount": { + "type": "number", + "description": "Number of Redis® replicas to deploy", + "default": 3 + }, + "revisionHistoryLimit": { + "type": "number", + "description": "The number of old history to retain to allow rollback", + "default": 10 + }, + "configuration": { + "type": "string", + "description": "Configuration for Redis® replicas nodes", + "default": "" + }, + "disableCommands": { + "type": "array", + "description": "Array with Redis® commands to disable on replicas nodes", + "default": [ + "FLUSHDB", + "FLUSHALL" + ], + "items": { + "type": "string" + } + }, + "command": { + "type": "array", + "description": "Override default container command (useful when using custom images)", + "default": [], + "items": {} + }, + "args": { + "type": "array", + "description": "Override default container args (useful when using custom images)", + "default": [], + "items": {} + }, + "enableServiceLinks": { + "type": "boolean", + "description": "Whether information about services should be injected into pod's environment variable", + "default": true + }, + "preExecCmds": { + "type": "array", + "description": "Additional commands to run prior to starting Redis® replicas", + "default": [], + "items": {} + }, + "extraFlags": { + "type": "array", + "description": "Array with additional command line flags for Redis® replicas", + "default": [], + "items": {} + }, + "extraEnvVars": { + "type": "array", + "description": "Array with extra environment variables to add to Redis® replicas nodes", + "default": [], + "items": {} + }, + "extraEnvVarsCM": { + "type": "string", + "description": "Name of existing ConfigMap containing extra env vars for Redis® replicas nodes", + "default": "" + }, + "extraEnvVarsSecret": { + "type": "string", + "description": "Name of existing Secret containing extra env vars for Redis® replicas nodes", + "default": "" + }, + "externalMaster": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Use external master for bootstrapping", + "default": false + }, + "host": { + "type": "string", + "description": "External master host to bootstrap from", + "default": "" + }, + "port": { + "type": "number", + "description": "Port for Redis service external master host", + "default": 6379 + } + } + }, + "containerPorts": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Container port to open on Redis® replicas nodes", + "default": 6379 + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable startupProbe on Redis® replicas nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for startupProbe", + "default": 10 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for startupProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for startupProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for startupProbe", + "default": 22 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for startupProbe", + "default": 1 + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable livenessProbe on Redis® replicas nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for livenessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for livenessProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for livenessProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for livenessProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for livenessProbe", + "default": 1 + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable readinessProbe on Redis® replicas nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for readinessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for readinessProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for readinessProbe", + "default": 1 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for readinessProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for readinessProbe", + "default": 1 + } + } + }, + "customStartupProbe": { + "type": "object", + "description": "Custom startupProbe that overrides the default one", + "default": {} + }, + "customLivenessProbe": { + "type": "object", + "description": "Custom livenessProbe that overrides the default one", + "default": {} + }, + "customReadinessProbe": { + "type": "object", + "description": "Custom readinessProbe that overrides the default one", + "default": {} + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if replica.resources is set (replica.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + }, + "podSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® replicas pods' Security Context", + "default": true + }, + "fsGroupChangePolicy": { + "type": "string", + "description": "Set filesystem group change policy", + "default": "Always" + }, + "sysctls": { + "type": "array", + "description": "Set kernel settings using the sysctl interface", + "default": [], + "items": {} + }, + "supplementalGroups": { + "type": "array", + "description": "Set filesystem extra groups", + "default": [], + "items": {} + }, + "fsGroup": { + "type": "number", + "description": "Set Redis® replicas pod's Security Context fsGroup", + "default": 1001 + } + } + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® replicas containers' Security Context", + "default": true + }, + "runAsUser": { + "type": "number", + "description": "Set Redis® replicas containers' Security Context runAsUser", + "default": 1001 + }, + "runAsGroup": { + "type": "number", + "description": "Set Redis® replicas containers' Security Context runAsGroup", + "default": 1001 + }, + "runAsNonRoot": { + "type": "boolean", + "description": "Set Redis® replicas containers' Security Context runAsNonRoot", + "default": true + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "Set Redis® replicas pod's Security Context allowPrivilegeEscalation", + "default": false + }, + "readOnlyRootFilesystem": { + "type": "boolean", + "description": "Set container's Security Context read-only root filesystem", + "default": true + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Set Redis® replicas containers' Security Context seccompProfile", + "default": "RuntimeDefault" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "Set Redis® replicas containers' Security Context capabilities to drop", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + } + } + }, + "schedulerName": { + "type": "string", + "description": "Alternate scheduler for Redis® replicas pods", + "default": "" + }, + "updateStrategy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Redis® replicas statefulset strategy type", + "default": "RollingUpdate" + } + } + }, + "minReadySeconds": { + "type": "number", + "description": "How many seconds a pod needs to be ready before killing the next, during update", + "default": 0 + }, + "priorityClassName": { + "type": "string", + "description": "Redis® replicas pods' priorityClassName", + "default": "" + }, + "podManagementPolicy": { + "type": "string", + "description": "podManagementPolicy to manage scaling operation of %%MAIN_CONTAINER_NAME%% pods", + "default": "" + }, + "automountServiceAccountToken": { + "type": "boolean", + "description": "Mount Service Account token in pod", + "default": false + }, + "hostAliases": { + "type": "array", + "description": "Redis® replicas pods host aliases", + "default": [], + "items": {} + }, + "podLabels": { + "type": "object", + "description": "Extra labels for Redis® replicas pods", + "default": {} + }, + "podAnnotations": { + "type": "object", + "description": "Annotations for Redis® replicas pods", + "default": {} + }, + "shareProcessNamespace": { + "type": "boolean", + "description": "Share a single process namespace between all of the containers in Redis® replicas pods", + "default": false + }, + "podAffinityPreset": { + "type": "string", + "description": "Pod affinity preset. Ignored if `replica.affinity` is set. Allowed values: `soft` or `hard`", + "default": "" + }, + "podAntiAffinityPreset": { + "type": "string", + "description": "Pod anti-affinity preset. Ignored if `replica.affinity` is set. Allowed values: `soft` or `hard`", + "default": "soft" + }, + "nodeAffinityPreset": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Node affinity preset type. Ignored if `replica.affinity` is set. Allowed values: `soft` or `hard`", + "default": "" + }, + "key": { + "type": "string", + "description": "Node label key to match. Ignored if `replica.affinity` is set", + "default": "" + }, + "values": { + "type": "array", + "description": "Node label values to match. Ignored if `replica.affinity` is set", + "default": [], + "items": {} + } + } + }, + "affinity": { + "type": "object", + "description": "Affinity for Redis® replicas pods assignment", + "default": {} + }, + "nodeSelector": { + "type": "object", + "description": "Node labels for Redis® replicas pods assignment", + "default": {} + }, + "tolerations": { + "type": "array", + "description": "Tolerations for Redis® replicas pods assignment", + "default": [], + "items": {} + }, + "topologySpreadConstraints": { + "type": "array", + "description": "Spread Constraints for Redis® replicas pod assignment", + "default": [], + "items": {} + }, + "dnsPolicy": { + "type": "string", + "description": "DNS Policy for Redis® replica pods", + "default": "" + }, + "dnsConfig": { + "type": "object", + "description": "DNS Configuration for Redis® replica pods", + "default": {} + }, + "lifecycleHooks": { + "type": "object", + "description": "for the Redis® replica container(s) to automate configuration before or after startup", + "default": {} + }, + "extraVolumes": { + "type": "array", + "description": "Optionally specify extra list of additional volumes for the Redis® replicas pod(s)", + "default": [], + "items": {} + }, + "extraVolumeMounts": { + "type": "array", + "description": "Optionally specify extra list of additional volumeMounts for the Redis® replicas container(s)", + "default": [], + "items": {} + }, + "sidecars": { + "type": "array", + "description": "Add additional sidecar containers to the Redis® replicas pod(s)", + "default": [], + "items": {} + }, + "initContainers": { + "type": "array", + "description": "Add additional init containers to the Redis® replicas pod(s)", + "default": [], + "items": {} + }, + "persistence": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable persistence on Redis® replicas nodes using Persistent Volume Claims", + "default": true + }, + "medium": { + "type": "string", + "description": "Provide a medium for `emptyDir` volumes.", + "default": "" + }, + "sizeLimit": { + "type": "string", + "description": "Set this to enable a size limit for `emptyDir` volumes.", + "default": "" + }, + "path": { + "type": "string", + "description": "The path the volume will be mounted at on Redis® replicas containers", + "default": "/data" + }, + "subPath": { + "type": "string", + "description": "The subdirectory of the volume to mount on Redis® replicas containers", + "default": "" + }, + "subPathExpr": { + "type": "string", + "description": "Used to construct the subPath subdirectory of the volume to mount on Redis® replicas containers", + "default": "" + }, + "storageClass": { + "type": "string", + "description": "Persistent Volume storage class", + "default": "" + }, + "accessModes": { + "type": "array", + "description": "Persistent Volume access modes", + "default": [ + "ReadWriteOnce" + ], + "items": { + "type": "string" + } + }, + "size": { + "type": "string", + "description": "Persistent Volume size", + "default": "8Gi" + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the PVC", + "default": {} + }, + "labels": { + "type": "object", + "description": "Additional custom labels for the PVC", + "default": {} + }, + "selector": { + "type": "object", + "description": "Additional labels to match for the PVC", + "default": {} + }, + "dataSource": { + "type": "object", + "description": "Custom PVC data source", + "default": {} + }, + "existingClaim": { + "type": "string", + "description": "Use a existing PVC which must be created manually before bound", + "default": "" + } + } + }, + "persistentVolumeClaimRetentionPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Controls if and how PVCs are deleted during the lifecycle of a StatefulSet", + "default": false + }, + "whenScaled": { + "type": "string", + "description": "Volume retention behavior when the replica count of the StatefulSet is reduced", + "default": "Retain" + }, + "whenDeleted": { + "type": "string", + "description": "Volume retention behavior that applies when the StatefulSet is deleted", + "default": "Retain" + } + } + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Redis® replicas service type", + "default": "ClusterIP" + }, + "ports": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Redis® replicas service port", + "default": 6379 + } + } + }, + "nodePorts": { + "type": "object", + "properties": { + "redis": { + "type": "string", + "description": "Node port for Redis® replicas", + "default": "" + } + } + }, + "externalTrafficPolicy": { + "type": "string", + "description": "Redis® replicas service external traffic policy", + "default": "Cluster" + }, + "internalTrafficPolicy": { + "type": "string", + "description": "Redis® replicas service internal traffic policy (requires Kubernetes v1.22 or greater to be usable)", + "default": "Cluster" + }, + "extraPorts": { + "type": "array", + "description": "Extra ports to expose (normally used with the `sidecar` value)", + "default": [], + "items": {} + }, + "clusterIP": { + "type": "string", + "description": "Redis® replicas service Cluster IP", + "default": "" + }, + "loadBalancerIP": { + "type": "string", + "description": "Redis® replicas service Load Balancer IP", + "default": "" + }, + "loadBalancerClass": { + "type": "string", + "description": "replicas service Load Balancer class if service type is `LoadBalancer` (optional, cloud specific)", + "default": "" + }, + "loadBalancerSourceRanges": { + "type": "array", + "description": "Redis® replicas service Load Balancer sources", + "default": [], + "items": {} + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® replicas service", + "default": {} + }, + "sessionAffinity": { + "type": "string", + "description": "Session Affinity for Kubernetes service, can be \"None\" or \"ClientIP\"", + "default": "None" + }, + "sessionAffinityConfig": { + "type": "object", + "description": "Additional settings for the sessionAffinity", + "default": {} + } + } + }, + "terminationGracePeriodSeconds": { + "type": "number", + "description": "Integer setting the termination grace period for the redis-replicas pods", + "default": 30 + }, + "autoscaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable replica autoscaling settings", + "default": false + }, + "minReplicas": { + "type": "number", + "description": "Minimum replicas for the pod autoscaling", + "default": 1 + }, + "maxReplicas": { + "type": "number", + "description": "Maximum replicas for the pod autoscaling", + "default": 11 + }, + "targetCPU": { + "type": "string", + "description": "Percentage of CPU to consider when autoscaling", + "default": "" + }, + "targetMemory": { + "type": "string", + "description": "Percentage of Memory to consider when autoscaling", + "default": "" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether a ServiceAccount should be created", + "default": true + }, + "name": { + "type": "string", + "description": "The name of the ServiceAccount to use.", + "default": "" + }, + "automountServiceAccountToken": { + "type": "boolean", + "description": "Whether to auto mount the service account token", + "default": false + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the ServiceAccount", + "default": {} + } + } + }, + "pdb": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Enable/disable a Pod Disruption Budget creation", + "default": true + } + } + } + } + }, + "sentinel": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Use Redis® Sentinel on Redis® pods.", + "default": false + }, + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "Redis® Sentinel image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "Redis® Sentinel image repository", + "default": "REPOSITORY_NAME/redis-sentinel" + }, + "digest": { + "type": "string", + "description": "Redis® Sentinel image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "Redis® Sentinel image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "Redis® Sentinel image pull secrets", + "default": [], + "items": {} + }, + "debug": { + "type": "boolean", + "description": "Enable image debug mode", + "default": false + } + } + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® Sentinel resource", + "default": {} + }, + "masterSet": { + "type": "string", + "description": "Master set name", + "default": "mymaster" + }, + "quorum": { + "type": "number", + "description": "Sentinel Quorum", + "default": 2 + }, + "getMasterTimeout": { + "type": "number", + "description": "Amount of time to allow before get_sentinel_master_info() times out.", + "default": 90 + }, + "automateClusterRecovery": { + "type": "boolean", + "description": "Automate cluster recovery in cases where the last replica is not considered a good replica and Sentinel won't automatically failover to it.", + "default": false + }, + "redisShutdownWaitFailover": { + "type": "boolean", + "description": "Whether the Redis® master container waits for the failover at shutdown (in addition to the Redis® Sentinel container).", + "default": true + }, + "downAfterMilliseconds": { + "type": "number", + "description": "Timeout for detecting a Redis® node is down", + "default": 60000 + }, + "failoverTimeout": { + "type": "number", + "description": "Timeout for performing a election failover", + "default": 180000 + }, + "parallelSyncs": { + "type": "number", + "description": "Number of replicas that can be reconfigured in parallel to use the new master after a failover", + "default": 1 + }, + "configuration": { + "type": "string", + "description": "Configuration for Redis® Sentinel nodes", + "default": "" + }, + "command": { + "type": "array", + "description": "Override default container command (useful when using custom images)", + "default": [], + "items": {} + }, + "args": { + "type": "array", + "description": "Override default container args (useful when using custom images)", + "default": [], + "items": {} + }, + "enableServiceLinks": { + "type": "boolean", + "description": "Whether information about services should be injected into pod's environment variable", + "default": true + }, + "preExecCmds": { + "type": "array", + "description": "Additional commands to run prior to starting Redis® Sentinel", + "default": [], + "items": {} + }, + "extraEnvVars": { + "type": "array", + "description": "Array with extra environment variables to add to Redis® Sentinel nodes", + "default": [], + "items": {} + }, + "extraEnvVarsCM": { + "type": "string", + "description": "Name of existing ConfigMap containing extra env vars for Redis® Sentinel nodes", + "default": "" + }, + "extraEnvVarsSecret": { + "type": "string", + "description": "Name of existing Secret containing extra env vars for Redis® Sentinel nodes", + "default": "" + }, + "externalMaster": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Use external master for bootstrapping", + "default": false + }, + "host": { + "type": "string", + "description": "External master host to bootstrap from", + "default": "" + }, + "port": { + "type": "number", + "description": "Port for Redis service external master host", + "default": 6379 + } + } + }, + "containerPorts": { + "type": "object", + "properties": { + "sentinel": { + "type": "number", + "description": "Container port to open on Redis® Sentinel nodes", + "default": 26379 + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable startupProbe on Redis® Sentinel nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for startupProbe", + "default": 10 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for startupProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for startupProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for startupProbe", + "default": 22 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for startupProbe", + "default": 1 + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable livenessProbe on Redis® Sentinel nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for livenessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for livenessProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for livenessProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for livenessProbe", + "default": 6 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for livenessProbe", + "default": 1 + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable readinessProbe on Redis® Sentinel nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for readinessProbe", + "default": 20 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for readinessProbe", + "default": 5 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for readinessProbe", + "default": 1 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for readinessProbe", + "default": 6 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for readinessProbe", + "default": 1 + } + } + }, + "customStartupProbe": { + "type": "object", + "description": "Custom startupProbe that overrides the default one", + "default": {} + }, + "customLivenessProbe": { + "type": "object", + "description": "Custom livenessProbe that overrides the default one", + "default": {} + }, + "customReadinessProbe": { + "type": "object", + "description": "Custom readinessProbe that overrides the default one", + "default": {} + }, + "persistence": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable persistence on Redis® sentinel nodes using Persistent Volume Claims (Experimental)", + "default": false + }, + "storageClass": { + "type": "string", + "description": "Persistent Volume storage class", + "default": "" + }, + "accessModes": { + "type": "array", + "description": "Persistent Volume access modes", + "default": [ + "ReadWriteOnce" + ], + "items": { + "type": "string" + } + }, + "size": { + "type": "string", + "description": "Persistent Volume size", + "default": "100Mi" + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the PVC", + "default": {} + }, + "labels": { + "type": "object", + "description": "Additional custom labels for the PVC", + "default": {} + }, + "selector": { + "type": "object", + "description": "Additional labels to match for the PVC", + "default": {} + }, + "dataSource": { + "type": "object", + "description": "Custom PVC data source", + "default": {} + }, + "medium": { + "type": "string", + "description": "Provide a medium for `emptyDir` volumes.", + "default": "" + }, + "sizeLimit": { + "type": "string", + "description": "Set this to enable a size limit for `emptyDir` volumes.", + "default": "" + } + } + }, + "persistentVolumeClaimRetentionPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Controls if and how PVCs are deleted during the lifecycle of a StatefulSet", + "default": false + }, + "whenScaled": { + "type": "string", + "description": "Volume retention behavior when the replica count of the StatefulSet is reduced", + "default": "Retain" + }, + "whenDeleted": { + "type": "string", + "description": "Volume retention behavior that applies when the StatefulSet is deleted", + "default": "Retain" + } + } + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if sentinel.resources is set (sentinel.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® Sentinel containers' Security Context", + "default": true + }, + "runAsUser": { + "type": "number", + "description": "Set Redis® Sentinel containers' Security Context runAsUser", + "default": 1001 + }, + "runAsGroup": { + "type": "number", + "description": "Set Redis® Sentinel containers' Security Context runAsGroup", + "default": 1001 + }, + "runAsNonRoot": { + "type": "boolean", + "description": "Set Redis® Sentinel containers' Security Context runAsNonRoot", + "default": true + }, + "readOnlyRootFilesystem": { + "type": "boolean", + "description": "Set container's Security Context read-only root filesystem", + "default": true + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "Set Redis® Sentinel containers' Security Context allowPrivilegeEscalation", + "default": false + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Set Redis® Sentinel containers' Security Context seccompProfile", + "default": "RuntimeDefault" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "Set Redis® Sentinel containers' Security Context capabilities to drop", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + } + } + }, + "lifecycleHooks": { + "type": "object", + "description": "for the Redis® sentinel container(s) to automate configuration before or after startup", + "default": {} + }, + "extraVolumes": { + "type": "array", + "description": "Optionally specify extra list of additional volumes for the Redis® Sentinel", + "default": [], + "items": {} + }, + "extraVolumeMounts": { + "type": "array", + "description": "Optionally specify extra list of additional volumeMounts for the Redis® Sentinel container(s)", + "default": [], + "items": {} + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Redis® Sentinel service type", + "default": "ClusterIP" + }, + "ports": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Redis® service port for Redis®", + "default": 6379 + }, + "sentinel": { + "type": "number", + "description": "Redis® service port for Redis® Sentinel", + "default": 26379 + } + } + }, + "nodePorts": { + "type": "object", + "properties": { + "redis": { + "type": "string", + "description": "Node port for Redis®", + "default": "" + }, + "sentinel": { + "type": "string", + "description": "Node port for Sentinel", + "default": "" + } + } + }, + "externalTrafficPolicy": { + "type": "string", + "description": "Redis® Sentinel service external traffic policy", + "default": "Cluster" + }, + "extraPorts": { + "type": "array", + "description": "Extra ports to expose (normally used with the `sidecar` value)", + "default": [], + "items": {} + }, + "clusterIP": { + "type": "string", + "description": "Redis® Sentinel service Cluster IP", + "default": "" + }, + "createMaster": { + "type": "boolean", + "description": "Enable master service pointing to the current master (experimental)", + "default": false + }, + "loadBalancerIP": { + "type": "string", + "description": "Redis® Sentinel service Load Balancer IP", + "default": "" + }, + "loadBalancerClass": { + "type": "string", + "description": "sentinel service Load Balancer class if service type is `LoadBalancer` (optional, cloud specific)", + "default": "" + }, + "loadBalancerSourceRanges": { + "type": "array", + "description": "Redis® Sentinel service Load Balancer sources", + "default": [], + "items": {} + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® Sentinel service", + "default": {} + }, + "sessionAffinity": { + "type": "string", + "description": "Session Affinity for Kubernetes service, can be \"None\" or \"ClientIP\"", + "default": "None" + }, + "sessionAffinityConfig": { + "type": "object", + "description": "Additional settings for the sessionAffinity", + "default": {} + }, + "headless": { + "type": "object", + "properties": { + "annotations": { + "type": "object", + "description": "Annotations for the headless service.", + "default": {} + } + } + } + } + }, + "masterService": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable master service pointing to the current master (experimental)", + "default": false + }, + "type": { + "type": "string", + "description": "Redis® Sentinel master service type", + "default": "ClusterIP" + }, + "ports": { + "type": "object", + "properties": { + "redis": { + "type": "number", + "description": "Redis® service port for Redis®", + "default": 6379 + } + } + }, + "nodePorts": { + "type": "object", + "properties": { + "redis": { + "type": "string", + "description": "Node port for Redis®", + "default": "" + } + } + }, + "externalTrafficPolicy": { + "type": "string", + "description": "Redis® master service external traffic policy", + "default": "" + }, + "extraPorts": { + "type": "array", + "description": "Extra ports to expose (normally used with the `sidecar` value)", + "default": [], + "items": {} + }, + "clusterIP": { + "type": "string", + "description": "Redis® master service Cluster IP", + "default": "" + }, + "loadBalancerIP": { + "type": "string", + "description": "Redis® master service Load Balancer IP", + "default": "" + }, + "loadBalancerClass": { + "type": "string", + "description": "master service Load Balancer class if service type is `LoadBalancer` (optional, cloud specific)", + "default": "" + }, + "loadBalancerSourceRanges": { + "type": "array", + "description": "Redis® master service Load Balancer sources", + "default": [], + "items": {} + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® master service", + "default": {} + }, + "sessionAffinity": { + "type": "string", + "description": "Session Affinity for Kubernetes service, can be \"None\" or \"ClientIP\"", + "default": "None" + }, + "sessionAffinityConfig": { + "type": "object", + "description": "Additional settings for the sessionAffinity", + "default": {} + } + } + }, + "terminationGracePeriodSeconds": { + "type": "number", + "description": "Integer setting the termination grace period for the redis-node pods", + "default": 30 + } + } + }, + "serviceBindings": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Create secret for service binding (Experimental)", + "default": false + } + } + }, + "networkPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable creation of NetworkPolicy resources", + "default": true + }, + "allowExternal": { + "type": "boolean", + "description": "Don't require client label for connections", + "default": true + }, + "allowExternalEgress": { + "type": "boolean", + "description": "Allow the pod to access any range of port and all destinations.", + "default": true + }, + "extraIngress": { + "type": "array", + "description": "Add extra ingress rules to the NetworkPolicy", + "default": [], + "items": {} + }, + "extraEgress": { + "type": "array", + "description": "Add extra egress rules to the NetworkPolicy", + "default": [], + "items": {} + }, + "ingressNSMatchLabels": { + "type": "object", + "description": "Labels to match to allow traffic from other namespaces", + "default": {} + }, + "ingressNSPodMatchLabels": { + "type": "object", + "description": "Pod labels to match to allow traffic from other namespaces", + "default": {} + }, + "metrics": { + "type": "object", + "properties": { + "allowExternal": { + "type": "boolean", + "description": "Don't require client label for connections for metrics endpoint", + "default": true + }, + "ingressNSMatchLabels": { + "type": "object", + "description": "Labels to match to allow traffic from other namespaces to metrics endpoint", + "default": {} + }, + "ingressNSPodMatchLabels": { + "type": "object", + "description": "Pod labels to match to allow traffic from other namespaces to metrics endpoint", + "default": {} + } + } + } + } + }, + "podSecurityPolicy": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later", + "default": false + }, + "enabled": { + "type": "boolean", + "description": "Enable PodSecurityPolicy's RBAC rules", + "default": false + } + } + }, + "rbac": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether RBAC resources should be created", + "default": false + }, + "rules": { + "type": "array", + "description": "Custom RBAC rules to set", + "default": [], + "items": {} + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean", + "description": "Specifies whether a ServiceAccount should be created", + "default": true + }, + "name": { + "type": "string", + "description": "The name of the ServiceAccount to use.", + "default": "" + }, + "automountServiceAccountToken": { + "type": "boolean", + "description": "Whether to auto mount the service account token", + "default": false + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for the ServiceAccount", + "default": {} + } + } + }, + "pdb": { + "type": "object", + "description": "DEPRECATED Please use `master.pdb` and `replica.pdb` values instead", + "default": {} + }, + "tls": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable TLS traffic", + "default": false + }, + "authClients": { + "type": "boolean", + "description": "Require clients to authenticate", + "default": true + }, + "autoGenerated": { + "type": "boolean", + "description": "Enable autogenerated certificates", + "default": false + }, + "existingSecret": { + "type": "string", + "description": "The name of the existing secret that contains the TLS certificates", + "default": "" + }, + "certificatesSecret": { + "type": "string", + "description": "DEPRECATED. Use existingSecret instead.", + "default": "" + }, + "certFilename": { + "type": "string", + "description": "Certificate filename", + "default": "" + }, + "certKeyFilename": { + "type": "string", + "description": "Certificate Key filename", + "default": "" + }, + "certCAFilename": { + "type": "string", + "description": "CA Certificate filename", + "default": "" + }, + "dhParamsFilename": { + "type": "string", + "description": "File containing DH params (in order to support DH based ciphers)", + "default": "" + } + } + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Start a sidecar prometheus exporter to expose Redis® metrics", + "default": false + }, + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "Redis® Exporter image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "Redis® Exporter image repository", + "default": "REPOSITORY_NAME/redis-exporter" + }, + "digest": { + "type": "string", + "description": "Redis® Exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "Redis® Exporter image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "Redis® Exporter image pull secrets", + "default": [], + "items": {} + } + } + }, + "containerPorts": { + "type": "object", + "properties": { + "http": { + "type": "number", + "description": "Metrics HTTP container port", + "default": 9121 + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable startupProbe on Redis® replicas nodes", + "default": false + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for startupProbe", + "default": 10 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for startupProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for startupProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for startupProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for startupProbe", + "default": 1 + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable livenessProbe on Redis® replicas nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for livenessProbe", + "default": 10 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for livenessProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for livenessProbe", + "default": 5 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for livenessProbe", + "default": 5 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for livenessProbe", + "default": 1 + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable readinessProbe on Redis® replicas nodes", + "default": true + }, + "initialDelaySeconds": { + "type": "number", + "description": "Initial delay seconds for readinessProbe", + "default": 5 + }, + "periodSeconds": { + "type": "number", + "description": "Period seconds for readinessProbe", + "default": 10 + }, + "timeoutSeconds": { + "type": "number", + "description": "Timeout seconds for readinessProbe", + "default": 1 + }, + "failureThreshold": { + "type": "number", + "description": "Failure threshold for readinessProbe", + "default": 3 + }, + "successThreshold": { + "type": "number", + "description": "Success threshold for readinessProbe", + "default": 1 + } + } + }, + "customStartupProbe": { + "type": "object", + "description": "Custom startupProbe that overrides the default one", + "default": {} + }, + "customLivenessProbe": { + "type": "object", + "description": "Custom livenessProbe that overrides the default one", + "default": {} + }, + "customReadinessProbe": { + "type": "object", + "description": "Custom readinessProbe that overrides the default one", + "default": {} + }, + "command": { + "type": "array", + "description": "Override default metrics container init command (useful when using custom images)", + "default": [], + "items": {} + }, + "redisTargetHost": { + "type": "string", + "description": "A way to specify an alternative Redis® hostname", + "default": "localhost" + }, + "extraArgs": { + "type": "object", + "description": "Extra arguments for Redis® exporter, for example:", + "default": {} + }, + "extraEnvVars": { + "type": "array", + "description": "Array with extra environment variables to add to Redis® exporter", + "default": [], + "items": {} + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled Redis® exporter containers' Security Context", + "default": true + }, + "runAsUser": { + "type": "number", + "description": "Set Redis® exporter containers' Security Context runAsUser", + "default": 1001 + }, + "runAsGroup": { + "type": "number", + "description": "Set Redis® exporter containers' Security Context runAsGroup", + "default": 1001 + }, + "runAsNonRoot": { + "type": "boolean", + "description": "Set Redis® exporter containers' Security Context runAsNonRoot", + "default": true + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "Set Redis® exporter containers' Security Context allowPrivilegeEscalation", + "default": false + }, + "readOnlyRootFilesystem": { + "type": "boolean", + "description": "Set container's Security Context read-only root filesystem", + "default": true + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Set Redis® exporter containers' Security Context seccompProfile", + "default": "RuntimeDefault" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "Set Redis® exporter containers' Security Context capabilities to drop", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + } + } + }, + "extraVolumes": { + "type": "array", + "description": "Optionally specify extra list of additional volumes for the Redis® metrics sidecar", + "default": [], + "items": {} + }, + "extraVolumeMounts": { + "type": "array", + "description": "Optionally specify extra list of additional volumeMounts for the Redis® metrics sidecar", + "default": [], + "items": {} + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + }, + "podLabels": { + "type": "object", + "description": "Extra labels for Redis® exporter pods", + "default": {} + }, + "service": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Create Service resource(s) for scraping metrics using PrometheusOperator ServiceMonitor, can be disabled when using a PodMonitor", + "default": true + }, + "type": { + "type": "string", + "description": "Redis® exporter service type", + "default": "ClusterIP" + }, + "ports": { + "type": "object", + "properties": { + "http": { + "type": "number", + "description": "Redis® exporter service port", + "default": 9121 + } + } + }, + "externalTrafficPolicy": { + "type": "string", + "description": "Redis® exporter service external traffic policy", + "default": "Cluster" + }, + "extraPorts": { + "type": "array", + "description": "Extra ports to expose (normally used with the `sidecar` value)", + "default": [], + "items": {} + }, + "loadBalancerIP": { + "type": "string", + "description": "Redis® exporter service Load Balancer IP", + "default": "" + }, + "loadBalancerClass": { + "type": "string", + "description": "exporter service Load Balancer class if service type is `LoadBalancer` (optional, cloud specific)", + "default": "" + }, + "loadBalancerSourceRanges": { + "type": "array", + "description": "Redis® exporter service Load Balancer sources", + "default": [], + "items": {} + }, + "annotations": { + "type": "object", + "description": "Additional custom annotations for Redis® exporter service", + "default": {} + }, + "clusterIP": { + "type": "string", + "description": "Redis® exporter service Cluster IP", + "default": "" + } + } + }, + "serviceMonitor": { + "type": "object", + "properties": { + "port": { + "type": "string", + "description": "the service port to scrape metrics from", + "default": "http-metrics" + }, + "enabled": { + "type": "boolean", + "description": "Create ServiceMonitor resource(s) for scraping metrics using PrometheusOperator", + "default": false + }, + "namespace": { + "type": "string", + "description": "The namespace in which the ServiceMonitor will be created", + "default": "" + }, + "interval": { + "type": "string", + "description": "The interval at which metrics should be scraped", + "default": "30s" + }, + "scrapeTimeout": { + "type": "string", + "description": "The timeout after which the scrape is ended", + "default": "" + }, + "relabelings": { + "type": "array", + "description": "Metrics RelabelConfigs to apply to samples before scraping.", + "default": [], + "items": {} + }, + "metricRelabelings": { + "type": "array", + "description": "Metrics RelabelConfigs to apply to samples before ingestion.", + "default": [], + "items": {} + }, + "honorLabels": { + "type": "boolean", + "description": "Specify honorLabels parameter to add the scrape endpoint", + "default": false + }, + "additionalLabels": { + "type": "object", + "description": "Additional labels that can be used so ServiceMonitor resource(s) can be discovered by Prometheus", + "default": {} + }, + "podTargetLabels": { + "type": "array", + "description": "Labels from the Kubernetes pod to be transferred to the created metrics", + "default": [], + "items": {} + }, + "sampleLimit": { + "type": "boolean", + "description": "Limit of how many samples should be scraped from every Pod", + "default": false + }, + "targetLimit": { + "type": "boolean", + "description": "Limit of how many targets should be scraped", + "default": false + }, + "additionalEndpoints": { + "type": "array", + "description": "Additional endpoints to scrape (e.g sentinel)", + "default": [], + "items": {} + } + } + }, + "podMonitor": { + "type": "object", + "properties": { + "port": { + "type": "string", + "description": "the pod port to scrape metrics from", + "default": "metrics" + }, + "enabled": { + "type": "boolean", + "description": "Create PodMonitor resource(s) for scraping metrics using PrometheusOperator", + "default": false + }, + "namespace": { + "type": "string", + "description": "The namespace in which the PodMonitor will be created", + "default": "" + }, + "interval": { + "type": "string", + "description": "The interval at which metrics should be scraped", + "default": "30s" + }, + "scrapeTimeout": { + "type": "string", + "description": "The timeout after which the scrape is ended", + "default": "" + }, + "relabelings": { + "type": "array", + "description": "Metrics RelabelConfigs to apply to samples before scraping.", + "default": [], + "items": {} + }, + "metricRelabelings": { + "type": "array", + "description": "Metrics RelabelConfigs to apply to samples before ingestion.", + "default": [], + "items": {} + }, + "honorLabels": { + "type": "boolean", + "description": "Specify honorLabels parameter to add the scrape endpoint", + "default": false + }, + "additionalLabels": { + "type": "object", + "description": "Additional labels that can be used so PodMonitor resource(s) can be discovered by Prometheus", + "default": {} + }, + "podTargetLabels": { + "type": "array", + "description": "Labels from the Kubernetes pod to be transferred to the created metrics", + "default": [], + "items": {} + }, + "sampleLimit": { + "type": "boolean", + "description": "Limit of how many samples should be scraped from every Pod", + "default": false + }, + "targetLimit": { + "type": "boolean", + "description": "Limit of how many targets should be scraped", + "default": false + }, + "additionalEndpoints": { + "type": "array", + "description": "Additional endpoints to scrape (e.g sentinel)", + "default": [], + "items": {} + } + } + }, + "prometheusRule": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Create a custom prometheusRule Resource for scraping metrics using PrometheusOperator", + "default": false + }, + "namespace": { + "type": "string", + "description": "The namespace in which the prometheusRule will be created", + "default": "" + }, + "additionalLabels": { + "type": "object", + "description": "Additional labels for the prometheusRule", + "default": {} + }, + "rules": { + "type": "array", + "description": "Custom Prometheus rules", + "default": [], + "items": {} + } + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable init container that changes the owner/group of the PV mount point to `runAsUser:fsGroup`", + "default": false + }, + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "OS Shell + Utility image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "OS Shell + Utility image repository", + "default": "REPOSITORY_NAME/os-shell" + }, + "digest": { + "type": "string", + "description": "OS Shell + Utility image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "OS Shell + Utility image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "OS Shell + Utility image pull secrets", + "default": [], + "items": {} + } + } + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "runAsUser": { + "type": "number", + "description": "Set init container's Security Context runAsUser", + "default": 0 + } + } + } + } + }, + "kubectl": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "Kubectl image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "Kubectl image repository", + "default": "REPOSITORY_NAME/kubectl" + }, + "digest": { + "type": "string", + "description": "Kubectl image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "Kubectl image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "Kubectl pull secrets", + "default": [], + "items": {} + } + } + }, + "command": { + "type": "array", + "description": "kubectl command to execute", + "default": [ + "/opt/bitnami/scripts/kubectl-scripts/update-master-label.sh" + ], + "items": { + "type": "string" + } + }, + "containerSecurityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enabled kubectl containers' Security Context", + "default": true + }, + "runAsUser": { + "type": "number", + "description": "Set kubectl containers' Security Context runAsUser", + "default": 1001 + }, + "runAsGroup": { + "type": "number", + "description": "Set kubectl containers' Security Context runAsGroup", + "default": 1001 + }, + "runAsNonRoot": { + "type": "boolean", + "description": "Set kubectl containers' Security Context runAsNonRoot", + "default": true + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "Set kubectl containers' Security Context allowPrivilegeEscalation", + "default": false + }, + "readOnlyRootFilesystem": { + "type": "boolean", + "description": "Set container's Security Context read-only root filesystem", + "default": true + }, + "seccompProfile": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Set kubectl containers' Security Context seccompProfile", + "default": "RuntimeDefault" + } + } + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "Set kubectl containers' Security Context capabilities to drop", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + } + } + }, + "resources": { + "type": "object", + "properties": { + "limits": { + "type": "object", + "description": "The resources limits for the kubectl containers", + "default": {} + }, + "requests": { + "type": "object", + "description": "The requested resources for the kubectl containers", + "default": {} + } + } + } + } + }, + "sysctl": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable init container to modify Kernel settings", + "default": false + }, + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "OS Shell + Utility image registry", + "default": "REGISTRY_NAME" + }, + "repository": { + "type": "string", + "description": "OS Shell + Utility image repository", + "default": "REPOSITORY_NAME/os-shell" + }, + "digest": { + "type": "string", + "description": "OS Shell + Utility image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag", + "default": "" + }, + "pullPolicy": { + "type": "string", + "description": "OS Shell + Utility image pull policy", + "default": "IfNotPresent" + }, + "pullSecrets": { + "type": "array", + "description": "OS Shell + Utility image pull secrets", + "default": [], + "items": {} + } + } + }, + "command": { + "type": "array", + "description": "Override default init-sysctl container command (useful when using custom images)", + "default": [], + "items": {} + }, + "mountHostSys": { + "type": "boolean", + "description": "Mount the host `/sys` folder to `/host-sys`", + "default": false + }, + "resourcesPreset": { + "type": "string", + "description": "Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if sysctl.resources is set (sysctl.resources is recommended for production).", + "default": "nano" + }, + "resources": { + "type": "object", + "description": "Set container requests and limits for different resources like CPU or memory (essential for production workloads)", + "default": {} + } + } + }, + "useExternalDNS": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enable various syntax that would enable external-dns to work. Note this requires a working installation of `external-dns` to be usable.", + "default": false + }, + "additionalAnnotations": { + "type": "object", + "description": "Extra annotations to be utilized when `external-dns` is enabled.", + "default": {} + }, + "annotationKey": { + "type": "string", + "description": "The annotation key utilized when `external-dns` is enabled. Setting this to `false` will disable annotations.", + "default": "external-dns.alpha.kubernetes.io/" + }, + "suffix": { + "type": "string", + "description": "The DNS suffix utilized when `external-dns` is enabled. Note that we prepend the suffix with the full name of the release.", + "default": "" + } } - } } - } } - } -} +} \ No newline at end of file diff --git a/packages/system/dashboard/charts/kubeapps/charts/redis/values.yaml b/packages/system/dashboard/charts/kubeapps/charts/redis/values.yaml index adb91c8b..09874845 100644 --- a/packages/system/dashboard/charts/kubeapps/charts/redis/values.yaml +++ b/packages/system/dashboard/charts/kubeapps/charts/redis/values.yaml @@ -102,7 +102,7 @@ diagnosticMode: image: registry: docker.io repository: bitnami/redis - tag: 7.2.5-debian-12-r3 + tag: 7.4.1-debian-12-r0 digest: "" ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' @@ -633,6 +633,9 @@ master: create: true minAvailable: "" maxUnavailable: "" + ## @param master.extraPodSpec Optionally specify extra PodSpec for the Redis® master pod(s) + ## + extraPodSpec: {} ## @section Redis® replicas configuration parameters ## replica: @@ -1118,6 +1121,9 @@ replica: create: true minAvailable: "" maxUnavailable: "" + ## @param replica.extraPodSpec Optionally specify extra PodSpec for the Redis® replicas pod(s) + ## + extraPodSpec: {} ## @section Redis® Sentinel configuration parameters ## @@ -1140,7 +1146,7 @@ sentinel: image: registry: docker.io repository: bitnami/redis-sentinel - tag: 7.2.5-debian-12-r3 + tag: 7.4.1-debian-12-r0 digest: "" ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' @@ -1520,6 +1526,9 @@ sentinel: ## @param sentinel.terminationGracePeriodSeconds Integer setting the termination grace period for the redis-node pods ## terminationGracePeriodSeconds: 30 + ## @param sentinel.extraPodSpec Optionally specify extra PodSpec for the Redis® Sentinel pod(s) + ## + extraPodSpec: {} ## @section Other Parameters ## @@ -1691,7 +1700,7 @@ metrics: image: registry: docker.io repository: bitnami/redis-exporter - tag: 1.62.0-debian-12-r1 + tag: 1.63.0-debian-12-r1 digest: "" pullPolicy: IfNotPresent ## Optionally specify an array of imagePullSecrets. @@ -1928,7 +1937,7 @@ metrics: # add metricRelabelings with label like app=redis to main redis pod-monitor port # - interval: "30s" # path: "/scrape" - # port: "metrics" + # port: "http-metrics" # params: # target: ["localhost:26379"] # metricRelabelings: @@ -2063,7 +2072,7 @@ volumePermissions: image: registry: docker.io repository: bitnami/os-shell - tag: 12-debian-12-r26 + tag: 12-debian-12-r30 digest: "" pullPolicy: IfNotPresent ## Optionally specify an array of imagePullSecrets. @@ -2103,6 +2112,14 @@ volumePermissions: seLinuxOptions: {} runAsUser: 0 + ## @param volumePermissions.extraEnvVars Array with extra environment variables to add to volume permissions init container. + ## e.g: + ## extraEnvVars: + ## - name: FOO + ## value: "bar" + ## + extraEnvVars: [] + ## Kubectl InitContainer ## used by Sentinel to update the isMaster label on the Redis(TM) pods ## @@ -2119,7 +2136,7 @@ kubectl: image: registry: docker.io repository: bitnami/kubectl - tag: 1.30.3-debian-12-r3 + tag: 1.31.1-debian-12-r3 digest: "" ## Specify a imagePullPolicy ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' @@ -2189,7 +2206,7 @@ sysctl: image: registry: docker.io repository: bitnami/os-shell - tag: 12-debian-12-r26 + tag: 12-debian-12-r30 digest: "" pullPolicy: IfNotPresent ## Optionally specify an array of imagePullSecrets. diff --git a/packages/system/dashboard/charts/kubeapps/templates/frontend/configmap.yaml b/packages/system/dashboard/charts/kubeapps/templates/frontend/configmap.yaml index b0c7d659..cafdc5fc 100644 --- a/packages/system/dashboard/charts/kubeapps/templates/frontend/configmap.yaml +++ b/packages/system/dashboard/charts/kubeapps/templates/frontend/configmap.yaml @@ -139,7 +139,7 @@ data: location /logos { # Add the Authorization header if exists - add_header Authorization $http_authorization; + proxy_set_header Cookie ""; proxy_pass http://cozystack.cozy-system.svc:80; } } diff --git a/packages/system/dashboard/charts/kubeapps/values.yaml b/packages/system/dashboard/charts/kubeapps/values.yaml index 8a81084f..e2f60969 100644 --- a/packages/system/dashboard/charts/kubeapps/values.yaml +++ b/packages/system/dashboard/charts/kubeapps/values.yaml @@ -213,10 +213,9 @@ frontend: image: registry: docker.io repository: bitnami/nginx - tag: 1.27.0-debian-12-r4 + tag: 1.27.2-debian-12-r2 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -321,7 +320,7 @@ frontend: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -627,10 +626,9 @@ dashboard: image: registry: docker.io repository: bitnami/kubeapps-dashboard - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -767,7 +765,7 @@ dashboard: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -1029,10 +1027,9 @@ apprepository: image: registry: docker.io repository: bitnami/kubeapps-apprepository-controller - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -1056,10 +1053,9 @@ apprepository: syncImage: registry: docker.io repository: bitnami/kubeapps-asset-syncer - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -1209,7 +1205,7 @@ apprepository: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -1423,10 +1419,9 @@ authProxy: image: registry: docker.io repository: bitnami/oauth2-proxy - tag: 7.6.0-debian-12-r17 + tag: 7.7.1-debian-12-r1 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -1531,7 +1526,7 @@ authProxy: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -1579,10 +1574,9 @@ pinnipedProxy: image: registry: docker.io repository: bitnami/kubeapps-pinniped-proxy - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -1661,7 +1655,7 @@ pinnipedProxy: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -1894,10 +1888,9 @@ kubeappsapis: image: registry: docker.io repository: bitnami/kubeapps-apis - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -1999,7 +1992,7 @@ kubeappsapis: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true @@ -2274,10 +2267,9 @@ ociCatalog: image: registry: docker.io repository: bitnami/kubeapps-oci-catalog - tag: 2.11.0-debian-12-r2 + tag: 2.12.0-debian-12-r0 digest: "" ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images ## pullPolicy: IfNotPresent @@ -2344,7 +2336,7 @@ ociCatalog: ## containerSecurityContext: enabled: true - seLinuxOptions: null + seLinuxOptions: {} runAsUser: 1001 runAsGroup: 1001 runAsNonRoot: true diff --git a/packages/system/dashboard/images/kubeapps-apis/Dockerfile b/packages/system/dashboard/images/kubeapps-apis/Dockerfile index 7a332d3e..95733b0b 100644 --- a/packages/system/dashboard/images/kubeapps-apis/Dockerfile +++ b/packages/system/dashboard/images/kubeapps-apis/Dockerfile @@ -3,23 +3,9 @@ # syntax = docker/dockerfile:1 -FROM alpine as source -ARG VERSION=v2.11.0 -RUN apk add --no-cache patch -WORKDIR /source -RUN wget -O- https://github.com/vmware-tanzu/kubeapps/archive/refs/tags/${VERSION}.tar.gz | tar xzf - --strip-components=1 -COPY fluxcd.diff /patches/fluxcd.diff -COPY labels.diff /patches/labels.diff -COPY reconcile-strategy.diff /patches/reconcile-strategy.diff -COPY dashboard-resource.diff /patches/dashboard-resource.diff -RUN patch -p1 < /patches/fluxcd.diff -RUN patch -p1 < /patches/labels.diff -RUN patch -p1 < /patches/reconcile-strategy.diff -RUN patch -p1 < /patches/dashboard-resource.diff - -FROM bitnami/golang:1.22.5 AS builder +FROM bitnami/golang:1.23.2 AS builder WORKDIR /go/src/github.com/vmware-tanzu/kubeapps -COPY --from=source /source/go.mod /source/go.sum ./ +COPY go.mod go.sum ./ ARG VERSION="devel" ARG TARGETARCH @@ -27,13 +13,13 @@ ARG TARGETARCH ARG lint # https://github.com/bufbuild/buf/releases/ -ARG BUF_VERSION="1.34.0" +ARG BUF_VERSION="1.45.0" # https://github.com/golangci/golangci-lint/releases -ARG GOLANGCILINT_VERSION="1.59.1" +ARG GOLANGCILINT_VERSION="1.61.0" # https://github.com/grpc-ecosystem/grpc-health-probe/releases/ -ARG GRPC_HEALTH_PROBE_VERSION="0.4.28" +ARG GRPC_HEALTH_PROBE_VERSION="0.4.34" # Install lint tools RUN if [ ! -z ${lint:-} ]; then \ @@ -54,8 +40,8 @@ RUN --mount=type=cache,target=/go/pkg/mod \ # We don't copy the pkg and cmd directories until here so the above layers can # be reused. -COPY --from=source /source/pkg pkg -COPY --from=source /source/cmd cmd +COPY pkg pkg +COPY cmd cmd RUN if [ ! -z ${lint:-} ]; then \ # Run golangci-lint to detect issues @@ -74,6 +60,15 @@ RUN --mount=type=cache,target=/go/pkg/mod \ -ldflags "-X github.com/vmware-tanzu/kubeapps/cmd/kubeapps-apis/cmd.version=$VERSION" \ ./cmd/kubeapps-apis +# Build 'kapp-controller' plugin, version 'v1alpha1' +RUN --mount=type=cache,target=/go/pkg/mod \ + --mount=type=cache,target=/root/.cache/go-build \ + GOPROXY="https://proxy.golang.org,direct" \ + go build \ + -ldflags "-X github.com/vmware-tanzu/kubeapps/cmd/kubeapps-apis/cmd.version=$VERSION" \ + -o /kapp-controller-packages-v1alpha1-plugin.so -buildmode=plugin \ + ./cmd/kubeapps-apis/plugins/kapp_controller/packages/v1alpha1/*.go + ## Build 'fluxv2' plugin, version 'v1alpha1' RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ @@ -106,6 +101,7 @@ RUN --mount=type=cache,target=/go/pkg/mod \ FROM bitnami/minideb:bookworm COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=builder /go/src/github.com/vmware-tanzu/kubeapps/kubeapps-apis /kubeapps-apis +COPY --from=builder /kapp-controller-packages-v1alpha1-plugin.so /plugins/kapp-controller-packages/ COPY --from=builder /fluxv2-packages-v1alpha1-plugin.so /plugins/fluxv2-packages/ COPY --from=builder /helm-packages-v1alpha1-plugin.so /plugins/helm-packages/ COPY --from=builder /resources-v1alpha1-plugin.so /plugins/resources/ diff --git a/packages/system/dashboard/patches/logos.patch b/packages/system/dashboard/patches/logos.patch index e00492db..477c3770 100644 --- a/packages/system/dashboard/patches/logos.patch +++ b/packages/system/dashboard/patches/logos.patch @@ -9,7 +9,7 @@ index d43f521..31ff7d5 100644 + + location /logos { + # Add the Authorization header if exists -+ add_header Authorization $http_authorization; ++ proxy_set_header Cookie ""; + proxy_pass http://cozystack.cozy-system.svc:80; + } } diff --git a/packages/system/keycloak-configure/templates/configure-kk.yaml b/packages/system/keycloak-configure/templates/configure-kk.yaml index 3bba54bb..b5530697 100644 --- a/packages/system/keycloak-configure/templates/configure-kk.yaml +++ b/packages/system/keycloak-configure/templates/configure-kk.yaml @@ -2,6 +2,9 @@ {{- $host := index $cozyConfig.data "root-host" }} {{- $apiServerAdress := index $cozyConfig.data "api-server-adress" }} {{- $k8sClient := randAlphaNum 32 -}} +{{- $kubeappsClient := randAlphaNum 32 -}} +{{- $rootSaConfigMap := lookup "v1" "ConfigMap" "kube-system" "kube-root-ca.crt" }} +{{- $k8sCa := index $rootSaConfigMap.data "ca.crt" | b64enc }} apiVersion: v1.edp.epam.com/v1alpha1 kind: ClusterKeycloak @@ -20,8 +23,8 @@ metadata: name: keycloakrealm-cozy namespace: {{ .Release.Namespace }} spec: - realmName: cozy - clusterKeycloakRef: keycloak-cozy + realmName: cozy + clusterKeycloakRef: keycloak-cozy --- @@ -36,6 +39,7 @@ spec: kind: ClusterKeycloakRealm description: "Group Membership" protocol: openid-connect + default: true protocolMappers: - name: groups protocol: openid-connect @@ -46,6 +50,8 @@ spec: "full.path": "false" "id.token.claim": "true" "userinfo.token.claim": "true" + attributes: + "include.in.token.scope": "true" --- @@ -84,3 +90,154 @@ spec: redirectUris: - http://localhost:18000 - http://localhost:8000 + +--- + +apiVersion: v1.edp.epam.com/v1 +kind: KeycloakClientScope +metadata: + name: kubernetes-client +spec: + name: kubernetes-client + realmRef: + name: keycloakrealm-cozy + kind: ClusterKeycloakRealm + description: "kubernetes-client" + protocol: openid-connect + default: true + attributes: + "include.in.token.scope": "true" + protocolMappers: + - name: audience + protocol: openid-connect + protocolMapper: "oidc-audience-mapper" + config: + "included.client.audience": "kubernetes" + "id.token.claim": "true" + "access.token.claim": "true" + "lightweight.claim": "false" + "introspection.token.claim": "true" + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: kubeapps-client +type: Opaque +stringData: + client-secret-key: {{ $kubeappsClient }} + +--- + +apiVersion: v1.edp.epam.com/v1 +kind: KeycloakClient +metadata: + name: kubeapps-client +spec: + serviceAccount: + enabled: true + realmRef: + name: keycloakrealm-cozy + kind: ClusterKeycloakRealm + secret: $kubeapps-client:client-secret-key + advancedProtocolMappers: true + authorizationServicesEnabled: true + name: kubeapps + clientId: kubeapps + directAccess: true + public: false + webUrl: "https://dashboard.{{ $host }}" + defaultClientScopes: + - groups + - kubernetes-client + redirectUris: + - "http://dashboard.{{ $host }}/oauth2/callback/*" + +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: kubeapps-auth-config + namespace: cozy-dashboard +data: + values.yaml: | + kubeapps: + authProxy: + enabled: true + provider: "oidc" + clientID: "kubeapps" + clientSecret: {{ $kubeappsClient }} + cookieSecret: {{ randAlphaNum 16 | b64enc | quote }} + extraFlags: + - --ssl-insecure-skip-verify + - --cookie-secure=false + - --scope=openid email groups + - --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy + +--- + +apiVersion: v1.edp.epam.com/v1 +kind: KeycloakRealmGroup +metadata: + name: kubeapps-admin + namespace: {{ include "tenant.name" . }} +spec: + name: kubeapps-admin + realmRef: + name: keycloakrealm-cozy + kind: ClusterKeycloakRealm + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: tenant-root-dashboard-resources + namespace: tenant-root +rules: +- apiGroups: + - "" + resources: + - secrets + resourceNames: + - kubeconfig + verbs: ["get", "list", "watch"] + + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: kubeconfig + namespace: tenant-root +stringData: + kubeconfig: | + apiVersion: v1 + clusters: + - cluster: + server: https://{{ $apiServerAdress }}:6443 + certificate-authority-data: {{ $k8sCa }} + name: cluster + contexts: + - context: + cluster: cluster + user: keycloak + name: default + current-context: default + users: + - name: keycloak + user: + exec: + apiVersion: client.authentication.k8s.io/v1beta1 + args: + - oidc-login + - get-token + - --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy + - --oidc-client-id=kubernetes + - --oidc-client-secret={{ $k8sClient }} + - --skip-open-browser + - --grant-type=password + command: kubectl diff --git a/packages/system/keycloak-configure/templates/rolebinding.yaml b/packages/system/keycloak-configure/templates/rolebinding.yaml new file mode 100644 index 00000000..83272889 --- /dev/null +++ b/packages/system/keycloak-configure/templates/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: kubeapps-admin-group + namespace: cozy-dashboard +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: admin +subjects: +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: kubeapps-admin